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 303d06c2d [fix:compatibility #3374]grpc plugin compatible with low 
version and output standard format json (#3379)
303d06c2d is described below

commit 303d06c2dfc247030ade170ff93c3e455f77dfe1
Author: hutaishi <[email protected]>
AuthorDate: Fri May 6 14:47:30 2022 +0800

    [fix:compatibility #3374]grpc plugin compatible with low version and output 
standard format json (#3379)
    
    * [fix:compatibility #3374]GRPC plugin is not compatible with low versions
    
    * [fix:compatibility #3374]GRPC plugin is not compatible with low versions
    
    * [fix:compatibility #3374]GRPC plugin is not compatible with low versions
    
    * [fix:compatibility #3374]GRPC plugin is not compatible with low versions
    
    * [fix:compatibility #3374]GRPC plugin is not compatible with low versions
    
    * export realtime
---
 .../grpc/json/JsonServerServiceInterceptor.java    | 59 +++++++++++++---------
 .../integrated/test/grpc/GrpcPluginTest.java       |  2 +-
 .../shenyu/plugin/grpc/proto/MessageWriter.java    | 31 +++++++++---
 .../plugin/grpc/proto/ShenyuGrpcResponse.java      |  6 +--
 4 files changed, 64 insertions(+), 34 deletions(-)

diff --git 
a/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java
 
b/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java
index 4a035253b..9a2835f78 100644
--- 
a/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java
+++ 
b/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerServiceInterceptor.java
@@ -17,25 +17,28 @@
 
 package org.apache.shenyu.client.grpc.json;
 
-import com.google.common.collect.Maps;
-import io.grpc.MethodDescriptor;
-import io.grpc.ServerMethodDefinition;
-import io.grpc.ServerServiceDefinition;
-import io.grpc.ServiceDescriptor;
-import io.grpc.ServerCallHandler;
-import io.grpc.ServerCall;
-import io.grpc.Metadata;
-import org.apache.shenyu.common.exception.ShenyuException;
-import org.apache.shenyu.common.utils.ReflectUtils;
-import org.apache.shenyu.protocol.grpc.constant.GrpcConstants;
-import org.apache.shenyu.protocol.grpc.message.JsonMessage;
-
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
+import org.apache.shenyu.common.exception.ShenyuException;
+import org.apache.shenyu.common.utils.ReflectUtils;
+import org.apache.shenyu.protocol.grpc.constant.GrpcConstants;
+import org.apache.shenyu.protocol.grpc.message.JsonMessage;
+
+import com.google.common.collect.Maps;
+
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import io.grpc.MethodDescriptor.PrototypeMarshaller;
+import io.grpc.ServerCall;
+import io.grpc.ServerCallHandler;
+import io.grpc.ServerMethodDefinition;
+import io.grpc.ServerServiceDefinition;
+import io.grpc.ServiceDescriptor;
+
 /**
  * Support json invoke.
  */
@@ -77,19 +80,28 @@ public class JsonServerServiceInterceptor {
         for (final ServerMethodDefinition<?, ?> definition : 
serviceDef.getMethods()) {
             MethodDescriptor.Marshaller<?> requestMarshaller = 
definition.getMethodDescriptor().getRequestMarshaller();
             Field defaultInstanceField = 
ReflectUtils.getField(requestMarshaller.getClass(), "defaultInstance");
+            Class grpcRequestParamClass = null;
             if (Objects.isNull(defaultInstanceField)) {
-                throw new ShenyuException(String.format("can not get 
defaultInstance Field of %s", requestMarshaller.getClass()));
+                // Compatible with lower versions. eg: grpc 1.6.0
+                if (requestMarshaller instanceof 
MethodDescriptor.PrototypeMarshaller) {
+                    MethodDescriptor.PrototypeMarshaller<?> 
prototypeMarshaller = (PrototypeMarshaller<?>) requestMarshaller;
+                    if 
(Objects.isNull(prototypeMarshaller.getMessagePrototype())) {
+                        throw new ShenyuException(String.format("can not get 
defaultInstance Field of %s", requestMarshaller.getClass()));
+                    }
+                    grpcRequestParamClass = 
prototypeMarshaller.getMessagePrototype().getClass();
+                }
+            } else {
+                defaultInstanceField.setAccessible(true);
+                grpcRequestParamClass = 
defaultInstanceField.get(requestMarshaller).getClass();
             }
 
-            defaultInstanceField.setAccessible(true);
-
             String fullMethodName = 
definition.getMethodDescriptor().getFullMethodName();
             MethodDescriptor.MethodType methodType = 
definition.getMethodDescriptor().getType();
             METHOD_TYPE_MAP.put(fullMethodName, methodType);
 
             String[] splitMethodName = fullMethodName.split("/");
             fullMethodName = splitMethodName[0] + 
GrpcConstants.GRPC_JSON_SERVICE + "/" + splitMethodName[1];
-            REQUEST_CLAZZ_MAP.put(fullMethodName, 
defaultInstanceField.get(requestMarshaller).getClass());
+            REQUEST_CLAZZ_MAP.put(fullMethodName, grpcRequestParamClass);
 
             final MethodDescriptor<?, ?> originalMethodDescriptor = 
definition.getMethodDescriptor();
             final MethodDescriptor<T, T> wrappedMethodDescriptor = 
originalMethodDescriptor
@@ -111,15 +123,14 @@ public class JsonServerServiceInterceptor {
             fullMethodName = splitMethodName[0] + 
GrpcConstants.GRPC_JSON_SERVICE + "/" + splitMethodName[1];
             fullMethodNameField.set(md, fullMethodName);
 
+            // Compatible with lower versions. Lower versions do not have this 
field. eg: grpc 1.6.0
             Field serviceNameField = ReflectUtils.getField(md.getClass(), 
"serviceName");
-            if (Objects.isNull(serviceNameField)) {
-                throw new ShenyuException(String.format("can not get 
serviceName Field Field of %s", md.getClass()));
+            if (Objects.nonNull(serviceNameField)) {
+                serviceNameField.setAccessible(true);
+                String serviceName = (String) serviceNameField.get(md);
+                serviceName = serviceName + GrpcConstants.GRPC_JSON_SERVICE;
+                serviceNameField.set(md, serviceName);
             }
-            serviceNameField.setAccessible(true);
-            String serviceName = (String) serviceNameField.get(md);
-            serviceName = serviceName + GrpcConstants.GRPC_JSON_SERVICE;
-            serviceNameField.set(md, serviceName);
-
             build.addMethod(md);
         }
         final ServerServiceDefinition.Builder serviceBuilder = 
ServerServiceDefinition
diff --git 
a/shenyu-integrated-test/shenyu-integrated-test-grpc/src/test/java/org/apache/shenyu/integrated/test/grpc/GrpcPluginTest.java
 
b/shenyu-integrated-test/shenyu-integrated-test-grpc/src/test/java/org/apache/shenyu/integrated/test/grpc/GrpcPluginTest.java
index 62469ea1b..84767771b 100644
--- 
a/shenyu-integrated-test/shenyu-integrated-test-grpc/src/test/java/org/apache/shenyu/integrated/test/grpc/GrpcPluginTest.java
+++ 
b/shenyu-integrated-test/shenyu-integrated-test-grpc/src/test/java/org/apache/shenyu/integrated/test/grpc/GrpcPluginTest.java
@@ -45,7 +45,7 @@ public class GrpcPluginTest extends AbstractPluginDataInit {
     public void testHelloWorld() throws Exception {
         JsonObject request = buildGrpcRequest();
         JsonArray response = HttpHelper.INSTANCE.postGateway("/grpc/echo", 
request, JsonArray.class);
-        Map<String, Object> result = 
GsonUtils.getInstance().toObjectMap(response.get(0).getAsString(), 
Object.class);
+        Map<String, Object> result = 
GsonUtils.getInstance().toObjectMap(response.get(0).toString(), Object.class);
         assertEquals("ReceivedHELLO", result.get("message"));
     }
 
diff --git 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/MessageWriter.java
 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/MessageWriter.java
index 458ffc920..1a1bf7a87 100644
--- 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/MessageWriter.java
+++ 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/MessageWriter.java
@@ -17,13 +17,20 @@
 
 package org.apache.shenyu.plugin.grpc.proto;
 
-import com.google.protobuf.DynamicMessage;
-import com.google.protobuf.Message;
-import io.grpc.stub.StreamObserver;
+import java.util.HashMap;
+
+import org.apache.commons.lang3.StringUtils;
 import org.apache.shenyu.protocol.grpc.message.JsonMessage;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.protobuf.DynamicMessage;
+import com.google.protobuf.Message;
+
+import io.grpc.stub.StreamObserver;
+
 /**
  * MessageWriter.
  */
@@ -31,6 +38,8 @@ public final class MessageWriter<T extends Message> 
implements StreamObserver<T>
 
     private static final Logger LOG = 
LoggerFactory.getLogger(MessageWriter.class);
 
+    private static final Gson GSON = new Gson();
+
     private final ShenyuGrpcResponse grpcResponse;
 
     private MessageWriter(final ShenyuGrpcResponse grpcResponse) {
@@ -40,8 +49,8 @@ public final class MessageWriter<T extends Message> 
implements StreamObserver<T>
     /**
      * New instance.
      *
-     * @param results  results
-     * @param <T>      t
+     * @param results results
+     * @param <T> t
      * @return message message
      */
     public static <T extends Message> MessageWriter<T> newInstance(final 
ShenyuGrpcResponse results) {
@@ -51,7 +60,17 @@ public final class MessageWriter<T extends Message> 
implements StreamObserver<T>
     @Override
     public void onNext(final T value) {
         String respData = 
JsonMessage.getDataFromDynamicMessage((DynamicMessage) value);
-        grpcResponse.getResults().add(respData);
+        if (StringUtils.isNotBlank(respData)) {
+            respData = respData.trim();
+            if (StringUtils.startsWith(respData, "{") && 
StringUtils.endsWith(respData, "}")) {
+                // standardized json output.
+                grpcResponse.getResults().add(GSON.fromJson(respData,
+                        new TypeToken<HashMap<String, Object>>() {
+                        }.getType()));
+            }
+        } else {
+            grpcResponse.getResults().add(respData);
+        }
     }
 
     @Override
diff --git 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/ShenyuGrpcResponse.java
 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/ShenyuGrpcResponse.java
index 3534a0836..865911713 100644
--- 
a/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/ShenyuGrpcResponse.java
+++ 
b/shenyu-plugin/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/proto/ShenyuGrpcResponse.java
@@ -29,7 +29,7 @@ public class ShenyuGrpcResponse implements Serializable {
 
     private static final long serialVersionUID = 4182753303732523014L;
 
-    private List<String> results;
+    private List<Object> results;
 
     /**
      * Instantiates a new Shenyu grpc response.
@@ -43,7 +43,7 @@ public class ShenyuGrpcResponse implements Serializable {
      *
      * @return the results
      */
-    public List<String> getResults() {
+    public List<Object> getResults() {
         return results;
     }
 
@@ -52,7 +52,7 @@ public class ShenyuGrpcResponse implements Serializable {
      *
      * @param results the results
      */
-    public void setResults(final List<String> results) {
+    public void setResults(final List<Object> results) {
         this.results = results;
     }
 }

Reply via email to