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

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


The following commit(s) were added to refs/heads/3.2.0 by this push:
     new 6da9df5   [Dubbo-267] Fix protobuf type lose field when deepCopy 
inJvmInvoker Class. (#268)
6da9df5 is described below

commit 6da9df5ce4dedaed0219e29f6cdeaf6318491c10
Author: MaruHibiki <1807180...@qq.com>
AuthorDate: Thu Dec 28 13:33:07 2023 +0800

     [Dubbo-267] Fix protobuf type lose field when deepCopy inJvmInvoker Class. 
(#268)
---
 .../dubbo-serialization-protobuf/pom.xml           |  6 ++
 .../support/ProtobufParamDeepCopyUtil.java         | 66 +++++++++++++++++++
 ...ache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil |  1 +
 .../support/ProtobufParamDeepCopyUtilTest.java     | 74 ++++++++++++++++++++++
 4 files changed, 147 insertions(+)

diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/pom.xml 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/pom.xml
index 24e01b4..63961d5 100644
--- a/dubbo-serialization-extensions/dubbo-serialization-protobuf/pom.xml
+++ b/dubbo-serialization-extensions/dubbo-serialization-protobuf/pom.xml
@@ -46,6 +46,12 @@ limitations under the License.
             <version>${dubbo.version}</version>
             <optional>true</optional>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo</artifactId>
+            <version>${dubbo.version}</version>
+            <optional>true</optional>
+        </dependency>
         <dependency>
             <groupId>com.google.protobuf</groupId>
             <artifactId>protobuf-java</artifactId>
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtil.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtil.java
new file mode 100644
index 0000000..b3a5fdf
--- /dev/null
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtil.java
@@ -0,0 +1,66 @@
+/*
+ * 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.dubbo.common.serialize.protobuf.support;
+
+import static 
org.apache.dubbo.common.constants.LoggerCodeConstants.PROTOCOL_ERROR_DESERIALIZE;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.rpc.protocol.injvm.DefaultParamDeepCopyUtil;
+import org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil;
+
+public class ProtobufParamDeepCopyUtil implements ParamDeepCopyUtil {
+    private static final ErrorTypeAwareLogger logger = 
LoggerFactory.getErrorTypeAwareLogger(DefaultParamDeepCopyUtil.class);
+
+    private ParamDeepCopyUtil delegate;
+
+    public ProtobufParamDeepCopyUtil(ParamDeepCopyUtil delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public <T> T copy(URL url, Object src, Class<T> targetClass) {
+        boolean isProtobufTypeSupported = 
ProtobufUtils.isSupported(targetClass);
+        if(isProtobufTypeSupported){
+            try (ByteArrayOutputStream outputStream = new 
ByteArrayOutputStream()) {
+                ProtobufUtils.serialize(src, outputStream);
+
+                try (ByteArrayInputStream inputStream = new 
ByteArrayInputStream(outputStream.toByteArray())) {
+                    T deserialize = ProtobufUtils.deserialize(inputStream, 
targetClass);
+                    return deserialize;
+                } catch (IOException e) {
+                    logger.error(PROTOCOL_ERROR_DESERIALIZE, "", "", "Unable 
to deep copy parameter to target class.", e);
+                }
+
+            } catch (Throwable e) {
+                logger.error(PROTOCOL_ERROR_DESERIALIZE, "", "", "Unable to 
deep copy parameter to target class.", e);
+            }
+
+            if (src.getClass().equals(targetClass)) {
+                return (T) src;
+            } else {
+                return null;
+            }
+        }
+        return delegate.copy(url, src, targetClass);
+    }
+}
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil
new file mode 100644
index 0000000..a3cb3e6
--- /dev/null
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil
@@ -0,0 +1 @@
+protobufDeepUtil=org.apache.dubbo.common.serialize.protobuf.support.ProtobufParamDeepCopyUtil
diff --git 
a/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtilTest.java
 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtilTest.java
new file mode 100644
index 0000000..1c4db2e
--- /dev/null
+++ 
b/dubbo-serialization-extensions/dubbo-serialization-protobuf/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufParamDeepCopyUtilTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.dubbo.common.serialize.protobuf.support;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.serialize.protobuf.support.model.GooglePB;
+import org.apache.dubbo.rpc.protocol.injvm.DefaultParamDeepCopyUtil;
+import org.apache.dubbo.rpc.protocol.injvm.ParamDeepCopyUtil;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+
+public class ProtobufParamDeepCopyUtilTest {
+    private ParamDeepCopyUtil paramDeepCopyUtil;
+
+    @BeforeEach
+    public void setUp() {
+        URL url = mockURL();
+        this.paramDeepCopyUtil = 
url.getOrDefaultFrameworkModel().getExtensionLoader(ParamDeepCopyUtil.class)
+            
.getExtension(url.getParameter(CommonConstants.INJVM_COPY_UTIL_KEY, 
DefaultParamDeepCopyUtil.NAME));
+    }
+
+    @Test
+    public void testProtobufDeepCopy() throws InvalidProtocolBufferException {
+        ProtobufUtils.marshaller(GooglePB.PBRequestType.getDefaultInstance());
+        GooglePB.PhoneNumber phoneNumber = GooglePB.PhoneNumber.newBuilder()
+            .setNumber("134123781291").build();
+        List<GooglePB.PhoneNumber> phoneNumberList = new ArrayList<>();
+        phoneNumberList.add(phoneNumber);
+        Map<String, GooglePB.PhoneNumber> phoneNumberMap = new HashMap<>();
+        phoneNumberMap.put("someUser", phoneNumber);
+        GooglePB.PBRequestType request = GooglePB.PBRequestType.newBuilder()
+            .setAge(15).setCash(10).setMoney(16.0).setNum(100L)
+            
.addAllPhone(phoneNumberList).putAllDoubleMap(phoneNumberMap).build();
+        GooglePB.PBRequestType copyResult = paramDeepCopyUtil.copy(mockURL(), 
request, GooglePB.PBRequestType.class);
+        String jsonString = ProtobufUtils.serializeJson(request);
+        String jsonString2 = ProtobufUtils.serializeJson(copyResult);
+        assertEquals(jsonString, jsonString2);
+        assertNotEquals(System.identityHashCode(request), 
System.identityHashCode(copyResult));
+        List<GooglePB.PhoneNumber> copyPhoneList = copyResult.getPhoneList();
+        Map<String, GooglePB.PhoneNumber> copyDoubleMap = 
copyResult.getDoubleMap();
+        assertNotEquals(System.identityHashCode(phoneNumberList.get(0)), 
System.identityHashCode(copyPhoneList.get(0)));
+        
assertNotEquals(System.identityHashCode(phoneNumberMap.get("someUser")), 
System.identityHashCode(copyDoubleMap.get("someUser")));
+    }
+
+    URL mockURL() {
+        URL url = new URL("dubbo", "localhost", 20880);
+        return url;
+    }
+}

Reply via email to