Visitar URL original
[type:refactor] enable external ingress adapters for Motan asset handoff by cloudbase-ai · Pull Request #7498 · apache/shenyu · GitHub
Skip to content

[type:refactor] enable external ingress adapters for Motan asset handoff - #7498

Merged
Aias00 merged 2 commits into
apache:masterfrom
cloudbase-ai:cloudbase/cleanup-motan-store-ownership
Oct 9, 2026
Merged

Aias00 merged 2 commits into
apache:masterfrom
cloudbase-ai:cloudbase/cleanup-motan-store-ownership

Conversation

@cloudbase-ai

@cloudbase-ai cloudbase-ai commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Problem And Result

Hand off motan ownership to apache/shenyu-plugin-store#8, which now includes original tests, fixtures, examples, deployment assets and SQL ownership manifests. Add a generic optional ingress adapter contract so recovered Motan fixtures can run from the store; core has no store artifact dependency. Shared schema DDL, generic APIs and complete historical upgrade SQL remain in core.

Receiving Assets And Validation

Ship db/plugins/<slug>/{h2,mysql,pg,og,ob,oracle}/preflight.sql and install.sql, row manifests, provenance and plugin-specific historical SQL archives. Metadata includes plugin definitions, selector/rule handles, menu resources, permissions and default-namespace relations. Run preflight before installation; repeat installs preserve existing plugin and namespace configuration. Full historical core upgrade files stay in main.

SQL provenance is recorded under the receiving db/plugins directories; original tests, examples and deployment fixtures retain their source layouts.

  • Preserved original Motan IT: 2 tests passed; original Motan E2E: 8 tests passed, 0 skipped. Class origin is the mounted store plugin JAR.
  • Portable Motan launcher passed the strict external cache probe (unauthenticated 403, four authenticated cache endpoints, loaded plugin identity), then reran original E2E8 successfully.
  • Recovered client SDK: 12 tests passed; client starter: 1 test passed; admin registration adapter: 8 tests passed; store ingress adapter: 2 tests passed.
  • Generic core ingress extension passed 143 controller tests and independent architecture review.
  • Executed shipped SQL twice on H2, MySQL (default and NO_BACKSLASH_ESCAPES) and PostgreSQL; verified row identities, conflicts and configuration preservation. Native Oracle/OpenGauss/OceanBase execution remains unverified.

Cutover Gates

This PR remains draft. Receiving CI/release validation and externally available store artifacts must pass before merge. Original Motan Kubernetes runtime has not been executed. Its fixtures and store ingress adapter are preserved, and the generic core hook is implemented; this lane remains a deployment validation gate. Receiving GitHub CI must complete before main cutover. Native Oracle/OpenGauss/OceanBase SQL execution remains a named validation gap. No upstream merge or Maven publication has been performed.

Core does not depend on store artifacts; deployments select optional external starters and apply the matching store metadata scripts.

Roadmap: #7306.

Signed-off-by: cloudbase-ai <22498243+cloudbase-ai@users.noreply.github.com>
Signed-off-by: cloudbase-ai <22498243+cloudbase-ai@users.noreply.github.com>
@cloudbase-ai cloudbase-ai changed the title [type:refactor] clean up stale Motan distribution metadata [type:refactor] enable external ingress adapters for Motan asset handoff Oct 8, 2026
@Aias00
Aias00 marked this pull request as ready for review October 9, 2026 03:46
* @param endpointsLister endpoints lister
* @return plugin data
*/
PluginData pluginData(V1Ingress ingress, Request request, Lister<V1Endpoints> endpointsLister);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] pluginData(ingress, request, endpointsLister) takes a Request request parameter, but the supplied FakeIngressPluginDefinition (and presumably most real implementations) ignore it — the namespace/name are already reachable via ingress.getMetadata(). Either document what an implementation is expected to use request for, or consider dropping it from the signature to avoid a misleading no-op parameter.

* @param endpointsLister endpoints lister
* @return metadata paths owned by this ingress
*/
default List<String> metadataPaths(final V1Ingress ingress, final Lister<V1Service> serviceLister,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NIT] The default metadataPaths returns singletonList(contextPath(...)), and IngressReconciler.doDeleteConfigByIngress relies on it to clean up metadata on ingress deletion. If an implementation overrides parse and creates metadata under a key other than contextPath, the default metadataPaths will not cover it and deleting the ingress leaks that metadata. Please state in the interface javadoc that every metadata key created in parse must be returned by metadataPaths (or override metadataPaths).

@Aias00 Aias00 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This PR introduces a clean extension point — the IngressPluginDefinition interface — so that non-core plugins like Motan can be wired in as external ingress adapters instead of being hardcoded in the kubernetes controller. It also removes the now-orphaned motan LICENSE entries from the bootstrap distribution. The change is a refactor/extension, not a behavior change for any plugin that ships in the main repo today.

What I verified and liked

  • Backward compatible. IngressParser keeps a no-arg constructor that delegates to an empty list, and the k8s starter now injects ObjectProvider<IngressPluginDefinition>.orderedStream() (sorted, so @Order resolves overlap — matches the interface javadoc). With zero external definitions (the current main-repo state) the list is empty and behavior is unchanged — confirmed by the all-green k8s integration suite (k8s-ingress-http/-websocket/-dubbo/-grpc all pass, plus pr_build/rat_check/Analyze).
  • Consistent dispatch priority. parse, getPluginName, and enablePluginsBasedOnAnnotations all resolve in the same order: external definition first (findFirst), then the built-in dubbo/ws/grpc/sofa chain, then the DIVIDE fallback. This means the selector created by parse (which carries the plugin name) and the plugin name used by processSelectorData / updateUpstreamFromEndpoints never disagree.
  • Symmetric add/delete. The deletion path threads the external plugin name + metadata paths through the new deleteSelectorByIngressName overload, and IngressSelectorCache.remove uses the same plugin name as the selector creation. The cache put/remove keys match.
  • LICENSE cleanup is verified-safe, not a compliance regression. I checked master: shenyu-plugin-motan no longer exists under shenyu-plugin, and neither shenyu-bootstrap/pom.xml nor shenyu-dist/shenyu-bootstrap-dist/pom.xml references motan. Since motan has moved to the shenyu-plugin-store repo and is no longer packaged into the bootstrap, removing the four motan entries + LICENSE-motan.txt is the correct cleanup.
  • Tests are non-vacuous. testDispatchToExternalDefinitionWhenMatched sets both plugin-fake-enabled=true and PLUGIN_DUBBO_ENABLED=true and asserts only fake is dispatched — this proves the external definition wins over the built-in dubbo branch (would fail on master, which has no such concept). testExternalPluginReconcileAndDeleteUseExternalPluginName exercises the full reconcile → delete lifecycle under the external plugin name (saveOrUpdatePluginData("fake") captured, selector created/removed under "fake"). Both genuinely depend on the new code.

Non-blocking observations / suggestions

  1. (Pre-existing, not introduced here) getPluginName and enablePluginsBasedOnAnnotations have no BRPC branch, while parse does. An ingress that enables only brpc would be parsed into a brpc config, but getPluginName falls through to DIVIDE and mis-routes the selector. This is a latent inconsistency in the existing code; please track it as a follow-up issue rather than folding it into this refactor.
  2. Static cache concurrency (pre-existing). IngressSelectorCache.get returns the live internal List from the ConcurrentMap (not a copy), and that cache is shared by the two reconcile worker threads (IngressControllerConfiguration wires each controller with withWorkerCount(2)). Concurrent put/remove/iterate on the same ingress key can throw ConcurrentModificationException. This predates the PR, but the new metadataPaths loop slightly widens the iteration surface. Consider returning a defensive copy, or documenting the contract.
  3. Design clarity. When an ingress matches an external definition, enablePluginsBasedOnAnnotations entirely skips the built-in plugin enablement (dubbo/ws/grpc/sofa). That is the intended "takeover" semantics, but it's worth stating explicitly in the IngressPluginDefinition javadoc / PR description so that a user who sets both an external annotation and a built-in one understands the built-in side is silently ignored.
  4. Upstream refresh scope. updateUpstreamFromEndpoints only refreshes DIVIDE/WEB_SOCKET upstreams and now also skips external plugins. That is correct for registry-based plugins (Motan/dubbo/sofa manage their own upstreams), but if a future external definition wants k8s-endpoints-based upstreams it will need to override the path — a note on the interface would help.
  5. Test readability. assertEquals(new Result(false), result) in the new test reads like "reconcile failed". Result(false) is the kubernetes-client framework's "do not requeue" signal (the method always returns it), not a failure. A one-line comment would prevent future misreads.

Conclusion

No blocking issues. The extension point is well-designed, backward compatible, and the motan LICENSE removal is verified-safe. Approving. The observations above (#1 and #2 are pre-existing and can be tracked separately) are optional follow-ups. See the two inline nits on the new interface for small API-doc improvements.

@Aias00
Aias00 merged commit 91bd8d0 into apache:master Oct 9, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants