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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0df2440  [type:fixbug] sofa plugin register metadata and parameters 
resolve [fix pr#2103]  (#2112)
0df2440 is described below

commit 0df24404d2e5d173e707f9b0a0cd5932ae4e2976
Author: likeguo <[email protected]>
AuthorDate: Wed Sep 22 18:12:13 2021 +0800

    [type:fixbug] sofa plugin register metadata and parameters resolve [fix 
pr#2103]  (#2112)
    
    * fixbug/sofa-plugin: Fix the param resolve bug
    
    * fixbug/sofa-plugin: Fix the param resolve bug
---
 .../client/sofa/SofaServiceBeanPostProcessor.java  |  20 +++-
 .../src/main/http/sofa-test-api.http               |  46 ++++----
 .../sofa/param/SofaParamResolveServiceImpl.java    | 130 +++++++++++++++------
 .../param/SofaBodyParamResolveServiceTest.java     |  24 ++--
 4 files changed, 145 insertions(+), 75 deletions(-)

diff --git 
a/shenyu-client/shenyu-client-sofa/src/main/java/org/apache/shenyu/client/sofa/SofaServiceBeanPostProcessor.java
 
b/shenyu-client/shenyu-client-sofa/src/main/java/org/apache/shenyu/client/sofa/SofaServiceBeanPostProcessor.java
index c8ddc53..be563c1 100644
--- 
a/shenyu-client/shenyu-client-sofa/src/main/java/org/apache/shenyu/client/sofa/SofaServiceBeanPostProcessor.java
+++ 
b/shenyu-client/shenyu-client-sofa/src/main/java/org/apache/shenyu/client/sofa/SofaServiceBeanPostProcessor.java
@@ -19,7 +19,6 @@ package org.apache.shenyu.client.sofa;
 
 import com.alipay.sofa.runtime.service.component.Service;
 import com.alipay.sofa.runtime.spring.factory.ServiceFactoryBean;
-
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import org.apache.commons.lang3.StringUtils;
 import 
org.apache.shenyu.client.core.disruptor.ShenyuClientRegisterEventPublisher;
@@ -38,6 +37,8 @@ import 
org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.util.ReflectionUtils;
 
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.Properties;
@@ -52,7 +53,7 @@ public class SofaServiceBeanPostProcessor implements 
BeanPostProcessor {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(SofaServiceBeanPostProcessor.class);
 
-    private ShenyuClientRegisterEventPublisher publisher = 
ShenyuClientRegisterEventPublisher.getInstance();
+    private final ShenyuClientRegisterEventPublisher publisher = 
ShenyuClientRegisterEventPublisher.getInstance();
 
     private final ExecutorService executorService;
 
@@ -119,9 +120,18 @@ public class SofaServiceBeanPostProcessor implements 
BeanPostProcessor {
         String configRuleName = shenyuSofaClient.ruleName();
         String ruleName = ("".equals(configRuleName)) ? path : configRuleName;
         String methodName = method.getName();
-        Class<?>[] parameterTypesClazz = method.getParameterTypes();
-        String parameterTypes = 
Arrays.stream(parameterTypesClazz).map(Class::getName)
-                .collect(Collectors.joining(","));
+        String parameterTypes = Arrays.stream(method.getParameters())
+                .map(parameter -> {
+                    StringBuilder result = new 
StringBuilder(parameter.getType().getName());
+                    final Type type = parameter.getParameterizedType();
+                    if (type instanceof ParameterizedType) {
+                        final Type[] actualTypeArguments = 
((ParameterizedType) type).getActualTypeArguments();
+                        for (Type actualTypeArgument : actualTypeArguments) {
+                            
result.append("#").append(actualTypeArgument.getTypeName());
+                        }
+                    }
+                    return result.toString();
+                }).collect(Collectors.joining(","));
         return MetaDataRegisterDTO.builder()
                 .appName(appName)
                 .serviceName(serviceName)
diff --git 
a/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/src/main/http/sofa-test-api.http
 
b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/src/main/http/sofa-test-api.http
index 0d4639b..3f29522 100644
--- 
a/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/src/main/http/sofa-test-api.http
+++ 
b/shenyu-examples/shenyu-examples-sofa/shenyu-examples-sofa-service/src/main/http/sofa-test-api.http
@@ -35,8 +35,10 @@ Accept: application/json
 Content-Type: application/json
 
 {
-  "id": 123,
-  "name": "test"
+  "sofaSimpleTypeBean": {
+    "id": 123,
+    "name": "test"
+  }
 }
 
 ### shengyu getway proxy findByIdsAndName
@@ -145,17 +147,19 @@ Accept: application/json
 Content-Type: application/json
 
 {
-  "sofaSimpleTypeBean": {
-    "id": "123",
-    "name": "test"
-  },
-  "idLists": [
-    123,
-    124
-  ],
-  "idMaps": {
-    "abc": "abc",
-    "cbd": "cbd"
+  "sofaComplexTypeBean": {
+    "sofaSimpleTypeBean": {
+      "id": "123",
+      "name": "test"
+    },
+    "idLists": [
+      123,
+      124
+    ],
+    "idMaps": {
+      "abc": "abc",
+      "cbd": "cbd"
+    }
   }
 }
 
@@ -204,12 +208,14 @@ Content-Type: application/json
       }
     }
   ],
-  "testKey1": {
-    "id": "123",
-    "name": "test"
-  },
-  "testKey2": {
-    "id": "123",
-    "name": "test"
+  "sofaSimpleTypeBeanMap": {
+    "testKey1": {
+      "id": "123",
+      "name": "test"
+    },
+    "testKey2": {
+      "id": "123",
+      "name": "test"
+    }
   }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/param/SofaParamResolveServiceImpl.java
 
b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/param/SofaParamResolveServiceImpl.java
index e0c244e..e6bf5bb 100644
--- 
a/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/param/SofaParamResolveServiceImpl.java
+++ 
b/shenyu-plugin/shenyu-plugin-sofa/src/main/java/org/apache/shenyu/plugin/sofa/param/SofaParamResolveServiceImpl.java
@@ -17,6 +17,8 @@
 
 package org.apache.shenyu.plugin.sofa.param;
 
+import com.alipay.hessian.generic.model.GenericCollection;
+import com.alipay.hessian.generic.model.GenericMap;
 import com.alipay.hessian.generic.model.GenericObject;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
@@ -24,13 +26,10 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.shenyu.common.utils.GsonUtils;
-import org.apache.shenyu.plugin.api.utils.BodyParamUtils;
 
-import java.util.Arrays;
-import java.util.LinkedList;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * The type Default generic param resolve service.
@@ -39,47 +38,92 @@ public class SofaParamResolveServiceImpl implements 
SofaParamResolveService {
 
     @Override
     public Pair<String[], Object[]> buildParameter(final String body, final 
String parameterTypes) {
-        String[] parameterTypesAndGeneric = StringUtils.split(parameterTypes, 
"#");
-        String[] parameters = StringUtils.split(parameterTypesAndGeneric[0], 
",");
-        if (isSingleCustomizeType(parameters)) {
-            return BodyParamUtils.buildSingleParameter(body, parameterTypes);
+        final String[] parameterTypeStrings = 
StringUtils.split(parameterTypes, ",");
+        List<String> parameterTypeArr = new 
ArrayList<>(parameterTypeStrings.length);
+        List<Object> values = new ArrayList<>();
+        final List<Object> params = new 
ArrayList<>(GsonUtils.getInstance().toObjectMap(body).values());
+        for (int paramIndex = 0; paramIndex < parameterTypeStrings.length; 
paramIndex++) {
+            final String[] parameter = 
StringUtils.split(parameterTypeStrings[paramIndex], "#");
+            parameterTypeArr.add(parameter[0]);
+            values.add(convertToParameterValue(params.get(paramIndex), 
parameter));
         }
-        LinkedList<String> genericTypes = new LinkedList<>();
-        if (parameterTypesAndGeneric.length > 1) {
-            
genericTypes.addAll(Arrays.asList(StringUtils.split(parameterTypesAndGeneric[1],
 ",")));
+        return new ImmutablePair<>(parameterTypeArr.toArray(new String[0]), 
values.toArray());
+    }
+
+    /**
+     * convert to parameter value.
+     *
+     * @param value         value support [json object string, json array 
string,string]
+     * @param parameterType parameter type support 
[javaPackage.ClassName#GenericType1#GenericType2], split is ,
+     * @return GenericObject, GenericMap, List, string, array...
+     * @see com.alipay.hessian.generic.model
+     */
+    @SuppressWarnings("all")
+    private Object convertToParameterValue(final Object value, final String[] 
parameterType) {
+        if (isSingleType(parameterType)) {
+            return value;
         }
-        Map<String, Object> paramMap = 
GsonUtils.getInstance().toObjectMap(body);
-        Object[] objects = paramMap.values().stream().map(each -> {
-            if (each instanceof JsonObject) {
-                return GsonUtils.getInstance().convertToMap(each.toString());
-            } else if (each instanceof JsonArray) {
-                if (genericTypes.isEmpty()) {
-                    return GsonUtils.getInstance().fromList(each.toString(), 
Object.class);
-                }
-                String type = genericTypes.pop();
-                return convertToGenericObjects(type, each);
-            } else {
-                return each;
+        if (value instanceof JsonObject && parameterType[0].contains("Map")) {
+            final Map<String, Object> mapValue = 
GsonUtils.getInstance().convertToMap(value.toString());
+            if (parameterType.length == 1) {
+                // no generic info
+                return mapValue;
             }
-        }).toArray();
-        return new ImmutablePair<>(parameters, objects);
+            assert parameterType.length == 3;
+            // generic map
+            final GenericMap genericMap = new GenericMap(parameterType[2]);
+            mapValue.replaceAll((k, v) -> 
convertToGenericObject(parameterType[2], mapValue.get(k)));
+            genericMap.setMap(mapValue);
+            return genericMap;
+        }
+        if (value instanceof JsonObject) {
+            return convertToGenericObject(parameterType[0], value);
+        }
+        if (value instanceof JsonArray) {
+            if (parameterType.length == 1) {
+                // no generic info
+                return GsonUtils.getInstance().fromList(value.toString(), 
Object.class);
+            }
+            // generic collection
+            final GenericCollection genericCollection = new 
GenericCollection(parameterType[1]);
+            
genericCollection.setCollection(convertToGenericObjects(parameterType[1], 
(Iterable<Object>) value));
+            return genericCollection;
+        }
+        return value;
+    }
+
+    /**
+     * convert json object to {@link GenericObject}.
+     *
+     * @param paramType  param type string
+     * @param paramValue param value (if is object, auto to convert string)
+     * @return {@link GenericObject},if is single customize type return  
paramValue
+     * @see GenericObject
+     * @see #isSingleType(String)
+     */
+    private static Object convertToGenericObject(final String paramType, final 
Object paramValue) {
+        if (isSingleType(paramType)) {
+            return paramValue;
+        }
+        final Map<String, Object> mapValue = 
GsonUtils.getInstance().convertToMap(paramValue.toString());
+        GenericObject genericObject = new GenericObject(paramType);
+        mapValue.forEach(genericObject::putField);
+        return genericObject;
     }
 
     /**
      * Convert to GenericObject.
      *
-     * @param type generic type.
-     * @param param actual parameter.
+     * @param type   generic type.
+     * @param params actual parameters.
      * @return list of GenericObject.
      */
-    @SuppressWarnings("all")
-    private static List<GenericObject> convertToGenericObjects(final String 
type, final Object param) {
-        List<Map> mapList = GsonUtils.getInstance().fromList(param.toString(), 
Map.class);
-        return mapList.stream().map(map -> {
-            GenericObject genericObject = new GenericObject(type);
-            map.forEach((key, value) -> genericObject.putField((String) key, 
value));
-            return genericObject;
-        }).collect(Collectors.toList());
+    private static List<Object> convertToGenericObjects(final String type, 
final Iterable<Object> params) {
+        List<Object> list = new ArrayList<>();
+        for (Object param : params) {
+            list.add(convertToGenericObject(type, param));
+        }
+        return list;
     }
 
     /**
@@ -88,7 +132,19 @@ public class SofaParamResolveServiceImpl implements 
SofaParamResolveService {
      * @param parameter parameter array.
      * @return only one parameter and it's customized type return true 
otherwise return false.
      */
-    private static boolean isSingleCustomizeType(final String[] parameter) {
-        return parameter.length == 1 && !parameter[0].startsWith("java") && 
!parameter[0].startsWith("[Ljava");
+    private static boolean isSingleType(final String[] parameter) {
+        return parameter.length == 1 && isSingleType(parameter[0]);
     }
+
+    /**
+     * is single type.<br>
+     * single type is package[java.xxx or [Ljava.xxx]
+     *
+     * @param parameterType parameter type.
+     * @return type is single type
+     */
+    private static boolean isSingleType(final String parameterType) {
+        return parameterType.startsWith("java");
+    }
+
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/param/SofaBodyParamResolveServiceTest.java
 
b/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/param/SofaBodyParamResolveServiceTest.java
index 75ddd8b..d710caa 100644
--- 
a/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/param/SofaBodyParamResolveServiceTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-sofa/src/test/java/org/apache/shenyu/plugin/sofa/param/SofaBodyParamResolveServiceTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shenyu.plugin.sofa.param;
 
+import com.alipay.hessian.generic.model.GenericObject;
 import org.apache.commons.lang3.tuple.Pair;
 
 import org.junit.Test;
@@ -93,32 +94,29 @@ public final class SofaBodyParamResolveServiceTest {
         Pair<String[], Object[]> pair = impl.buildParameter(body, 
parameterTypes);
         assertThat(pair.getLeft().length, is(1));
         assertThat(pair.getRight().length, is(1));
-        Map map = (Map) pair.getRight()[0];
-        map = (Map) map.get("student");
-        assertNull(map.get("id"));
-        assertNull(map.get("name"));
+        GenericObject student = (GenericObject) pair.getRight()[0];
+        assertNull(student.getField("id"));
+        assertNull(student.getField("name"));
 
         body = "{\"students\":[{\"id\":null,\"name\":null}]}";
         parameterTypes = 
"org.apache.shenyu.web.rpc.DubboMultiParameterResolveServiceImplTest.Student[]";
         pair = impl.buildParameter(body, parameterTypes);
         assertThat(pair.getLeft().length, is(1));
         assertThat(pair.getRight().length, is(1));
-        map = (Map) pair.getRight()[0];
-        List list = (List) map.get("students");
-        map = (Map) list.get(0);
+        List list = (List) pair.getRight()[0];
+        Map map = (Map) list.get(0);
         assertNull(map.get("id"));
         assertNull(map.get("name"));
 
-        body = 
"{\"dubboTest\":{\"id\":null,\"name\":null},\"idLists\":[null,null],\"idMaps\":{\"id2\":null,\"id1\":null}}";
+        body = 
"{\"complexBean\":{\"dubboTest\":{\"id\":null,\"name\":null},\"idLists\":[null,null],\"idMaps\":{\"id2\":null,\"id1\":null}}}";
         parameterTypes = 
"org.apache.shenyu.web.rpc.DubboMultiParameterResolveServiceImplTest.ComplexBean";
         pair = impl.buildParameter(body, parameterTypes);
         assertThat(pair.getLeft().length, is(1));
         assertThat(pair.getRight().length, is(1));
-        map = (Map) pair.getRight()[0];
-        Map dubboTest = (Map) map.get("dubboTest");
-        assertNull(dubboTest.get("id"));
-        assertNull(dubboTest.get("name"));
-        list = (List) map.get("idLists");
+        GenericObject dubboTest = (GenericObject) pair.getRight()[0];
+        assertNull(dubboTest.getField("id"));
+        assertNull(dubboTest.getField("name"));
+        list = (List) dubboTest.getField("idLists");
         assertNull(list.get(0));
         assertNull(list.get(1));
 

Reply via email to