Aias00 opened a new issue, #7468: URL: https://github.com/apache/shenyu/issues/7468
## Description The config import flow detects duplicates only against rows that existed before the import started. It does not update the in-memory duplicate sets/maps after each successful insert, so duplicate business keys inside the same uploaded ZIP can slip through. The reachable endpoint is `POST /configs/import` at `shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java:131`. `ConfigsServiceImpl.configsImport()` creates one `ConfigsImportContext` and iterates the handlers for each ZIP item (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ConfigsServiceImpl.java:439-445`). Handler order includes auth, metadata, selectors, rules, dicts, proxy selectors, discovery, and discovery upstream (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/configs/ConfigsExportImportEnum.java:25-75`). Several import services share the same pattern: - `SelectorServiceImpl.importData()` builds `pluginSelectorMap` from `selectorMapper.selectAllByNamespaceId(namespace)` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java:570`) and builds `existSelectorSet` from that snapshot (`SelectorServiceImpl.java:583`), but after `create(selectorDTO)` it does not add the inserted selector name to the set (`SelectorServiceImpl.java:599-611`). - `RuleServiceImpl.importData()` builds `selectorRuleMap` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java:350`) and `existRuleNameSet` from that original map (`RuleServiceImpl.java:368`), then inserts without adding the rule name (`RuleServiceImpl.java:380-394`). - `MetaDataServiceImpl.importData()` builds `existMetadataPathSet` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java:258`) and inserts without adding the path (`MetaDataServiceImpl.java:276-278`). - `AppAuthServiceImpl.importData()` builds `existAppKeySet` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java:358`) and inserts without adding the app key (`AppAuthServiceImpl.java:376-383`). - `ShenyuDictServiceImpl.importData()` builds `dictTypeMap` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java:115`) and rebuilds the set from that original map for each row (`ShenyuDictServiceImpl.java:123-127`), then inserts without updating it (`ShenyuDictServiceImpl.java:135`). - `ProxySelectorServiceImpl.importData()` builds `pluginProxySelectorMap` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ProxySelectorServiceImpl.java:553`) and inserts without updating it (`ProxySelectorServiceImpl.java:574-581`). - `DiscoveryServiceImpl.importData()` builds `pluginDiscoveryMap` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java:490`) and inserts without updating it (`DiscoveryServiceImpl.java:510-514`). - `DiscoveryUpstreamServiceImpl.importData()` builds `discoveryHandlerUpstreamMap` once (`shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java:361`) and inserts without updating it (`DiscoveryUpstreamServiceImpl.java:379-384`). The schema does not enforce business uniqueness for several of these tables. For example, `selector`, `rule`, `app_auth`, `proxy_selector`, and `discovery` have only primary-key constraints in `db/init/mysql/schema.sql:2176`, `:2132`, `:92`, `:2470`, and `:2414`. Other tables have unique constraints that can fail late, such as `shenyu_dict` (`db/init/mysql/schema.sql:2222-2234`) and `discovery_upstream` (`db/init/mysql/schema.sql:2449-2462`). ## Trigger Upload a config ZIP where a file contains duplicate business keys that do not already exist in the target namespace. Examples: - two selectors with the same remapped plugin id and selector name; - two rules with the same remapped selector id and rule name; - two metadata rows with the same path; - two app auth rows with the same app key; - two dict rows with the same type/code/name; - two proxy selectors with the same plugin/name; - two discoveries with the same plugin/name; - two discovery upstreams with the same remapped handler/url. ## Expected behavior The import should detect duplicates inside the uploaded archive and report the later row as failed, or map the later row to the first inserted row consistently without writing duplicate business records. ## Actual behavior Each service compares each row only against the original database snapshot. The first duplicate row is inserted, but the duplicate set/map is not updated, so the second row is treated as new. Depending on the table, the import either persists duplicate business records or fails late with a database unique-key exception instead of producing a row-level duplicate failure. ## Impact Duplicate selectors, rules, metadata, app auth entries, proxy selectors, or discoveries can be imported into a namespace even though the import code attempts to prevent duplicates. For tables with database unique keys, a duplicate inside one archive can abort the import with a low-level database error instead of returning a clean import result. ## Suggested fix Pre-validate each import list for duplicate business keys before writing, or add each successful insert to the in-memory duplicate set/map immediately after the insert succeeds. For namespace imports that remap ids, compute the duplicate key from the remapped plugin/selector/handler id. ## Related existing issues This is distinct from #6465, which only covers discovery upstream duplicate checks before handler-id remapping, and from #6697, which covers transaction boundaries for dictionary import. It is also distinct from older primary-key/id conflict reports such as #5826 and #5895. This issue is about duplicate business keys inside the same uploaded archive. ## Reviewed Revision And Validation Apache ShenYu 2.7.2-SNAPSHOT, master at a89b6a2338c24e978428b731e8f1edce86022418. Severity: medium. Confidence: high. Independent actual SelectorService import test reproduced two same-business-key inserts; wider sibling patterns were inspected and should be covered when fixing. Current source references: - `shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java:131` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ConfigsServiceImpl.java:439` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/configs/ConfigsExportImportEnum.java:25` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java:570` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/SelectorServiceImpl.java:583` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java:350` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/RuleServiceImpl.java:368` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/MetaDataServiceImpl.java:258` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/AppAuthServiceImpl.java:358` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ShenyuDictServiceImpl.java:115` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/ProxySelectorServiceImpl.java:553` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryServiceImpl.java:490` - `shenyu-admin/src/main/java/org/apache/shenyu/admin/service/impl/DiscoveryUpstreamServiceImpl.java:361` - `db/init/mysql/schema.sql:2176` - `db/init/mysql/schema.sql:2132` - `db/init/mysql/schema.sql:92` - `db/init/mysql/schema.sql:2222` - `db/init/mysql/schema.sql:2449` No implementation fix or full deployed end-to-end validation was performed by this review. Source-flow and runtime evidence are distinguished above. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
