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

albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git


The following commit(s) were added to refs/heads/master by this push:
     new 0a61a91  Fix protobuf json serialize object attachments (#143)
0a61a91 is described below

commit 0a61a9125d541430972ca23356e5be455e587a48
Author: Albumen Kevin <[email protected]>
AuthorDate: Thu Sep 29 17:11:25 2022 +0800

    Fix protobuf json serialize object attachments (#143)
---
 .../support/GenericProtobufJsonObjectInput.java    |   9 +-
 .../support/GenericProtobufJsonObjectOutput.java   |   7 +-
 .../protobuf/support/ProtobufAttachmentUtils.java  | 102 ++++++++++++---------
 .../serialize/protobuf/support/ProtobufUtils.java  |  23 ++++-
 .../src/main/proto/MapValue.proto                  |   5 +
 5 files changed, 89 insertions(+), 57 deletions(-)

diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectInput.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectInput.java
index 6a32747..5f5da17 100644
--- 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectInput.java
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectInput.java
@@ -34,7 +34,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.lang.reflect.Type;
-import java.util.HashMap;
 import java.util.Map;
 
 import static 
org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;
@@ -145,12 +144,8 @@ public class GenericProtobufJsonObjectInput implements 
ObjectInput {
     @Override
     public Map<String, Object> readAttachments() throws IOException, 
ClassNotFoundException {
         String json = readLine();
-        Map<String, String> attachments = ProtobufUtils.deserializeJson(json, 
MapValue.Map.class).getAttachmentsMap();
-        Map<String, Object> genericAttachments = new HashMap<>();
-        attachments.forEach((k, v) -> {
-            genericAttachments.put(k, v);
-        });
-        return genericAttachments;
+        MapValue.Map map = ProtobufUtils.deserializeJson(json, 
MapValue.Map.class, ProtobufAttachmentUtils.getTypeRegistry());
+        return ProtobufAttachmentUtils.unwrap(map);
     }
 
     @Override
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectOutput.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectOutput.java
index 27a0aa1..4940e28 100644
--- 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectOutput.java
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/GenericProtobufJsonObjectOutput.java
@@ -32,7 +32,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.util.HashMap;
 import java.util.Map;
 
 import static 
org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;
@@ -145,10 +144,8 @@ public class GenericProtobufJsonObjectOutput implements 
ObjectOutput {
             return;
         }
 
-        Map<String, String> stringAttachments = new HashMap<>();
-        attachments.forEach((k, v) -> stringAttachments.put(k, (String) v));
-        MapValue.Map proto = 
MapValue.Map.newBuilder().putAllAttachments(stringAttachments).build();
-        writer.write(ProtobufUtils.serializeJson(proto));
+        MapValue.Map map = ProtobufAttachmentUtils.wrap(attachments);
+        writer.write(ProtobufUtils.serializeJson(map, 
ProtobufAttachmentUtils.getTypeRegistry()));
         writer.println();
         writer.flush();
     }
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufAttachmentUtils.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufAttachmentUtils.java
index eea20c3..9b9bf85 100644
--- 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufAttachmentUtils.java
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufAttachmentUtils.java
@@ -16,9 +16,10 @@
  */
 package org.apache.dubbo.common.serialize.protobuf.support;
 
+import org.apache.dubbo.common.serialize.protobuf.support.wrapper.MapValue;
+
 import com.google.protobuf.Any;
 import com.google.protobuf.BoolValue;
-import com.google.protobuf.ByteString;
 import com.google.protobuf.DoubleValue;
 import com.google.protobuf.Empty;
 import com.google.protobuf.FloatValue;
@@ -26,14 +27,9 @@ import com.google.protobuf.Int32Value;
 import com.google.protobuf.Int64Value;
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.protobuf.StringValue;
+import com.google.protobuf.util.JsonFormat;
 
-import org.apache.dubbo.common.serialize.protobuf.support.wrapper.MapValue;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -44,6 +40,8 @@ public class ProtobufAttachmentUtils {
     private static Map<String, BuiltinMarshaller> marshallers = new 
HashMap<>();
     private final static String NULL_CLASS_NAME = "null";
 
+    private final static JsonFormat.TypeRegistry typeRegistry;
+
     static {
         marshaller(String.class, new StringMarshaller());
         marshaller(Integer.class, new IntegerMarshaller());
@@ -52,6 +50,21 @@ public class ProtobufAttachmentUtils {
         marshaller(Float.class, new FloatMarshaller());
         marshaller(Double.class, new DoubleMarshaller());
         marshallers.put(NULL_CLASS_NAME, new NullMarshaller());
+        typeRegistry = JsonFormat.TypeRegistry
+            .newBuilder()
+            .add(StringValue.getDescriptor())
+            .add(Int32Value.getDescriptor())
+            .add(Int64Value.getDescriptor())
+            .add(BoolValue.getDescriptor())
+            .add(FloatValue.getDescriptor())
+            .add(DoubleValue.getDescriptor())
+            .add(Empty.getDescriptor())
+            .add(MapValue.Attachment.getDescriptor())
+            .build();
+    }
+
+    static JsonFormat.TypeRegistry getTypeRegistry() {
+        return typeRegistry;
     }
 
     static void marshaller(Class<?> clazz, BuiltinMarshaller marshaller) {
@@ -96,110 +109,111 @@ public class ProtobufAttachmentUtils {
             throw new IllegalStateException(className + " in attachment is not 
supported by protobuf.");
         }
 
-        ByteArrayOutputStream stream = new ByteArrayOutputStream();
-        
ProtobufUtils.serialize(StringValue.newBuilder().setValue(className).build(), 
stream);
-        marshaller.marshal(obj, stream);
-        stream.flush();
-        return 
Any.newBuilder().setValue(ByteString.copyFrom(stream.toByteArray())).build();
+        MapValue.Attachment attachment = MapValue.Attachment.newBuilder()
+            .setType(className)
+            .setData(marshaller.marshal(obj))
+            .build();
+        return Any.pack(attachment);
     }
 
     private static Object unmarshal(Any any) throws 
InvalidProtocolBufferException {
-        InputStream stream = new 
ByteArrayInputStream(any.getValue().toByteArray());
-        String className = ProtobufUtils.deserialize(stream, 
StringValue.class).getValue();
+        MapValue.Attachment attachment = any.unpack(MapValue.Attachment.class);
+        String className = attachment.getType();
         BuiltinMarshaller marshaller = marshallers.get(className);
         if (marshaller == null) {
             throw new IllegalStateException(className + " in attachment is not 
supported by protobuf.");
         }
-        return marshaller.unmarshal(stream);
+        return marshaller.unmarshal(attachment.getData());
     }
 
     private static interface BuiltinMarshaller<T> {
-        void marshal(T obj, OutputStream stream) throws IOException;
+        Any marshal(T obj) throws IOException;
 
-        T unmarshal(InputStream stream) throws InvalidProtocolBufferException;
+        T unmarshal(Any any) throws InvalidProtocolBufferException;
     }
 
     static class StringMarshaller implements BuiltinMarshaller<String> {
         @Override
-        public void marshal(String obj, OutputStream stream) throws 
IOException {
-            
ProtobufUtils.serialize(StringValue.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(String obj) throws IOException {
+            return Any.pack(StringValue.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public String unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
StringValue.class).getValue();
+        public String unmarshal(Any any) throws InvalidProtocolBufferException 
{
+            return any.unpack(StringValue.class).getValue();
         }
     }
 
     static class IntegerMarshaller implements BuiltinMarshaller<Integer> {
         @Override
-        public void marshal(Integer obj, OutputStream stream) throws 
IOException {
-            
ProtobufUtils.serialize(Int32Value.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(Integer obj) throws IOException {
+            return Any.pack(Int32Value.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public Integer unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
Int32Value.class).getValue();
+        public Integer unmarshal(Any any) throws 
InvalidProtocolBufferException {
+            return any.unpack(Int32Value.class).getValue();
         }
+
     }
 
     static class LongMarshaller implements BuiltinMarshaller<Long> {
         @Override
-        public void marshal(Long obj, OutputStream stream) throws IOException {
-            
ProtobufUtils.serialize(Int64Value.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(Long obj) throws IOException {
+            return Any.pack(Int64Value.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public Long unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
Int64Value.class).getValue();
+        public Long unmarshal(Any any) throws InvalidProtocolBufferException {
+            return any.unpack(Int64Value.class).getValue();
         }
     }
 
     static class BooleanMarshaller implements BuiltinMarshaller<Boolean> {
         @Override
-        public void marshal(Boolean obj, OutputStream stream) throws 
IOException {
-            
ProtobufUtils.serialize(BoolValue.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(Boolean obj) throws IOException {
+            return Any.pack(BoolValue.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public Boolean unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
BoolValue.class).getValue();
+        public Boolean unmarshal(Any any) throws 
InvalidProtocolBufferException {
+            return any.unpack(BoolValue.class).getValue();
         }
     }
 
     static class FloatMarshaller implements BuiltinMarshaller<Float> {
         @Override
-        public void marshal(Float obj, OutputStream stream) throws IOException 
{
-            
ProtobufUtils.serialize(FloatValue.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(Float obj) throws IOException {
+            return Any.pack(FloatValue.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public Float unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
FloatValue.class).getValue();
+        public Float unmarshal(Any any) throws InvalidProtocolBufferException {
+            return any.unpack(FloatValue.class).getValue();
         }
     }
 
     static class DoubleMarshaller implements BuiltinMarshaller<Double> {
         @Override
-        public void marshal(Double obj, OutputStream stream) throws 
IOException {
-            
ProtobufUtils.serialize(DoubleValue.newBuilder().setValue(obj).build(), stream);
+        public Any marshal(Double obj) throws IOException {
+            return Any.pack(DoubleValue.newBuilder().setValue(obj).build());
         }
 
         @Override
-        public Double unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
-            return ProtobufUtils.deserialize(stream, 
DoubleValue.class).getValue();
+        public Double unmarshal(Any any) throws InvalidProtocolBufferException 
{
+            return any.unpack(DoubleValue.class).getValue();
         }
     }
 
     static class NullMarshaller implements BuiltinMarshaller<Object> {
 
         @Override
-        public void marshal(Object obj, OutputStream stream) throws 
IOException {
-            ProtobufUtils.serialize(Empty.newBuilder().build(), stream);
+        public Any marshal(Object obj) throws IOException {
+            return Any.pack(Empty.newBuilder().build());
         }
 
         @Override
-        public Object unmarshal(InputStream stream) throws 
InvalidProtocolBufferException {
+        public Object unmarshal(Any any) throws InvalidProtocolBufferException 
{
             return null;
         }
     }
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufUtils.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufUtils.java
index d63d83a..42285ca 100644
--- 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufUtils.java
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufUtils.java
@@ -72,8 +72,29 @@ public class ProtobufUtils {
         return (T) builder.build();
     }
 
+    static <T> T deserializeJson(String json, Class<T> requestClass, 
JsonFormat.TypeRegistry typeRegistry) throws InvalidProtocolBufferException {
+        Builder builder;
+        try {
+            builder = getMessageBuilder(requestClass);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Get google protobuf message 
builder from " + requestClass.getName() + "failed", e);
+        }
+        JsonFormat.parser()
+            .usingTypeRegistry(typeRegistry)
+            .merge(json, builder);
+        return (T) builder.build();
+    }
+
     static String serializeJson(Object value) throws 
InvalidProtocolBufferException {
-        Printer printer = 
JsonFormat.printer().omittingInsignificantWhitespace();
+        Printer printer = JsonFormat.printer()
+            .omittingInsignificantWhitespace();
+        return printer.print((MessageOrBuilder) value);
+    }
+
+    static String serializeJson(Object value, JsonFormat.TypeRegistry 
typeRegistry) throws InvalidProtocolBufferException {
+        Printer printer = JsonFormat.printer()
+            .usingTypeRegistry(typeRegistry)
+            .omittingInsignificantWhitespace();
         return printer.print((MessageOrBuilder) value);
     }
 
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/proto/MapValue.proto
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/proto/MapValue.proto
index 5829f31..290de73 100644
--- 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/proto/MapValue.proto
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/proto/MapValue.proto
@@ -28,3 +28,8 @@ message Map{
   map<string, string> attachments = 1;
   map<string, google.protobuf.Any> attachmentsV2 = 2;
 }
+
+message Attachment{
+  string type = 1;
+  google.protobuf.Any data = 2;
+}

Reply via email to