This is an automated email from the ASF dual-hosted git repository.

yu199195 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 567142e072 Fixed selector and rule  match bug (#7055)
567142e072 is described below

commit 567142e07261b3e615ae8850b30f4421f455cc5d
Author: xiaoyu <[email protected]>
AuthorDate: Fri Sep 11 15:38:20 2026 +0800

    Fixed selector and rule  match bug (#7055)
    
    * chore: add .gitnexus to .gitignore
    
    * feat: add GitNexus documentation and configuration files
    
    * chore: update .gitignore to include .claude and .agents
    
    * fix: improve null handling in selector and rule data processing
    
    * feat: add CLAUDE.md for project guidance and documentation
    
    ---------
    
    Co-authored-by: yu.xiao <[email protected]>
---
 .gitignore                                         |  5 +-
 .idea/vcs.xml                                      |  7 +++
 CLAUDE.md                                          | 59 ++++++++++++++++++++++
 .../shenyu/plugin/base/AbstractShenyuPlugin.java   | 12 +++--
 4 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/.gitignore b/.gitignore
index e266500fd7..a152504936 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,6 @@ target/
 *.class
 *.jar
 *.war
-*.zip
 *.tar
 *.tar.gz
 .flattened-pom.xml
@@ -18,7 +17,8 @@ cobertura.ser
 .settings/
 .project
 .classpath
-
+.claude
+.agents
 # idea ignore
 .idea/
 !/.idea/icon.svg
@@ -53,3 +53,4 @@ Thumbs.db
 
 # local worktrees
 .worktrees/
+.gitnexus
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 35eb1ddfbb..1364320233 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,5 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="GitSharedSettings">
+    <option name="FORCE_PUSH_PROHIBITED_PATTERNS">
+      <list>
+        <option value="main" />
+      </list>
+    </option>
+  </component>
   <component name="VcsDirectoryMappings">
     <mapping directory="" vcs="Git" />
   </component>
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000000..c97a4d203b
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,59 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with 
code in this repository.
+
+## Project
+
+Apache ShenYu — a reactive API gateway for microservices. Java 17, Maven 
multi-module build (root `pom.xml`, version `2.7.2-SNAPSHOT`). Use the wrapper 
`./mvnw`, not a local `mvn`.
+
+## Commands
+
+```bash
+# Full build (checkstyle + RAT license check run automatically at validate 
phase)
+./mvnw clean install -DskipTests
+
+# Faster build of one module and its dependencies
+./mvnw -pl shenyu-admin -am clean install -DskipTests 
-Dmaven.javadoc.skip=true -Drat.skip=true -Djacoco.skip=true
+
+# Run all tests in a module
+./mvnw test -pl shenyu-common
+
+# Run a single test class / method (surefire)
+./mvnw test -pl shenyu-common -Dtest=GsonUtilsTest
+./mvnw test -pl shenyu-common -Dtest='GsonUtilsTest#testToJson'
+
+# Checkstyle only
+./mvnw checkstyle:check
+```
+
+- **Checkstyle is enforced on every build** (validate phase). Config: 
`script/shenyu_checkstyle.xml`. It is strict (javadoc, import order, final 
parameters); match the style of surrounding files.
+- **Apache RAT** enforces license headers: every new source file needs the 
Apache 2.0 header (`script/checkstyle-header.txt`).
+- Distribution packages / Docker images: `make build-admin`, `make 
build-bootstrap`, `make build-all-image` (see `Makefile`; builds via 
`shenyu-dist/*`).
+
+## Architecture
+
+ShenYu is split into a **control plane** and a **data plane** that communicate 
only through data-sync channels — the gateway never reads the database.
+
+- **`shenyu-admin`** — control plane. Spring MVC + MyBatis app (port 9095) 
with a web dashboard. Persists plugins/selectors/rules/metadata (DB init 
scripts under `db/`; H2 by default, MySQL/PG/Oracle supported). Structure: 
`controller` → `service` → `mapper`, with `listener` publishing config-change 
events.
+- **`shenyu-admin-listener`** + **`shenyu-sync-data-center`** — config sync 
from admin to gateways. One submodule per channel: websocket (default), http 
long-polling, zookeeper, nacos, etcd, consul, apollo, polaris. Gateway-side 
subscribers update in-memory caches; changed config takes effect without 
restart.
+- **`shenyu-bootstrap`** — data plane. A thin Spring WebFlux launcher; its 
behavior is composed by which starters are on its classpath 
(`shenyu-spring-boot-starter-*`). Port 9195.
+- **`shenyu-web`** — gateway runtime core. `ShenyuWebHandler` 
(`shenyu-web/.../web/handler/ShenyuWebHandler.java`) executes an ordered chain 
of plugins per request.
+- **`shenyu-plugin`** — all gateway features are plugins.
+  - `shenyu-plugin-api`: `ShenyuPlugin` (reactive `execute(exchange, chain)` + 
`getOrder()`), `ShenyuPluginChain`, `ShenyuContext`.
+  - `shenyu-plugin-base`: `AbstractShenyuPlugin` implements selector → rule 
matching against cached config, then calls the concrete plugin's `doExecute`; 
`PluginDataHandler` implementations receive config updates from data sync into 
per-plugin caches.
+  - Feature plugins grouped by category: `shenyu-plugin-proxy` (dubbo, grpc, 
spring-cloud, sofa, tars, websocket, mqtt...), `-security`, `-logging`, 
`-cache`, `-fault-tolerance`, `-ai`, `-mcp-server`, etc. A plugin is activated 
by adding its starter to the bootstrap pom.
+- **`shenyu-spi`** — custom SPI extension mechanism: `@SPI` on the interface, 
`@Join` on implementations, registration files under `META-INF/shenyu/`. Used 
for load balancers, condition matchers, etc. (`shenyu-loadbalancer` plugs in 
this way).
+- **`shenyu-client`** + **`shenyu-register-center`** — client-side API 
registration. Backend services annotate endpoints (e.g. 
`@ShenyuSpringMvcClient`) and register metadata/URIs to admin through a 
register channel (http, zookeeper, nacos...). Admin consumes registrations 
through `shenyu-disruptor` (async event pipeline).
+- **`shenyu-common`** — shared model (`PluginData`, `SelectorData`, 
`RuleData`, `MetaData`), enums, constants, utils. Config semantics live here, 
so changes ripple to both admin and gateway.
+
+Typical config flow: dashboard/API change in admin → DB write + change event → 
sync channel → gateway subscriber updates cache → `AbstractShenyuPlugin` 
matches subsequent requests against new selectors/rules.
+
+## Testing modules
+
+- Unit tests live per module (surefire).
+- `shenyu-integrated-test` and `shenyu-e2e` are Docker-based integration/e2e 
suites run in CI; not part of a normal local build.
+- `shenyu-examples` contains sample backend services for manually exercising 
the gateway.
+
+## GitNexus code intelligence
+
+This repo is indexed by the GitNexus MCP server (repo name `shenyu`). Prefer 
`query`/`context` for finding execution flows across the admin↔gateway 
boundary, and `impact` before refactoring widely-used symbols (e.g. anything in 
`shenyu-common`). Skill docs live under `.claude/skills/gitnexus/`.
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
index 83b1e9fa81..87b4214c05 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java
@@ -99,9 +99,11 @@ public abstract class AbstractShenyuPlugin implements 
ShenyuPlugin {
         if (Objects.nonNull(selectorData) && 
StringUtils.isBlank(selectorData.getId())) {
             return handleSelectorIfNull(pluginName, exchange, chain);
         }
-        selectorData = defaultMatchSelector(exchange, selectors, path);
         if (Objects.isNull(selectorData)) {
-            return handleSelectorIfNull(pluginName, exchange, chain);
+            selectorData = defaultMatchSelector(exchange, selectors, path);
+            if (Objects.isNull(selectorData)) {
+                return handleSelectorIfNull(pluginName, exchange, chain);
+            }
         }
         printLog(selectorData, pluginName);
         if (!selectorData.getContinued()) {
@@ -125,9 +127,11 @@ public abstract class AbstractShenyuPlugin implements 
ShenyuPlugin {
         if (Objects.nonNull(ruleData) && Objects.isNull(ruleData.getId())) {
             return handleRuleIfNull(pluginName, exchange, chain);
         }
-        ruleData = defaultMatchRule(exchange, rules, path);
         if (Objects.isNull(ruleData)) {
-            return handleRuleIfNull(pluginName, exchange, chain);
+            ruleData = defaultMatchRule(exchange, rules, path);
+            if (Objects.isNull(ruleData)) {
+                return handleRuleIfNull(pluginName, exchange, chain);
+            }
         }
         printLog(ruleData, pluginName);
         return doExecute(exchange, chain, selectorData, ruleData);

Reply via email to