You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2019/12/26 08:28:01 UTC

[servicecomb-java-chassis] branch master updated: [SCB-1684][HIGHWAY-WEAK]add codec test cases and fix Date/LocalDate c… (#1491)

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

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new e364764  [SCB-1684][HIGHWAY-WEAK]add codec test cases and fix Date/LocalDate c… (#1491)
e364764 is described below

commit e3647646032852c10eb0b5b88c492b87ccc381c1
Author: bao liu <bi...@qq.com>
AuthorDate: Thu Dec 26 16:27:54 2019 +0800

    [SCB-1684][HIGHWAY-WEAK]add codec test cases and fix Date/LocalDate c… (#1491)
    
    * [SCB-1684][HIGHWAY-WEAK]add codec test cases and fix Date/LocalDate codec problem
    
    * add test case for default value
    
    * fix empty array write problem
---
 .../protobuf/definition/OperationProtobuf.java     |   8 +-
 .../codec/protobuf/definition/ProtobufManager.java |   2 +-
 .../internal/converter/TestSchemaMetaCodec.java    | 192 +++++++++++++++++++++
 .../main/java/io/protostuff/ProtobufOutputEx.java  |   2 +-
 .../impl/ints/Fixed32PackedWriteSchemas.java       |  84 +++++----
 .../impl/ints/Int32PackedWriteSchemas.java         |  84 +++++----
 .../impl/ints/SFixed32PackedWriteSchemas.java      |  85 +++++----
 .../impl/ints/SInt32PackedWriteSchemas.java        |  85 +++++----
 .../impl/ints/UInt32PackedWriteSchemas.java        |  86 +++++----
 .../serializer/scalar/Int64WriteSchemas.java       |  15 ++
 .../TestCompatibilityOfImplementations.java        |  68 ++++++++
 .../transport/highway/HighwayCodec.java            |   4 +-
 12 files changed, 537 insertions(+), 178 deletions(-)

diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
index d699e60..927a5f3 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
@@ -38,7 +38,7 @@ public class OperationProtobuf {
 
   private RootSerializer requestSerializer;
 
-  private RootDeserializer<Map> requestDeserializer;
+  private RootDeserializer<Object> requestDeserializer;
 
   private RootSerializer responseSerializer;
 
@@ -50,8 +50,8 @@ public class OperationProtobuf {
 
     ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
     Message requestMessage = mapper.getRequestMessage(operationMeta.getOperationId());
-    requestSerializer = mapper.createRootSerializer(requestMessage, Map.class);
-    requestDeserializer = mapper.createRootDeserializer(requestMessage, Map.class);
+    requestSerializer = mapper.createRootSerializer(requestMessage, Object.class);
+    requestDeserializer = mapper.createRootDeserializer(requestMessage, Object.class);
 
     Message responseMessage = mapper.getResponseMessage(operationMeta.getOperationId());
     responseSerializer = mapper
@@ -70,7 +70,7 @@ public class OperationProtobuf {
     return requestSerializer;
   }
 
-  public RootDeserializer<Map> findRequestDesirializer() {
+  public RootDeserializer<Object> findRequestDesirializer() {
     return requestDeserializer;
   }
 
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
index d67f8d5..86ef301 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
@@ -26,7 +26,7 @@ public final class ProtobufManager {
 
   private static final Object LOCK = new Object();
 
-  public static OperationProtobuf getOrCreateOperation(OperationMeta operationMeta) throws Exception {
+  public static OperationProtobuf getOrCreateOperation(OperationMeta operationMeta) {
     OperationProtobuf operationProtobuf = operationMeta.getExtData(EXT_ID);
     if (operationProtobuf == null) {
       synchronized (LOCK) {
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
new file mode 100644
index 0000000..fd81a99
--- /dev/null
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
@@ -0,0 +1,192 @@
+/*
+ * 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.servicecomb.codec.protobuf.internal.converter;
+
+import java.time.LocalDate;
+import java.time.temporal.ChronoField;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
+import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;
+import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
+import org.apache.servicecomb.core.definition.MicroserviceMeta;
+import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
+import org.apache.servicecomb.foundation.test.scaffolding.model.User;
+import org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.swagger.models.Swagger;
+import mockit.Expectations;
+import mockit.Injectable;
+
+/**
+ * SchemaMetaCodec test cases
+ */
+public class TestSchemaMetaCodec {
+  @Test
+  public void testProtoSchemaOperationUser(@Injectable MicroserviceMeta microserviceMeta) throws Exception {
+    new Expectations() {
+      {
+        microserviceMeta.getMicroserviceName();
+        result = "test";
+        microserviceMeta.getExtData(ProtobufManager.EXT_ID);
+        result = null;
+      }
+    };
+    SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);
+    Swagger swagger = swaggerGenerator.generate();
+    SchemaMeta schemaMeta = new SchemaMeta(microserviceMeta, "ProtoSchema", swagger);
+
+    // response message
+    OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(schemaMeta.getOperations().get("user"));
+    RootSerializer responseSerializer = operationProtobuf.findResponseSerializer(200);
+    User user = new User();
+    user.name = "user";
+    User friend = new User();
+    friend.name = "friend";
+    List<User> friends = new ArrayList<>();
+    friends.add(friend);
+    user.friends = friends;
+    byte[] values = responseSerializer.serialize(user);
+    RootDeserializer<Object> responseDeserializer = operationProtobuf.findResponseDesirialize(200);
+    User decodedUser = (User) responseDeserializer.deserialize(values);
+    Assert.assertEquals(user.name, decodedUser.name);
+    Assert.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);
+
+    user.friends = new ArrayList<>();
+    values = responseSerializer.serialize(user);
+    responseDeserializer = operationProtobuf.findResponseDesirialize(200);
+    decodedUser = (User) responseDeserializer.deserialize(values);
+    Assert.assertEquals(user.name, decodedUser.name);
+    // proto buffer encode and decode empty list to be null
+    Assert.assertEquals(null, decodedUser.friends);
+
+    // request message
+    RootSerializer requestSerializer = operationProtobuf.findRequestSerializer();
+    user.friends = friends;
+    values = requestSerializer.serialize(user);
+    RootDeserializer<Object> requestDeserializer = operationProtobuf.findRequestDesirializer();
+    decodedUser = (User) responseDeserializer.deserialize(values);
+    Assert.assertEquals(user.name, decodedUser.name);
+    Assert.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);
+  }
+
+  @Test
+  @SuppressWarnings({"rawtypes", "unchecked"})
+  public void testProtoSchemaOperationBase(@Injectable MicroserviceMeta microserviceMeta) throws Exception {
+    new Expectations() {
+      {
+        microserviceMeta.getMicroserviceName();
+        result = "test";
+        microserviceMeta.getExtData(ProtobufManager.EXT_ID);
+        result = null;
+      }
+    };
+    SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);
+    Swagger swagger = swaggerGenerator.generate();
+    SchemaMeta schemaMeta = new SchemaMeta(microserviceMeta, "ProtoSchema", swagger);
+
+    // response message
+    // TODO : WEAK fix this line "java.lang.NoClassDefFoundError: org/apache/servicecomb/foundation/common/utils/bean/Getter"
+    OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(schemaMeta.getOperations().get("base"));
+    RootSerializer responseSerializer = operationProtobuf.findResponseSerializer(200);
+    byte[] values = responseSerializer.serialize(30); // here do not need wrapper ?
+    RootDeserializer<Object> responseDeserializer = operationProtobuf.findResponseDesirialize(200);
+    Object decodedValue = responseDeserializer.deserialize(values);
+    Assert.assertEquals(30, ((PropertyWrapper) decodedValue).getValue()); // here need wrapper ?
+
+    // request message
+    RootSerializer requestSerializer = operationProtobuf.findRequestSerializer();
+    boolean boolValue = true;
+    int iValue = 20;
+    long lValue = 30L;
+    float fValue = 40f;
+    double dValue = 50D;
+    String sValue = "hello";
+    int[] iArray = new int[] {60, 70};
+    Color color = Color.BLUE;
+    LocalDate localDate = LocalDate.of(2019, 10, 1);
+    Date date = new Date();
+    Empty empty = new Empty();
+    Map<String, Object> args = new HashMap<>();
+    args.put("boolValue", boolValue);
+    args.put("iValue", iValue);
+    args.put("lValue", lValue);
+    args.put("fValue", fValue);
+    args.put("dValue", dValue);
+    args.put("sValue", sValue);
+    args.put("iArray", iArray);
+    args.put("color", color);
+    args.put("localDate", localDate);
+    args.put("date", date);
+    args.put("empty", empty);
+    values = requestSerializer.serialize(args);
+    RootDeserializer<Object> requestDeserializer = operationProtobuf.findRequestDesirializer();
+    Object obj = requestDeserializer.deserialize(values);
+    Map<String, Object> decodedArgs = (Map<String, Object>) obj;
+    Assert.assertEquals(boolValue, decodedArgs.get("boolValue")); // default value not serialized
+    Assert.assertEquals(iValue, decodedArgs.get("iValue"));
+    Assert.assertEquals(lValue, decodedArgs.get("lValue"));
+    Assert.assertEquals(fValue, decodedArgs.get("fValue"));
+    Assert.assertEquals(dValue, decodedArgs.get("dValue"));
+    // TODO: WEAK following need take care of
+    Assert.assertEquals(iArray[0], (int) ((List<Integer>) decodedArgs.get("iArray")).get(0)); // handling list
+    Assert.assertEquals(iArray[1], (int) ((List<Integer>) decodedArgs.get("iArray")).get(1));
+    Assert.assertEquals(2, ((List<Integer>) decodedArgs.get("iArray")).size());
+    Assert.assertEquals(color.ordinal(), decodedArgs.get("color")); // handling enum
+    Assert.assertEquals(localDate.getLong(ChronoField.EPOCH_DAY), decodedArgs.get("localDate")); // handling LocalDate
+    Assert.assertEquals(date.getTime(), decodedArgs.get("date")); // handling Date
+    Assert.assertTrue(decodedArgs.get("empty") instanceof Map); // handling object, should by Empty.class
+
+    // default value testing
+    args.put("boolValue", false);
+    args.put("iValue", 0);
+    args.put("lValue", 0L);
+    args.put("fValue", 0F);
+    args.put("dValue", 0D);
+    args.put("sValue", null);
+    args.put("iArray", new int[0]);
+    args.put("color", null);
+    args.put("localDate", null);
+    args.put("date", null);
+    args.put("empty", null);
+    values = requestSerializer.serialize(args);
+    obj = requestDeserializer.deserialize(values);
+    decodedArgs = (Map<String, Object>) obj;
+    Assert.assertEquals(null, decodedArgs.get("boolValue"));
+    Assert.assertEquals(null, decodedArgs.get("iValue"));
+    Assert.assertEquals(null, decodedArgs.get("lValue"));
+    Assert.assertEquals(null, decodedArgs.get("fValue"));
+    Assert.assertEquals(null, decodedArgs.get("dValue"));
+    Assert.assertEquals(null, decodedArgs.get("iArray"));
+    Assert.assertEquals(null, decodedArgs.get("color"));
+    Assert.assertEquals(null, decodedArgs.get("localDate"));
+    Assert.assertEquals(null, decodedArgs.get("date"));
+    Assert.assertEquals(null, decodedArgs.get("empty"));
+  }
+}
diff --git a/foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java b/foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java
index 7a48d98..41be1ed 100644
--- a/foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java
+++ b/foundations/foundation-protobuf/src/main/java/io/protostuff/ProtobufOutputEx.java
@@ -839,7 +839,7 @@ public final class ProtobufOutputEx extends WriteSession implements OutputEx {
   @Override
   public final void writeScalarBool(int tag, int tagSize, boolean value) {
     if (value) {
-      writeBool(tag, tagSize, true);
+      writeBool(tag, tagSize, value);
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32PackedWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32PackedWriteSchemas.java
index bf1aa2b..9a5c995 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32PackedWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Fixed32PackedWriteSchemas.java
@@ -29,49 +29,65 @@ public class Fixed32PackedWriteSchemas {
     public Fixed32PackedWriters(Field protoField) {
       super(protoField);
 
-      primitiveArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (int element : array) {
+      primitiveArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (int element : array) {
+            output.writePackedFixed32(element);
+          }
+        });
+      };
+
+      arrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (Integer element : array) {
+            if (element != null) {
               output.writePackedFixed32(element);
+              continue;
             }
-          });
 
-      arrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (Integer element : array) {
-              if (element != null) {
-                output.writePackedFixed32(element);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      collectionWriter = (o, value) -> {
+        if (value.isEmpty()) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, collection) -> {
+          for (Integer element : collection) {
+            if (element != null) {
+              output.writePackedFixed32(element);
+              continue;
             }
-          });
 
-      collectionWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, collection) -> {
-            for (Integer element : collection) {
-              if (element != null) {
-                output.writePackedFixed32(element);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      stringArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (String element : array) {
+            if (element != null) {
+              int parsedValue = Integer.parseInt(element, 10);
+              output.writePackedFixed32(parsedValue);
+              continue;
             }
-          });
 
-      stringArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (String element : array) {
-              if (element != null) {
-                int parsedValue = Integer.parseInt(element, 10);
-                output.writePackedFixed32(parsedValue);
-                continue;
-              }
-
-              ProtoUtils.throwNotSupportNullElement(protoField);
-            }
-          });
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32PackedWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32PackedWriteSchemas.java
index 733ee60..5f8b856 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32PackedWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/Int32PackedWriteSchemas.java
@@ -29,49 +29,65 @@ public class Int32PackedWriteSchemas {
     public Int32PackedWriters(Field protoField) {
       super(protoField);
 
-      primitiveArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (int element : array) {
+      primitiveArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (int element : array) {
+            output.writePackedInt32(element);
+          }
+        });
+      };
+
+      arrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (Integer element : array) {
+            if (element != null) {
               output.writePackedInt32(element);
+              continue;
             }
-          });
 
-      arrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (Integer element : array) {
-              if (element != null) {
-                output.writePackedInt32(element);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      collectionWriter = (o, value) -> {
+        if (value.isEmpty()) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, collection) -> {
+          for (Integer element : collection) {
+            if (element != null) {
+              output.writePackedInt32(element);
+              continue;
             }
-          });
 
-      collectionWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, collection) -> {
-            for (Integer element : collection) {
-              if (element != null) {
-                output.writePackedInt32(element);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      stringArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (String element : array) {
+            if (element != null) {
+              int parsedValue = Integer.parseInt(element, 10);
+              output.writePackedInt32(parsedValue);
+              continue;
             }
-          });
 
-      stringArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (String element : array) {
-              if (element != null) {
-                int parsedValue = Integer.parseInt(element, 10);
-                output.writePackedInt32(parsedValue);
-                continue;
-              }
-
-              ProtoUtils.throwNotSupportNullElement(protoField);
-            }
-          });
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32PackedWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32PackedWriteSchemas.java
index 5c3fcad..661a99d 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32PackedWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SFixed32PackedWriteSchemas.java
@@ -29,49 +29,66 @@ public class SFixed32PackedWriteSchemas {
     public SFixed32PackedWriters(Field protoField) {
       super(protoField);
 
-      primitiveArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (int element : array) {
+      primitiveArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (int element : array) {
+            output.writePackedSFixed32(element);
+          }
+        });
+      };
+
+      arrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (Integer element : array) {
+            if (element != null) {
               output.writePackedSFixed32(element);
+              continue;
             }
-          });
-
-      arrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (Integer element : array) {
-              if (element != null) {
-                output.writePackedSFixed32(element);
-                continue;
-              }
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
-            }
-          });
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
       collectionWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, collection) -> {
-            for (Integer element : collection) {
-              if (element != null) {
-                output.writePackedSFixed32(element);
-                continue;
-              }
-
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      {
+        if (value.isEmpty()) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, collection) -> {
+          for (Integer element : collection) {
+            if (element != null) {
+              output.writePackedSFixed32(element);
+              continue;
             }
-          });
 
-      stringArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (String element : array) {
-              if (element != null) {
-                int parsedValue = Integer.parseInt(element, 10);
-                output.writePackedSFixed32(parsedValue);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      stringArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (String element : array) {
+            if (element != null) {
+              int parsedValue = Integer.parseInt(element, 10);
+              output.writePackedSFixed32(parsedValue);
+              continue;
             }
-          });
+
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32PackedWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32PackedWriteSchemas.java
index 05446ee..c1d4482 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32PackedWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/SInt32PackedWriteSchemas.java
@@ -29,49 +29,66 @@ public class SInt32PackedWriteSchemas {
     public SInt32PackedWriters(Field protoField) {
       super(protoField);
 
-      primitiveArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (int element : array) {
+      primitiveArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (int element : array) {
+            output.writePackedSInt32(element);
+          }
+        });
+      };
+
+      arrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (Integer element : array) {
+            if (element != null) {
               output.writePackedSInt32(element);
+              continue;
             }
-          });
-
-      arrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (Integer element : array) {
-              if (element != null) {
-                output.writePackedSInt32(element);
-                continue;
-              }
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
-            }
-          });
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
       collectionWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, collection) -> {
-            for (Integer element : collection) {
-              if (element != null) {
-                output.writePackedSInt32(element);
-                continue;
-              }
-
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      {
+        if (value.isEmpty()) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, collection) -> {
+          for (Integer element : collection) {
+            if (element != null) {
+              output.writePackedSInt32(element);
+              continue;
             }
-          });
 
-      stringArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (String element : array) {
-              if (element != null) {
-                int parsedValue = Integer.parseInt(element, 10);
-                output.writePackedSInt32(parsedValue);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      stringArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (String element : array) {
+            if (element != null) {
+              int parsedValue = Integer.parseInt(element, 10);
+              output.writePackedSInt32(parsedValue);
+              continue;
             }
-          });
+
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32PackedWriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32PackedWriteSchemas.java
index fc948a9..30e9dd4 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32PackedWriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/repeated/impl/ints/UInt32PackedWriteSchemas.java
@@ -29,49 +29,67 @@ public class UInt32PackedWriteSchemas {
     public UInt32PackedWriters(Field protoField) {
       super(protoField);
 
-      primitiveArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (int element : array) {
-              output.writePackedUInt32(element);
-            }
-          });
+      primitiveArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (int element : array) {
+            output.writePackedUInt32(element);
+          }
+        });
+      };
 
       arrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (Integer element : array) {
-              if (element != null) {
-                output.writePackedUInt32(element);
-                continue;
-              }
-
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (Integer element : array) {
+            if (element != null) {
+              output.writePackedUInt32(element);
+              continue;
             }
-          });
 
-      collectionWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, collection) -> {
-            for (Integer element : collection) {
-              if (element != null) {
-                output.writePackedUInt32(element);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      collectionWriter = (o, value) ->
+      {
+        if (value.isEmpty()) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, collection) -> {
+          for (Integer element : collection) {
+            if (element != null) {
+              output.writePackedUInt32(element);
+              continue;
             }
-          });
 
-      stringArrayWriter = (o, value) ->
-          o.writeObject(tag, tagSize, value, (output, array) -> {
-            for (String element : array) {
-              if (element != null) {
-                int parsedValue = Integer.parseInt(element, 10);
-                output.writePackedUInt32(parsedValue);
-                continue;
-              }
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
 
-              ProtoUtils.throwNotSupportNullElement(protoField);
+      stringArrayWriter = (o, value) -> {
+        if (value.length == 0) {
+          return;
+        }
+        o.writeObject(tag, tagSize, value, (output, array) -> {
+          for (String element : array) {
+            if (element != null) {
+              int parsedValue = Integer.parseInt(element, 10);
+              output.writePackedUInt32(parsedValue);
+              continue;
             }
-          });
+
+            ProtoUtils.throwNotSupportNullElement(protoField);
+          }
+        });
+      };
     }
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int64WriteSchemas.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int64WriteSchemas.java
index c442d55..71edff8 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int64WriteSchemas.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/scalar/Int64WriteSchemas.java
@@ -17,6 +17,9 @@
 package org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.scalar;
 
 import java.io.IOException;
+import java.time.LocalDate;
+import java.time.temporal.ChronoField;
+import java.util.Date;
 
 import org.apache.servicecomb.foundation.common.utils.bean.Getter;
 import org.apache.servicecomb.foundation.common.utils.bean.LongGetter;
@@ -67,6 +70,18 @@ public class Int64WriteSchemas {
         return;
       }
 
+      if (value instanceof Date) {
+        long parsedValue = ((Date) value).getTime();
+        output.writeScalarInt64(tag, tagSize, parsedValue);
+        return;
+      }
+
+      if (value instanceof LocalDate) {
+        long parsedValue = ((LocalDate) value).getLong(ChronoField.EPOCH_DAY);
+        output.writeScalarInt64(tag, tagSize, parsedValue);
+        return;
+      }
+
       ProtoUtils.throwNotSupportWrite(protoField, value);
     }
   }
diff --git a/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/compatibility/TestCompatibilityOfImplementations.java b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/compatibility/TestCompatibilityOfImplementations.java
new file mode 100644
index 0000000..e5fb652
--- /dev/null
+++ b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/compatibility/TestCompatibilityOfImplementations.java
@@ -0,0 +1,68 @@
+/*
+ * 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.servicecomb.foundation.protobuf.compatibility;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.protobuf.internal.model.ProtobufRoot;
+import org.apache.servicecomb.foundation.protobuf.internal.model.Root;
+import org.apache.servicecomb.foundation.protobuf.performance.ProtubufCodecEngine;
+import org.apache.servicecomb.foundation.protobuf.performance.engine.Protobuf;
+import org.apache.servicecomb.foundation.protobuf.performance.engine.ScbWeak;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCompatibilityOfImplementations {
+  static ProtubufCodecEngine scbWeak = new ScbWeak();
+
+  static ProtubufCodecEngine protobuf = new Protobuf();
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testEmptyCollection() throws Exception {
+    ProtobufRoot.Root.Builder builder = ProtobufRoot.Root.newBuilder();
+    byte[] values = protobuf.serialize(builder);
+    Assert.assertEquals(values.length, 0);
+    ProtobufRoot.Root.Builder o = (ProtobufRoot.Root.Builder) protobuf.deserialize(values);
+    Assert.assertTrue(o.getFixed32SNotPackedList().isEmpty());
+
+    builder = ProtobufRoot.Root.newBuilder().addFixed32SNotPacked(30);
+    values = protobuf.serialize(builder);
+    Assert.assertArrayEquals(new byte[] {(byte) -123, (byte) 6, (byte) 30, (byte) 0, (byte) 0, (byte) 0}, values);
+    o = (ProtobufRoot.Root.Builder) protobuf.deserialize(values);
+    Assert.assertEquals(30, (int) o.getFixed32SNotPackedList().get(0));
+
+    Root root = new Root();
+    root.setFixed32sNotPacked(new ArrayList<>());
+    values = scbWeak.serialize(root);
+    Assert.assertEquals(values.length, 0);
+    Map<String, Object> newRootMap = (Map<String, Object>) scbWeak.deserialize(values);
+    Assert.assertEquals(null,
+        newRootMap.get("fixed32sNotPacked")); // This is different , because depends on default model initializer
+
+    List<Integer> iValues = new ArrayList<>();
+    iValues.add(30);
+    root.setFixed32sNotPacked(iValues);
+    values = scbWeak.serialize(root);
+    Assert.assertArrayEquals(new byte[] {(byte) -123, (byte) 6, (byte) 30, (byte) 0, (byte) 0, (byte) 0}, values);
+    newRootMap = (Map<String, Object>) scbWeak.deserialize(values);
+    Assert.assertEquals(30, (int) ((List<Integer>) newRootMap.get("fixed32sNotPacked")).get(0));
+  }
+}
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
index 71b8505..cd7c548 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
@@ -55,9 +55,9 @@ public final class HighwayCodec {
   @SuppressWarnings("rawtypes")
   public static void decodeRequest(Invocation invocation, RequestHeader header, OperationProtobuf operationProtobuf,
       Buffer bodyBuffer) throws Exception {
-    RootDeserializer<Map> schema = operationProtobuf.findRequestDesirializer();
+    RootDeserializer<Object> schema = operationProtobuf.findRequestDesirializer();
     // TODO: WEAK read array or map
-    Object[] args = schema.deserialize(bodyBuffer.getBytes()).values().toArray();
+    Object[] args = (Object[])schema.deserialize(bodyBuffer.getBytes());
 
     invocation.setSwaggerArguments(args);
     invocation.mergeContext(header.getContext());