This is an automated email from the ASF dual-hosted git repository.
Aias00 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 f897a5c647 fix(plugin): prefer specific metadata path patterns (#7086)
f897a5c647 is described below
commit f897a5c647a7331233b38548838032e2f4fccdaa
Author: Liming Deng <[email protected]>
AuthorDate: Wed Sep 30 09:57:33 2026 +0800
fix(plugin): prefer specific metadata path patterns (#7086)
* fix(plugin): prefer specific metadata path patterns
* fix(plugin): invalidate cached wildcard matches
---
.../shenyu/plugin/base/cache/MetaDataCache.java | 7 ++-
.../shenyu/plugin/base/utils/PathMatchUtils.java | 12 +++++
.../plugin/base/cache/MetaDataCacheTest.java | 55 ++++++++++++++++++++++
3 files changed, 73 insertions(+), 1 deletion(-)
diff --git
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
index 70d6725844..344fa049ca 100644
---
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
+++
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
@@ -97,6 +97,11 @@ public final class MetaDataCache {
}
private void clean(final String key) {
+ if (key.contains("*")) {
+ CACHE.clear();
+ MAPPING.clear();
+ return;
+ }
// springCloud and divide are needs to be cleaned
Optional.ofNullable(MAPPING.get(key))
.ifPresent(paths -> {
@@ -125,7 +130,7 @@ public final class MetaDataCache {
final MetaData value = META_DATA_MAP.values()
.stream()
.filter(data -> data.getEnabled() &&
PathMatchUtils.match(data.getPath(), path))
- .findFirst()
+ .min((left, right) ->
PathMatchUtils.compare(left.getPath(), right.getPath(), path))
.orElse(null);
final String metaPath = Optional.ofNullable(value)
.map(MetaData::getPath)
diff --git
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/PathMatchUtils.java
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/PathMatchUtils.java
index e69c062200..e3041780b9 100644
---
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/PathMatchUtils.java
+++
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/utils/PathMatchUtils.java
@@ -54,6 +54,18 @@ public class PathMatchUtils {
public static boolean match(final String matchUrls, final String realPath)
{
return MATCHER.match(matchUrls, realPath);
}
+
+ /**
+ * Compare two path patterns for a concrete path.
+ *
+ * @param left the left path pattern
+ * @param right the right path pattern
+ * @param realPath the concrete path
+ * @return a negative value when left is more specific
+ */
+ public static int compare(final String left, final String right, final
String realPath) {
+ return MATCHER.getPatternComparator(realPath).compare(left, right);
+ }
/**
* Path pattern boolean.
diff --git
a/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/cache/MetaDataCacheTest.java
b/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/cache/MetaDataCacheTest.java
new file mode 100644
index 0000000000..a7e6b43690
--- /dev/null
+++
b/shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/cache/MetaDataCacheTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shenyu.plugin.base.cache;
+
+import org.apache.shenyu.common.dto.MetaData;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+class MetaDataCacheTest {
+
+ private final MetaDataCache cache = MetaDataCache.getInstance();
+
+ @AfterEach
+ void tearDown() {
+ cache.getMetaDataMap().clear();
+ cache.getMetaDataCache().clear();
+ }
+
+ @Test
+ void shouldPreferMostSpecificMatchingPattern() {
+ MetaData broad = createMetaData("p", "/api/**");
+ MetaData specific = createMetaData("a", "/api/users/**");
+ cache.cache(broad);
+ assertSame(broad, cache.obtain("/api/users/42"));
+
+ cache.cache(specific);
+
+ assertSame(specific, cache.obtain("/api/users/42"));
+ }
+
+ private MetaData createMetaData(final String id, final String path) {
+ MetaData metaData = new MetaData();
+ metaData.setId(id);
+ metaData.setPath(path);
+ metaData.setEnabled(true);
+ return metaData;
+ }
+}