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;
}
}