[ 
https://issues.apache.org/jira/browse/SCB-903?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16611455#comment-16611455
 ] 

ASF GitHub Bot commented on SCB-903:
------------------------------------

liubao68 closed pull request #901: [SCB-903]Add a feature to 
serialize/deserialize using Object to avoid information lose
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/901
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index 18e5bcfc2..29697445a 100644
--- 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++ 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -38,7 +38,9 @@
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.exc.MismatchedInputException;
+import com.fasterxml.jackson.databind.type.SimpleType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
+import com.netflix.config.DynamicPropertyFactory;
 
 import io.swagger.models.parameters.Parameter;
 import io.vertx.core.buffer.Buffer;
@@ -49,6 +51,12 @@
 
   public static final String PARAMTYPE = "body";
 
+  private static final JavaType OBJECT_TYPE = 
SimpleType.constructUnsafe(Object.class);
+
+  // This configuration is used for temporary use only. Do not use it if you 
are sure how it works. And may be deleted in future.
+  private static boolean decodeAsObject = DynamicPropertyFactory.getInstance()
+      .getBooleanProperty("servicecomb.rest.parameter.decodeAsObject", 
false).get();
+
   public static class BodyProcessor implements ParamValueProcessor {
     protected JavaType targetType;
 
@@ -88,6 +96,10 @@ public Object getValue(HttpServletRequest request) throws 
Exception {
       }
 
       try {
+        if (decodeAsObject) {
+          return RestObjectMapperFactory.getRestObjectMapper()
+              .readValue(inputStream, OBJECT_TYPE);
+        }
         return RestObjectMapperFactory.getRestObjectMapper()
             .readValue(inputStream, targetType);
       } catch (MismatchedInputException e) {
diff --git 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
index 124e178ab..713711ed8 100644
--- 
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
+++ 
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/QueryProcessorCreator.java
@@ -35,8 +35,12 @@
   public static final String PARAMTYPE = "query";
 
   public static class QueryProcessor extends AbstractParamProcessor {
+    // This configuration is used for temporary use only. Do not use it if you 
are sure how it works. And may be deleted in future.
     private boolean emptyAsNull = DynamicPropertyFactory.getInstance()
         .getBooleanProperty("servicecomb.rest.parameter.query.emptyAsNull", 
false).get();
+    // This configuration is used for temporary use only. Do not use it if you 
are sure how it works. And may be deleted in future.
+    private boolean ignoreDefaultValue = DynamicPropertyFactory.getInstance()
+        
.getBooleanProperty("servicecomb.rest.parameter.query.ignoreDefaultValue", 
false).get();
 
     public QueryProcessor(String paramPath, JavaType targetType, Object 
defaultValue) {
       super(paramPath, targetType, defaultValue);
@@ -57,7 +61,7 @@ public Object getValue(HttpServletRequest request) throws 
Exception {
         }
         if (value == null) {
           Object defaultValue = getDefaultValue();
-          if (defaultValue != null) {
+          if (!ignoreDefaultValue && defaultValue != null) {
             value = defaultValue;
           }
         }
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java 
b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index ceb5f928e..43dc36baf 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -185,6 +185,9 @@ public String getOperationName() {
   }
 
   public String getConfigTransportName() {
+    if (operationMeta.getTransport() != null) {
+      return operationMeta.getTransport();
+    }
     return referenceConfig.getTransport();
   }
 
diff --git 
a/core/src/main/java/org/apache/servicecomb/core/definition/OperationMeta.java 
b/core/src/main/java/org/apache/servicecomb/core/definition/OperationMeta.java
index a1882751c..4e3471611 100644
--- 
a/core/src/main/java/org/apache/servicecomb/core/definition/OperationMeta.java
+++ 
b/core/src/main/java/org/apache/servicecomb/core/definition/OperationMeta.java
@@ -27,6 +27,8 @@
 import org.apache.servicecomb.swagger.invocation.response.ResponseMeta;
 import org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;
 
+import com.netflix.config.DynamicPropertyFactory;
+
 import io.swagger.models.Operation;
 
 public class OperationMeta {
@@ -56,6 +58,8 @@
   // 为避免每个地方都做复杂的层次管理,直接在这里保存扩展数据
   private Map<String, Object> extData = new ConcurrentHashMap<>();
 
+  private String transport = null;
+
   public void init(SchemaMeta schemaMeta, Method method, String operationPath, 
String httpMethod,
       Operation swaggerOperation) {
     this.schemaMeta = schemaMeta;
@@ -71,6 +75,14 @@ public void init(SchemaMeta schemaMeta, Method method, 
String operationPath, Str
     responsesMeta.init(schemaMeta.getSwaggerToClassGenerator(),
         swaggerOperation,
         method.getGenericReturnType());
+
+    transport = DynamicPropertyFactory.getInstance()
+        .getStringProperty("servicecomb.operation."
+            + microserviceQualifiedName + ".transport", null).get();
+  }
+
+  public String getTransport() {
+    return transport;
   }
 
   public String getHttpMethod() {
diff --git a/integration-tests/it-common/src/main/resources/microservice.yaml 
b/integration-tests/it-common/src/main/resources/microservice.yaml
index d4a11c79c..43df9e297 100644
--- a/integration-tests/it-common/src/main/resources/microservice.yaml
+++ b/integration-tests/it-common/src/main/resources/microservice.yaml
@@ -21,10 +21,15 @@ APPLICATION_ID: integration-test
 service_description:
   name: $invalid-name-must-be-overridden
   version: 1.0.0
+  environment: development
 servicecomb:
   service:
     registry:
       address: http://127.0.0.1:30100
+      instance:
+        healthCheck:
+          interval: 5
+          times: 3
   request:
     # 10 minute
     timeout: 600000
diff --git 
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
index a3b770471..8177191c3 100644
--- 
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
+++ 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
@@ -22,6 +22,7 @@
 import org.apache.servicecomb.it.junit.ITJUnitUtils;
 import org.apache.servicecomb.it.testcase.TestChangeTransport;
 import org.apache.servicecomb.it.testcase.TestDataTypePrimitive;
+import org.apache.servicecomb.it.testcase.TestDefaultJsonValueJaxrsSchema;
 import org.apache.servicecomb.it.testcase.TestDefaultValue;
 import org.apache.servicecomb.it.testcase.TestIgnoreMethod;
 import org.apache.servicecomb.it.testcase.TestParamCodec;
@@ -100,6 +101,7 @@ protected static void run() throws Throwable {
 
   private static void testStandalone() throws Throwable {
     deploys.getBaseProducer().ensureReady();
+
     ITJUnitUtils.addParent("standalone");
 
     ITJUnitUtils.runWithHighwayAndRest(TestChangeTransport.class);
@@ -113,6 +115,7 @@ private static void testStandalone() throws Throwable {
 
     ITJUnitUtils.runWithHighwayAndRest(TestParamCodec.class);
     ITJUnitUtils.run(TestParamCodecEdge.class);
+    ITJUnitUtils.run(TestDefaultJsonValueJaxrsSchema.class);
 
     ITJUnitUtils.runWithRest(TestRestServerConfig.class);
 
diff --git 
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultJsonValueJaxrsSchema.java
 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultJsonValueJaxrsSchema.java
new file mode 100644
index 000000000..07545320e
--- /dev/null
+++ 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestDefaultJsonValueJaxrsSchema.java
@@ -0,0 +1,102 @@
+/*
+ * 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.it.testcase;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.it.extend.engine.GateRestTemplate;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.web.client.RestTemplate;
+
+public class TestDefaultJsonValueJaxrsSchema {
+  static RestTemplate client = 
GateRestTemplate.createEdgeRestTemplate("defaultJsonValueJaxrs");
+
+  @BeforeClass
+  public static void classSetup() {
+  }
+
+  @Test
+  public void invokeFromEdgeWithQuery() {
+    String result = client.getForObject("/queryInput?size=3", String.class);
+    Assert.assertEquals(result, "expected:3:3");
+
+    result = client.getForObject("/queryInput", String.class);
+    Assert.assertEquals(result, "expected:0:null");
+
+    result = client.getForObject("/queryInput?size=", String.class);
+    Assert.assertEquals(result, "expected:0:null");
+  }
+
+  @Test
+  public void invokeFromEdgeWithRawJson() {
+    HttpHeaders headers = new HttpHeaders();
+    headers.setContentType(MediaType.APPLICATION_JSON);
+    Map<String, Object> body = new HashMap<>();
+    body.put("type", 100);
+    HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body, headers);
+    Map result =
+        client.postForObject("/jsonInput", entity, Map.class);
+    Assert.assertEquals(result.get("type"), 100);
+    Assert.assertEquals(result.get("message"), "expected:30:0");
+
+    body = new HashMap<>();
+    body.put("type", 100);
+    body.put("defaultValue", null);
+    entity = new HttpEntity<>(body, headers);
+    result =
+        client.postForObject("/jsonInput", entity, Map.class);
+    Assert.assertEquals(result.get("type"), 100);
+    Assert.assertEquals(result.get("message"), "expected:null:0");
+
+    body = new HashMap<>();
+    body.put("type", 200);
+    body.put("defaultValue", -1);
+    entity = new HttpEntity<>(body, headers);
+    result =
+        client.postForObject("/jsonInput", entity, Map.class);
+    Assert.assertEquals(result.get("type"), 200);
+    Assert.assertEquals(result.get("message"), "expected:-1:0");
+
+    body = new HashMap<>();
+    body.put("type", 200);
+    body.put("defaultValue", -1);
+    body.put("items", null);
+    entity = new HttpEntity<>(body, headers);
+    result =
+        client.postForObject("/jsonInput", entity, Map.class);
+    Assert.assertEquals(result.get("type"), 200);
+    Assert.assertEquals(result.get("message"), "expected:-1:null");
+
+    body = new HashMap<>();
+    body.put("type", 200);
+    body.put("defaultValue", -1);
+    body.put("items", new ArrayList<String>());
+    entity = new HttpEntity<>(body, headers);
+    result =
+        client.postForObject("/jsonInput", entity, Map.class);
+    Assert.assertEquals(result.get("type"), 200);
+    Assert.assertEquals(result.get("message"), "expected:-1:0");
+  }
+}
diff --git a/integration-tests/it-edge/src/main/resources/microservice.yaml 
b/integration-tests/it-edge/src/main/resources/microservice.yaml
index b1ca0db82..88703c043 100644
--- a/integration-tests/it-edge/src/main/resources/microservice.yaml
+++ b/integration-tests/it-edge/src/main/resources/microservice.yaml
@@ -25,6 +25,19 @@ servicecomb:
         default: loadbalance
         service:
           it-auth: loadbalance
+  rest:
+    parameter:
+      decodeAsObject: true
+      query:
+        ignoreDefaultValue: true
+        emptyAsNull: true
+  operation:
+    it-producer:
+      defaultJsonValueJaxrs:
+        jsonInput:
+          transport: rest
+        queryInput:
+          transport: rest
   http:
     dispatcher:
       edge:
diff --git 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueJaxrsSchema.java
 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueJaxrsSchema.java
new file mode 100644
index 000000000..65308533d
--- /dev/null
+++ 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueJaxrsSchema.java
@@ -0,0 +1,47 @@
+/*
+ * 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.it.schema;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "defaultJsonValueJaxrs")
+@Path("/v1/defaultJsonValueJaxrs")
+public class DefaultJsonValueJaxrsSchema {
+  @Path("jsonInput")
+  @POST
+  public DefaultJsonValueResponse jsonInput(DefaultJsonValueRequest request) {
+    DefaultJsonValueResponse response = new DefaultJsonValueResponse();
+    response.setType(request.getType());
+    StringBuilder sb = new StringBuilder();
+    sb.append(request.getDefaultValue());
+    response.setMessage("expected:" + sb.toString() + ":" + 
(request.getItems() == null ? null
+        : request.getItems().size()));
+    return response;
+  }
+
+  @Path("queryInput")
+  @GET
+  public String queryInput(HttpServletRequest request, @QueryParam("size") int 
size) {
+    return "expected:" + size + ":" + request.getParameter("size");
+  }
+}
diff --git 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueRequest.java
 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueRequest.java
new file mode 100644
index 000000000..3410eac36
--- /dev/null
+++ 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueRequest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.it.schema;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultJsonValueRequest {
+  private int type;
+
+  private Integer defaultValue = 30;
+
+  private List<String> items = new ArrayList<>();
+
+  public int getType() {
+    return type;
+  }
+
+  public void setType(int type) {
+    this.type = type;
+  }
+
+  public Integer getDefaultValue() {
+    return defaultValue;
+  }
+
+  public void setDefaultValue(Integer defaultValue) {
+    this.defaultValue = defaultValue;
+  }
+
+  public List<String> getItems() {
+    return items;
+  }
+
+  public void setItems(List<String> items) {
+    this.items = items;
+  }
+}
diff --git 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueResponse.java
 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueResponse.java
new file mode 100644
index 000000000..69079eab1
--- /dev/null
+++ 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/DefaultJsonValueResponse.java
@@ -0,0 +1,39 @@
+/*
+ * 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.it.schema;
+
+public class DefaultJsonValueResponse {
+  private int type;
+
+  private String message;
+
+  public int getType() {
+    return type;
+  }
+
+  public void setType(int type) {
+    this.type = type;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Add a feature to serialize/deserialize using Object to avoid information lose
> -----------------------------------------------------------------------------
>
>                 Key: SCB-903
>                 URL: https://issues.apache.org/jira/browse/SCB-903
>             Project: Apache ServiceComb
>          Issue Type: New Feature
>          Components: Java-Chassis
>            Reporter: liubao
>            Assignee: liubao
>            Priority: Major
>
> Scenario:
> When using edge, user need to know if default values is given in json 
> request. They check this constraints by if the key is exists in json string. 
> But now, edge will convert json string to schema related class. When 
> conversion happens, new keys will be added. User can never know it is default 
> value or if the key is not exists.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to