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 97affed698 [type:fix] Preserve copied API bean paths during
registration (#7256)
97affed698 is described below
commit 97affed6985384983e9025072fd34729dc0e4011
Author: Liming Deng <[email protected]>
AuthorDate: Wed Sep 30 11:37:58 2026 +0800
[type:fix] Preserve copied API bean paths during registration (#7256)
* fix(client): bind copied API definitions to their copied bean
* test(client): clarify independent registration state in API copies
---
.../shenyu/client/core/register/ApiBean.java | 6 +-
.../client/core/register/ApiBeanCopyTest.java | 67 ++++++++++++++++++++++
2 files changed, 71 insertions(+), 2 deletions(-)
diff --git
a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
index a50cdfa5ae..afa1c9de94 100644
---
a/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
+++
b/shenyu-client/shenyu-client-core/src/main/java/org/apache/shenyu/client/core/register/ApiBean.java
@@ -238,7 +238,8 @@ public class ApiBean {
}
/**
- * deep copy.
+ * Copy API metadata for independent processing by another registrar.
+ * Bean and definition registration states intentionally restart at INIT;
the bean instance and Methods are shared.
*
* @return ApiBean
*/
@@ -246,7 +247,7 @@ public class ApiBean {
final ApiBean copy = new ApiBean(clientName, beanName, beanInstance,
beanPath);
beanProperties.forEach((k, v) -> copy.addProperties(k.toString(),
Objects.toString(v)));
for (ApiDefinition definition : apiDefinitions) {
- final ApiDefinition newDefinition = new ApiDefinition(this,
definition.apiMethod, definition.methodPath);
+ final ApiDefinition newDefinition = new ApiDefinition(copy,
definition.apiMethod, definition.methodPath);
definition.apiProperties.forEach((k, v) ->
newDefinition.addProperties(k.toString(), Objects.toString(v)));
copy.apiDefinitions.add(newDefinition);
}
@@ -266,6 +267,7 @@ public class ApiBean {
/**
* The instance of the class in which the function resides.
+ * Assigned later when an initially unbound definition is supplied to
the ApiBean list constructor.
*/
private ApiBean apiBean;
diff --git
a/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/ApiBeanCopyTest.java
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/ApiBeanCopyTest.java
new file mode 100644
index 0000000000..8a52c4fb83
--- /dev/null
+++
b/shenyu-client/shenyu-client-core/src/test/java/org/apache/shenyu/client/core/register/ApiBeanCopyTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.client.core.register;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+/**
+ * Tests ownership and mutation isolation of copied API definitions.
+ */
+public class ApiBeanCopyTest {
+
+ @Test
+ public void testCopiedDefinitionsUseCopiedBeanPath() throws
NoSuchMethodException {
+ ApiBean original = new ApiBean("http", "bean", new Object(),
"/original");
+ original.addProperties("bean-property", "original");
+ original.addApiDefinition(Object.class.getMethod("toString"),
"/first");
+ original.addApiDefinition(Object.class.getMethod("hashCode"),
"/second");
+ original.getApiDefinitions().get(0).addProperties("api-property",
"original");
+ original.setStatus(ApiBean.Status.REGISTERED);
+
original.getApiDefinitions().get(0).setStatus(ApiBean.Status.REGISTERED);
+ ApiBean copy = original.copy();
+ assertEquals(ApiBean.Status.INIT, copy.getStatus());
+ assertEquals(ApiBean.Status.REGISTERED, original.getStatus());
+ assertEquals(ApiBean.Status.REGISTERED,
original.getApiDefinitions().get(0).getStatus());
+ assertNotSame(copy.getApiDefinitions().get(0),
copy.getApiDefinitions().get(1));
+ copy.setBeanPath("/processed");
+ copy.addProperties("bean-property", "copied");
+ copy.getApiDefinitions().get(0).addProperties("api-property",
"copied");
+ copy.getApiDefinitions().get(0).setMethodPath("/changed");
+ assertSame(original.getBeanInstance(), copy.getBeanInstance());
+ for (int i = 0; i < original.getApiDefinitions().size(); i++) {
+ ApiBean.ApiDefinition copiedDefinition =
copy.getApiDefinitions().get(i);
+ ApiBean.ApiDefinition originalDefinition =
original.getApiDefinitions().get(i);
+ assertNotSame(originalDefinition, copiedDefinition);
+ assertSame(copy, copiedDefinition.getApiBean());
+ assertEquals(ApiBean.Status.INIT, copiedDefinition.getStatus());
+ assertSame(original, originalDefinition.getApiBean());
+ assertEquals("/processed", copiedDefinition.getBeanPath());
+ assertEquals("/original", originalDefinition.getBeanPath());
+ assertEquals(originalDefinition.getApiMethod(),
copiedDefinition.getApiMethod());
+ }
+ assertEquals("original", original.getPropertiesValue("bean-property"));
+ assertEquals("original",
original.getApiDefinitions().get(0).getPropertiesValue("api-property"));
+ assertEquals("/first",
original.getApiDefinitions().get(0).getMethodPath());
+ assertEquals("/second",
copy.getApiDefinitions().get(1).getMethodPath());
+ }
+}