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 2020/01/11 10:02:53 UTC
[servicecomb-java-chassis] 01/08: [SCB-1703]Highway transport
switch to new codec APIs and turn on highway transport
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
commit 66ac9b37f2534775b89f6f1bf73d1f58f35a52a3
Author: liubao <bi...@qq.com>
AuthorDate: Thu Jan 2 19:29:44 2020 +0800
[SCB-1703]Highway transport switch to new codec APIs and turn on highway transport
---
.../protobuf/definition/OperationProtobuf.java | 65 ++++--
.../converter/SwaggerToProtoGenerator.java | 39 +++-
.../internal/converter/TestSchemaMetaCodec.java | 142 +++++++------
...c.java => TestSchemaMetaCodecRestTemplate.java} | 137 +++++++------
.../java/org/apache/servicecomb/core/Const.java | 2 +
.../org/apache/servicecomb/core/Invocation.java | 14 +-
.../jaxrs/client/CodeFirstRestTemplateJaxrs.java | 4 +-
.../servicecomb/demo/jaxrs/client/JaxrsClient.java | 188 +++++++++++++-----
.../client/beanParam/BeanParamPojoClient.java | 8 +-
.../beanParam/BeanParamRestTemplateClient.java | 7 +-
.../client/validation/ValidationServiceClient.java | 2 +-
.../servicecomb/demo/CodeFirstRestTemplate.java | 70 ++++---
.../org/apache/servicecomb/demo/DemoConst.java | 3 +-
.../client/CodeFirstRestTemplateSpringmvc.java | 17 +-
.../demo/springmvc/client/SpringmvcClient.java | 219 ++++++++++++++++-----
.../demo/springmvc/client/TestObject.java | 23 ++-
.../demo/springmvc/client/TestResponse.java | 10 +-
.../demo/springmvc/client/TestRestTemplate.java | 4 +-
.../src/main/resources/microservice.yaml | 2 +-
.../foundation/protobuf/ProtoMapper.java | 38 ++--
.../protobuf/RequestRootDeserializer.java | 53 +++++
.../foundation/protobuf/RequestRootSerializer.java | 53 +++++
.../protobuf/ResponseRootDeserializer.java | 49 +++++
.../foundation/protobuf/internal/ProtoUtils.java | 9 +
.../protobuf/internal/schema/SchemaManager.java | 52 +++--
.../deserializer/DeserializerSchemaManager.java | 49 +++--
.../schema/deserializer/MessageReadSchema.java | 36 ++--
.../schema/serializer/MessageWriteSchema.java | 46 ++++-
.../schema/serializer/SerializerSchemaManager.java | 22 ++-
.../protobuf/internal/TestMethodWrap.java | 91 ---------
.../foundation/vertx/server/TcpParser.java | 5 +
.../pojo/definition/PojoConsumerOperationMeta.java | 2 +
.../swagger/invocation/SwaggerInvocation.java | 4 +
.../transport/highway/HighwayClientPackage.java | 5 +
.../transport/highway/HighwayCodec.java | 14 +-
.../transport/highway/HighwayOutputStream.java | 38 +++-
.../services/org.apache.servicecomb.core.Transport | 2 +-
.../transport/highway/TestHighwayCodec.java | 16 +-
.../transport/highway/TestHighwayTransport.java | 3 +-
39 files changed, 1048 insertions(+), 495 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 0a0838c..b9d6826 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
@@ -17,6 +17,10 @@
package org.apache.servicecomb.codec.protobuf.definition;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.core.Response.Status;
@@ -26,8 +30,11 @@ import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
+import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+import org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;
import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import io.protostuff.compiler.model.Message;
@@ -38,13 +45,14 @@ public class OperationProtobuf {
private OperationMeta operationMeta;
- private RootSerializer requestSerializer;
+ private RequestRootSerializer requestSerializer;
- private RootDeserializer<Object> requestDeserializer;
+ // For wrapped parameters, this is a Map. While for POJO body, this is an Object.
+ private RequestRootDeserializer<Object> requestDeserializer;
private RootSerializer responseSerializer;
- private RootDeserializer<Object> responseDeserializer;
+ private ResponseRootDeserializer<Object> responseDeserializer;
public OperationProtobuf(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
this.scopedProtobufSchemaManager = scopedProtobufSchemaManager;
@@ -52,14 +60,32 @@ public class OperationProtobuf {
ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
Message requestMessage = mapper.getRequestMessage(operationMeta.getOperationId());
- requestSerializer = mapper.createRootSerializer(requestMessage, Object.class);
- SwaggerProducerOperation producerOperation = operationMeta.getExtData(Const.PRODUCER_OPERATION);
- if (producerOperation == null) {
+
+ if (operationMeta.getExtData(Const.PRODUCER_OPERATION) != null &&
+ ((SwaggerProducerOperation) operationMeta.getExtData(Const.PRODUCER_OPERATION)).getProducerMethod() != null) {
+ // producer invocation
requestDeserializer = mapper
- .createRootDeserializer(requestMessage, Object.class);
- } else {
+ .createRequestRootDeserializer(requestMessage, getMethodParameterTypesMap(
+ ((SwaggerProducerOperation) operationMeta.getExtData(Const.PRODUCER_OPERATION)).getProducerMethod()));
+ requestSerializer = mapper
+ .createRequestRootSerializer(requestMessage, getMethodParameterTypesMap(
+ ((SwaggerProducerOperation) operationMeta.getExtData(Const.PRODUCER_OPERATION)).getProducerMethod()),
+ false);
+ } else if (operationMeta.getExtData(Const.CONSUMER_OPERATION) != null
+ && ((SwaggerConsumerOperation) operationMeta.getExtData(Const.CONSUMER_OPERATION)).getConsumerMethod()
+ != null) {
+ // consumer pojo invocation
requestDeserializer = mapper
- .createRootDeserializer(requestMessage, Map.class, producerOperation.getProducerMethod());
+ .createRequestRootDeserializer(requestMessage, getMethodParameterTypesMap(
+ ((SwaggerConsumerOperation) operationMeta.getExtData(Const.CONSUMER_OPERATION)).getConsumerMethod()));
+ requestSerializer = mapper
+ .createRequestRootSerializer(requestMessage, getMethodParameterTypesMap(
+ ((SwaggerConsumerOperation) operationMeta.getExtData(Const.CONSUMER_OPERATION)).getConsumerMethod()),
+ false);
+ } else {
+ // consumer RestTemplate invocation
+ requestSerializer = mapper.createRequestRootSerializer(requestMessage, (Map<String, Type>) null, true);
+ requestDeserializer = mapper.createRequestRootDeserializer(requestMessage, Object.class);
}
Message responseMessage = mapper.getResponseMessage(operationMeta.getOperationId());
@@ -67,19 +93,28 @@ public class OperationProtobuf {
.createRootSerializer(responseMessage,
operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode()));
responseDeserializer = mapper
- .createRootDeserializer(responseMessage,
+ .createResponseRootDeserializer(responseMessage,
operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode()));
}
+ private Map<String, Type> getMethodParameterTypesMap(Method method) {
+ Map<String, Type> parameters = new HashMap<>();
+ for (Parameter parameter : method.getParameters()) {
+ // TODO : WEAK parameter generics
+ parameters.put(parameter.getName(), parameter.getType());
+ }
+ return parameters;
+ }
+
public OperationMeta getOperationMeta() {
return operationMeta;
}
- public RootSerializer findRequestSerializer() {
+ public RequestRootSerializer findRequestSerializer() {
return requestSerializer;
}
- public RootDeserializer<Object> findRequestDesirializer() {
+ public RequestRootDeserializer<Object> findRequestDesirializer() {
return requestDeserializer;
}
@@ -91,11 +126,11 @@ public class OperationProtobuf {
return null;
}
- public RootDeserializer<Object> findResponseDesirialize(int statusCode) {
+ public ResponseRootDeserializer<Object> findResponseDesirialize(int statusCode) {
if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {
return responseDeserializer;
}
// TODO : handles only one response type.
- return null;
+ throw new IllegalStateException("not implemented now, statusCode = " + statusCode);
}
}
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
index 78367f2..6b73b06 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
@@ -28,11 +28,14 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.hash.Hashing;
@@ -49,6 +52,8 @@ import io.swagger.models.properties.Property;
import io.vertx.core.json.Json;
public class SwaggerToProtoGenerator {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerToProtoGenerator.class);
+
private final String protoPackage;
private final Swagger swagger;
@@ -283,13 +288,45 @@ public class SwaggerToProtoGenerator {
appendLine(serviceBuilder, "service MainService {");
for (Path path : paths.values()) {
for (Operation operation : path.getOperationMap().values()) {
- convertOperation(operation);
+ if (isUpload(operation)) {
+ LOGGER.warn("Not support operation for highway {}.{}, {}", this.protoPackage, operation.getOperationId(),
+ "file upload not supported");
+ continue;
+ } else if (isDownload(operation)) {
+ LOGGER.warn("Not support operation for highway {}.{}, {}", this.protoPackage, operation.getOperationId(),
+ "file download not supported");
+ continue;
+ }
+ try {
+ convertOperation(operation);
+ } catch (Exception e) {
+ LOGGER.error("Not support operation for highway {}.{}", this.protoPackage, operation.getOperationId(), e);
+ }
}
}
+
serviceBuilder.setLength(serviceBuilder.length() - 1);
+
appendLine(serviceBuilder, "}");
}
+ private boolean isUpload(Operation operation) {
+ if (operation.getConsumes() != null && operation.getConsumes().contains(MediaType.MULTIPART_FORM_DATA)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean isDownload(Operation operation) {
+ if (operation.getResponses().get("200").getResponseSchema() instanceof ModelImpl) {
+ ModelImpl model = (ModelImpl) operation.getResponses().get("200").getResponseSchema();
+ if ("file".equals(model.getType())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private void convertOperation(Operation operation) {
ProtoMethod protoMethod = new ProtoMethod();
fillRequestType(operation, protoMethod);
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
index abf509d..3a2fb8e 100644
--- 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
@@ -28,22 +28,24 @@ 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.Const;
-import org.apache.servicecomb.core.SCBEngine;
-import org.apache.servicecomb.core.definition.CoreMetaUtils;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
-import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
+import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
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.engine.SwaggerConsumer;
+import org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;
import org.apache.servicecomb.swagger.engine.SwaggerEnvironment;
import org.apache.servicecomb.swagger.engine.SwaggerProducer;
import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import io.swagger.models.Swagger;
@@ -51,26 +53,58 @@ import mockit.Expectations;
import mockit.Injectable;
/**
- * SchemaMetaCodec test cases
+ * SchemaMetaCodec test cases. This test cases covers POJO invoker and producer.
*/
public class TestSchemaMetaCodec {
- @Test
- public void testProtoSchemaOperationUser(@Injectable MicroserviceMeta microserviceMeta) throws Exception {
+ @Injectable
+ private MicroserviceMeta providerMicroserviceMeta;
+
+ @Injectable
+ private MicroserviceMeta consumerMicroserviceMeta;
+
+ private SchemaMeta providerSchemaMeta;
+
+ private SchemaMeta consumerSchemaMeta;
+
+ @Before
+ public void setUp() {
new Expectations() {
{
- microserviceMeta.getMicroserviceName();
+ providerMicroserviceMeta.getMicroserviceName();
+ result = "test";
+ providerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID);
+ result = null;
+ consumerMicroserviceMeta.getMicroserviceName();
result = "test";
- microserviceMeta.getExtData(ProtobufManager.EXT_ID);
+ consumerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID);
result = null;
}
};
SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);
Swagger swagger = swaggerGenerator.generate();
- SchemaMeta schemaMeta = new SchemaMeta(microserviceMeta, "ProtoSchema", swagger);
+ SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
- // response message
- OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(schemaMeta.getOperations().get("user"));
- RootSerializer responseSerializer = operationProtobuf.findResponseSerializer(200);
+ providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, "ProtoSchema", swagger);
+ SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(new ProtoSchema(), swagger);
+ for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
+ OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());
+ operationMeta.putExtData(Const.PRODUCER_OPERATION, producerOperation);
+ }
+
+ consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, "ProtoSchema", swagger);
+ SwaggerConsumer swaggerConsumer = swaggerEnvironment.createConsumer(ProtoSchema.class, swagger);
+ for (SwaggerConsumerOperation consumerOperation : swaggerConsumer.getOperations().values()) {
+ OperationMeta operationMeta = consumerSchemaMeta.ensureFindOperation(consumerOperation.getSchemaOperationId());
+ operationMeta.putExtData(Const.CONSUMER_OPERATION, consumerOperation);
+ }
+ }
+
+ @Test
+ public void testProtoSchemaOperationUser() throws Exception {
+ OperationProtobuf providerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(providerSchemaMeta.getOperations().get("user"));
+ OperationProtobuf consumerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(consumerSchemaMeta.getOperations().get("user"));
User user = new User();
user.name = "user";
User friend = new User();
@@ -78,65 +112,48 @@ public class TestSchemaMetaCodec {
List<User> friends = new ArrayList<>();
friends.add(friend);
user.friends = friends;
- byte[] values = responseSerializer.serialize(user);
- RootDeserializer<Object> responseDeserializer = operationProtobuf.findResponseDesirialize(200);
+ byte[] values;
+
+ // request message
+ Map<String, Object> args = new HashMap<>();
+ RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+ user.friends = friends;
+ args.put("user", user);
+ values = requestSerializer.serialize(args);
+
+ RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+ Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);
+ Assert.assertEquals(user.name, ((User) decodedUserArgs.get("user")).name);
+ Assert.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get("user")).friends.get(0).name);
+
+ // response message
+ RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+ values = responseSerializer.serialize(user);
+ ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.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,
- @Injectable SCBEngine scbEngine) 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);
-
- SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
- SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(new ProtoSchema(), swagger);
- schemaMeta.putExtData(CoreMetaUtils.SWAGGER_PRODUCER, swaggerProducer);
- for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
- OperationMeta operationMeta = schemaMeta.ensureFindOperation(producerOperation.getOperationId());
- operationMeta.putExtData(Const.PRODUCER_OPERATION, producerOperation);
- }
-
- // response message
+ public void testProtoSchemaOperationBase() throws Exception {
// 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 ?
+ OperationProtobuf providerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
+ OperationProtobuf consumerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(consumerSchemaMeta.getOperations().get("base"));
+ byte[] values;
// request message
- RootSerializer requestSerializer = operationProtobuf.findRequestSerializer();
+ RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
boolean boolValue = true;
int iValue = 20;
long lValue = 30L;
@@ -161,9 +178,8 @@ public class TestSchemaMetaCodec {
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;
+ RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+ Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);
Assert.assertEquals(boolValue, decodedArgs.get("boolValue"));
Assert.assertEquals(iValue, decodedArgs.get("iValue"));
Assert.assertEquals(lValue, decodedArgs.get("lValue"));
@@ -189,8 +205,7 @@ public class TestSchemaMetaCodec {
args.put("date", null);
args.put("empty", null);
values = requestSerializer.serialize(args);
- obj = requestDeserializer.deserialize(values);
- decodedArgs = (Map<String, Object>) obj;
+ decodedArgs = requestDeserializer.deserialize(values);
Assert.assertEquals(null, decodedArgs.get("boolValue"));
Assert.assertEquals(null, decodedArgs.get("iValue"));
Assert.assertEquals(null, decodedArgs.get("lValue"));
@@ -201,5 +216,12 @@ public class TestSchemaMetaCodec {
Assert.assertEquals(null, decodedArgs.get("localDate"));
Assert.assertEquals(null, decodedArgs.get("date"));
Assert.assertEquals(null, decodedArgs.get("empty"));
+
+ // response message
+ RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+ values = responseSerializer.serialize(30);
+ ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+ Object decodedValue = responseDeserializer.deserialize(values);
+ Assert.assertEquals(30, (int) decodedValue);
}
}
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/TestSchemaMetaCodecRestTemplate.java
similarity index 65%
copy from common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
copy to common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
index abf509d..9dccd73 100644
--- 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/TestSchemaMetaCodecRestTemplate.java
@@ -28,14 +28,13 @@ 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.Const;
-import org.apache.servicecomb.core.SCBEngine;
-import org.apache.servicecomb.core.definition.CoreMetaUtils;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
-import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
+import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
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;
@@ -44,6 +43,7 @@ import org.apache.servicecomb.swagger.engine.SwaggerProducer;
import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import io.swagger.models.Swagger;
@@ -51,26 +51,53 @@ import mockit.Expectations;
import mockit.Injectable;
/**
- * SchemaMetaCodec test cases
+ * SchemaMetaCodec test cases. This test cases covers RestTemplate invoker and producer.
*/
-public class TestSchemaMetaCodec {
- @Test
- public void testProtoSchemaOperationUser(@Injectable MicroserviceMeta microserviceMeta) throws Exception {
+public class TestSchemaMetaCodecRestTemplate {
+ @Injectable
+ private MicroserviceMeta providerMicroserviceMeta;
+
+ @Injectable
+ private MicroserviceMeta consumerMicroserviceMeta;
+
+ private SchemaMeta providerSchemaMeta;
+
+ private SchemaMeta consumerSchemaMeta;
+
+ @Before
+ public void setUp() {
new Expectations() {
{
- microserviceMeta.getMicroserviceName();
+ providerMicroserviceMeta.getMicroserviceName();
+ result = "test";
+ providerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID);
+ result = null;
+ consumerMicroserviceMeta.getMicroserviceName();
result = "test";
- microserviceMeta.getExtData(ProtobufManager.EXT_ID);
+ consumerMicroserviceMeta.getExtData(ProtobufManager.EXT_ID);
result = null;
}
};
SpringmvcSwaggerGenerator swaggerGenerator = new SpringmvcSwaggerGenerator(ProtoSchema.class);
Swagger swagger = swaggerGenerator.generate();
- SchemaMeta schemaMeta = new SchemaMeta(microserviceMeta, "ProtoSchema", swagger);
+ SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
- // response message
- OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(schemaMeta.getOperations().get("user"));
- RootSerializer responseSerializer = operationProtobuf.findResponseSerializer(200);
+ providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, "ProtoSchema", swagger);
+ SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(new ProtoSchema(), swagger);
+ for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
+ OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());
+ operationMeta.putExtData(Const.PRODUCER_OPERATION, producerOperation);
+ }
+
+ consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, "ProtoSchema", swagger);
+ }
+
+ @Test
+ public void testProtoSchemaOperationUser() throws Exception {
+ OperationProtobuf providerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(providerSchemaMeta.getOperations().get("user"));
+ OperationProtobuf consumerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(consumerSchemaMeta.getOperations().get("user"));
User user = new User();
user.name = "user";
User friend = new User();
@@ -78,65 +105,48 @@ public class TestSchemaMetaCodec {
List<User> friends = new ArrayList<>();
friends.add(friend);
user.friends = friends;
- byte[] values = responseSerializer.serialize(user);
- RootDeserializer<Object> responseDeserializer = operationProtobuf.findResponseDesirialize(200);
+ byte[] values;
+
+ // request message
+ Map<String, Object> args = new HashMap<>();
+ RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+ user.friends = friends;
+ args.put("user", user);
+ values = requestSerializer.serialize(args);
+
+ RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+ Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);
+ Assert.assertEquals(user.name, ((User) decodedUserArgs.get("user")).name);
+ Assert.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get("user")).friends.get(0).name);
+
+ // response message
+ RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+ values = responseSerializer.serialize(user);
+ ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.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,
- @Injectable SCBEngine scbEngine) 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);
-
- SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
- SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(new ProtoSchema(), swagger);
- schemaMeta.putExtData(CoreMetaUtils.SWAGGER_PRODUCER, swaggerProducer);
- for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
- OperationMeta operationMeta = schemaMeta.ensureFindOperation(producerOperation.getOperationId());
- operationMeta.putExtData(Const.PRODUCER_OPERATION, producerOperation);
- }
-
- // response message
+ public void testProtoSchemaOperationBase() throws Exception {
// 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 ?
+ OperationProtobuf providerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
+ OperationProtobuf consumerOperationProtobuf = ProtobufManager
+ .getOrCreateOperation(consumerSchemaMeta.getOperations().get("base"));
+ byte[] values;
// request message
- RootSerializer requestSerializer = operationProtobuf.findRequestSerializer();
+ RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
boolean boolValue = true;
int iValue = 20;
long lValue = 30L;
@@ -161,9 +171,8 @@ public class TestSchemaMetaCodec {
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;
+ RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+ Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);
Assert.assertEquals(boolValue, decodedArgs.get("boolValue"));
Assert.assertEquals(iValue, decodedArgs.get("iValue"));
Assert.assertEquals(lValue, decodedArgs.get("lValue"));
@@ -189,8 +198,7 @@ public class TestSchemaMetaCodec {
args.put("date", null);
args.put("empty", null);
values = requestSerializer.serialize(args);
- obj = requestDeserializer.deserialize(values);
- decodedArgs = (Map<String, Object>) obj;
+ decodedArgs = requestDeserializer.deserialize(values);
Assert.assertEquals(null, decodedArgs.get("boolValue"));
Assert.assertEquals(null, decodedArgs.get("iValue"));
Assert.assertEquals(null, decodedArgs.get("lValue"));
@@ -201,5 +209,12 @@ public class TestSchemaMetaCodec {
Assert.assertEquals(null, decodedArgs.get("localDate"));
Assert.assertEquals(null, decodedArgs.get("date"));
Assert.assertEquals(null, decodedArgs.get("empty"));
+
+ // response message
+ RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+ values = responseSerializer.serialize(30);
+ ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+ Object decodedValue = responseDeserializer.deserialize(values);
+ Assert.assertEquals(30, (int) decodedValue);
}
}
diff --git a/core/src/main/java/org/apache/servicecomb/core/Const.java b/core/src/main/java/org/apache/servicecomb/core/Const.java
index e46cc82..520edf4 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Const.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Const.java
@@ -37,6 +37,8 @@ public final class Const {
public static final String PRODUCER_OPERATION = "producer-operation";
+ public static final String CONSUMER_OPERATION = "consumer-operation";
+
public static final String SRC_MICROSERVICE = "x-cse-src-microservice";
public static final String TARGET_MICROSERVICE = "x-cse-target-microservice";
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 5ddf4a3..c4103f0 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -44,6 +44,7 @@ import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.InvocationType;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+import org.apache.servicecomb.swagger.invocation.context.InvocationContext;
import org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;
import com.fasterxml.jackson.databind.JavaType;
@@ -187,15 +188,26 @@ public class Invocation extends SwaggerInvocation {
}
public Map<String, Object> getArguments() {
+ if (swaggerArguments == null) {
+ return new HashMap<>(0);
+ }
Map<String, Object> result = new HashMap<>(swaggerArguments.length);
for (int i = 0; i < swaggerArguments.length; i++) {
+ if (swaggerArguments[i] instanceof InvocationContext) {
+ continue;
+ }
result.put(this.operationMeta.getParamName(i), swaggerArguments[i]);
}
return result;
}
public void setArguments(Map<String, Object> swaggerArguments) {
- Object[] args = new Object[swaggerArguments.size()];
+ if (swaggerArguments == null) {
+ // Empty arguments
+ setSwaggerArguments(null);
+ return;
+ }
+ Object[] args = new Object[this.operationMeta.getParamSize()];
for (Entry<String, Object> item : swaggerArguments.entrySet()) {
args[this.operationMeta.getParameterIndex(item.getKey())] = item.getValue();
}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
index c3d24da..fc33127 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
@@ -51,13 +51,13 @@ public class CodeFirstRestTemplateJaxrs extends CodeFirstRestTemplate {
}
@Override
- protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) {
+ protected void testOnlyRest(String microserviceName, RestTemplate template, String cseUrlPrefix) {
try {
testUpload(template, cseUrlPrefix);
} catch (IOException e) {
throw new IllegalStateException(e);
}
- super.testOnlyRest(template, cseUrlPrefix);
+ super.testOnlyRest(microserviceName, template, cseUrlPrefix);
}
private void testUpload(RestTemplate template, String cseUrlPrefix) throws IOException {
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index 8589c44..b1cbd13 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -74,16 +74,29 @@ public class JaxrsClient {
testCompute(templateNew);
testValidator(templateNew);
testClientTimeOut(templateNew);
- testJaxRSDefaultValues(templateNew);
- testSpringMvcDefaultValuesJavaPrimitive(templateNew);
+ testJaxRSDefaultValuesAllTransport(templateNew);
+ testSpringMvcDefaultValuesJavaPrimitiveAllTransport(templateNew);
MultiErrorCodeServiceClient.runTest();
BeanParamPojoClient beanParamPojoClient = new BeanParamPojoClient();
- beanParamPojoClient.testAll();
+ beanParamPojoClient.testAllTransport();
BeanParamRestTemplateClient beanParamRestTemplateClient = new BeanParamRestTemplateClient();
- beanParamRestTemplateClient.testAll();
+ beanParamRestTemplateClient.testAllTransport();
DefaultModelServiceClient.run();
ValidationServiceClient.run();
+
+ testOnlyRest(templateNew);
+ beanParamPojoClient.testRestOnly();
+ beanParamRestTemplateClient.testRestOnly();
+ }
+
+ private static void testOnlyRest(RestTemplate template) {
+ String microserviceName = "jaxrs";
+ String cseUrlPrefix = "cse://" + microserviceName;
+ ArchaiusUtils.setProperty("servicecomb.reference.transport." + microserviceName, "rest");
+
+ testGetRest(template, cseUrlPrefix);
+ testSpringMvcDefaultValuesJavaPrimitiveRest(templateNew);
}
private static void testCompute(RestTemplate template) throws Exception {
@@ -94,7 +107,7 @@ public class JaxrsClient {
String cseUrlPrefix = "cse://" + microserviceName;
- testGet(template, cseUrlPrefix);
+ testGetAllTransport(template, cseUrlPrefix);
testPost(template, cseUrlPrefix);
testPut(template, cseUrlPrefix);
testDelete(template, cseUrlPrefix);
@@ -120,7 +133,49 @@ public class JaxrsClient {
}
}
- private static void testJaxRSDefaultValues(RestTemplate template) {
+ private static void testJaxRSDefaultValuesRest(RestTemplate template) {
+ String result;
+ String microserviceName = "jaxrs";
+ String cseUrlPrefix = "cse://" + microserviceName + "/JaxRSDefaultValues/";
+ boolean failed = false;
+ try {
+ result = template.getForObject(cseUrlPrefix + "/query2", String.class);
+ } catch (InvocationException e) {
+ failed = true;
+ TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+ }
+
+ failed = false;
+ try {
+ result = template.getForObject(cseUrlPrefix + "/query2?d=2&e=2", String.class);
+ } catch (InvocationException e) {
+ failed = true;
+ TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+ }
+ TestMgr.check(failed, true);
+
+ failed = false;
+ try {
+ result = template.getForObject(cseUrlPrefix + "/query2?a=&d=2&e=2", String.class);
+ } catch (InvocationException e) {
+ failed = true;
+ TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+ }
+ TestMgr.check(failed, true);
+
+ result = template.getForObject(cseUrlPrefix + "/query2?d=30&e=2", String.class);
+ TestMgr.check("Hello 20bobo40302", result);
+
+ failed = false;
+ try {
+ result = template.getForObject(cseUrlPrefix + "/query3?a=2&b=2", String.class);
+ } catch (InvocationException e) {
+ failed = true;
+ TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+ }
+ TestMgr.check(failed, true);
+ }
+ private static void testJaxRSDefaultValuesAllTransport(RestTemplate template) {
String microserviceName = "jaxrs";
for (String transport : DemoConst.transports) {
ArchaiusUtils.setProperty("servicecomb.reference.transport." + microserviceName, transport);
@@ -144,42 +199,43 @@ public class JaxrsClient {
result = template.getForObject(cseUrlPrefix + "/query?d=10", String.class);
TestMgr.check("Hello 20bobo4010", result);
boolean failed = false;
- try {
- result = template.getForObject(cseUrlPrefix + "/query2", String.class);
- } catch (InvocationException e) {
- failed = true;
- TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
- }
-
- failed = false;
- try {
- result = template.getForObject(cseUrlPrefix + "/query2?d=2&e=2", String.class);
- } catch (InvocationException e) {
- failed = true;
- TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
- }
- TestMgr.check(failed, true);
-
- failed = false;
- try {
- result = template.getForObject(cseUrlPrefix + "/query2?a=&d=2&e=2", String.class);
- } catch (InvocationException e) {
- failed = true;
- TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
- }
- TestMgr.check(failed, true);
-
- result = template.getForObject(cseUrlPrefix + "/query2?d=30&e=2", String.class);
- TestMgr.check("Hello 20bobo40302", result);
-
- failed = false;
- try {
- result = template.getForObject(cseUrlPrefix + "/query3?a=2&b=2", String.class);
- } catch (InvocationException e) {
- failed = true;
- TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
- }
- TestMgr.check(failed, true);
+ // TODO: WEAK invocationexception not support in HIGHWAY
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2?d=2&e=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2?a=&d=2&e=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
+//
+// result = template.getForObject(cseUrlPrefix + "/query2?d=30&e=2", String.class);
+// TestMgr.check("Hello 20bobo40302", result);
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query3?a=2&b=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2", String.class);
TestMgr.check("Hello 302", result);
@@ -213,7 +269,7 @@ public class JaxrsClient {
}
}
- private static void testGet(RestTemplate template, String cseUrlPrefix) {
+ private static void testGetRest(RestTemplate template, String cseUrlPrefix) {
Map<String, String> params = new HashMap<>();
params.put("a", "5");
params.put("b", "3");
@@ -229,6 +285,23 @@ public class JaxrsClient {
TestMgr.check(-1, result);
}
+ private static void testGetAllTransport(RestTemplate template, String cseUrlPrefix) {
+ // TODO: WEAK highway not support HttpServletRequest
+// Map<String, String> params = new HashMap<>();
+// params.put("a", "5");
+// params.put("b", "3");
+// int result =
+// template.getForObject(cseUrlPrefix + "/compute/reduce?a={a}&b={b}", Integer.class, params);
+// TestMgr.check(2, result);
+//
+// result = template.getForObject(cseUrlPrefix + "/compute/reduce?a={a}&b={b}", Integer.class, 5, 4);
+// TestMgr.check(1, result);
+//
+// result = template.getForObject(cseUrlPrefix + "/compute/reduce?a=5&b=6",
+// Integer.class);
+// TestMgr.check(-1, result);
+ }
+
private static void testPost(RestTemplate template, String cseUrlPrefix) {
Map<String, String> params = new HashMap<>();
params.put("a", "5");
@@ -416,7 +489,7 @@ public class JaxrsClient {
TestMgr.check(true, isExcep);
}
- private static void testSpringMvcDefaultValuesJavaPrimitive(RestTemplate template) {
+ private static void testSpringMvcDefaultValuesJavaPrimitiveRest(RestTemplate template) {
String microserviceName = "jaxrs";
String cseUrlPrefix = "cse://" + microserviceName + "/JaxRSDefaultValues/";
@@ -441,4 +514,31 @@ public class JaxrsClient {
result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null, String.class);
TestMgr.check("Hello false,\0,0,0,0,0,0.0,0.0,null", result);
}
+
+ private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestTemplate template) {
+ // TODO : WEAK highway not support primitive default values
+// String microserviceName = "jaxrs";
+// String cseUrlPrefix = "cse://" + microserviceName + "/JaxRSDefaultValues/";
+//
+// HttpHeaders headers = new HttpHeaders();
+// headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);
+// MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+// HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
+//
+// //default values with primitive
+// String result = template.postForObject(cseUrlPrefix + "/javaprimitiveint", request, String.class);
+// TestMgr.check("Hello 0bobo", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivenumber", request, String.class);
+// TestMgr.check("Hello 0.0false", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivestr", request, String.class);
+// TestMgr.check("Hello", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb", request, String.class);
+// TestMgr.check("Hello nullnull", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null, String.class);
+// TestMgr.check("Hello false,\0,0,0,0,0,0.0,0.0,null", result);
+ }
}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamPojoClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamPojoClient.java
index cf70f8e..2f384f4 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamPojoClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamPojoClient.java
@@ -30,7 +30,13 @@ public class BeanParamPojoClient {
beanParamTestServiceIntf = Invoker.createProxy("jaxrs", "beanParamTest", BeanParamTestServiceIntf.class);
}
- public void testAll() {
+ public void testAllTransport() {
+ // TODO : WEAK highway not implement InvocationContext and BeanParam and Upload
+// testBeanParam();
+// testUpload();
+ }
+
+ public void testRestOnly() {
testBeanParam();
testUpload();
}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamRestTemplateClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamRestTemplateClient.java
index 82422d9..401d3a2 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamRestTemplateClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/beanParam/BeanParamRestTemplateClient.java
@@ -40,7 +40,12 @@ public class BeanParamRestTemplateClient {
}
- public void testAll() {
+ public void testAllTransport() {
+// testBeanParam();
+// testUpload();
+ }
+
+ public void testRestOnly() {
testBeanParam();
testUpload();
}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
index 980e801..84fa8d0 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
@@ -35,7 +35,7 @@ public class ValidationServiceClient {
public static void run() {
// highway do not support this feature
- ArchaiusUtils.setProperty("servicecomb.reference.transport.jaxrs", "rest");
+ ArchaiusUtils.setProperty("servicecomb.references.transport.jaxrs", "rest");
testValidation();
}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
index b49f6d8..417c351 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
@@ -45,42 +45,42 @@ import io.vertx.core.json.JsonObject;
public class CodeFirstRestTemplate {
protected void changeTransport(String microserviceName, String transport) {
- ArchaiusUtils.setProperty("servicecomb.reference.transport." + microserviceName, transport);
+ ArchaiusUtils.setProperty("servicecomb.references.transport." + microserviceName, transport);
TestMgr.setMsg(microserviceName, transport);
}
public void testCodeFirst(RestTemplate template, String microserviceName, String basePath) {
String cseUrlPrefix = "cse://" + microserviceName + basePath;
- // TODO recover highway test in SCB-1635
-// changeTransport(microserviceName, "highway");
-// testOnlyHighway(template, cseUrlPrefix);
+ changeTransport(microserviceName, "highway");
+ testOnlyHighway(template, cseUrlPrefix);
changeTransport(microserviceName, Const.RESTFUL);
- testOnlyRest(template, cseUrlPrefix);
+ testOnlyRest(microserviceName, template, cseUrlPrefix);
- for (String transport : DemoConst.transports) {
+ for (String transport : DemoConst.transports) {
changeTransport(microserviceName, transport);
testAllTransport(microserviceName, template, cseUrlPrefix);
}
}
protected void testAllTransport(String microserviceName, RestTemplate template, String cseUrlPrefix) {
- testCodeFirstUserMap(template, cseUrlPrefix);
- testCodeFirstTextPlain(template, cseUrlPrefix);
- testCodeFirstAppXml(template, cseUrlPrefix);
- testCodeFirstBytes(template, cseUrlPrefix);
- testCseResponse(microserviceName, template, cseUrlPrefix);
- testCodeFirstAddDate(template, cseUrlPrefix);
-
- testCodeFirstAdd(template, cseUrlPrefix);
- testCodeFirstAddString(template, cseUrlPrefix);
+ // TODO : WEAK not supported now in HIGHWAY
+// testCodeFirstUserMap(template, cseUrlPrefix);
+// testCodeFirstTextPlain(template, cseUrlPrefix);
+// testCodeFirstAppXml(template, cseUrlPrefix);
+// testCodeFirstBytes(template, cseUrlPrefix);
+// testCseResponse(microserviceName, template, cseUrlPrefix);
+// testCodeFirstAddDate(template, cseUrlPrefix);
+
+// testCodeFirstAdd(template, cseUrlPrefix);
+// testCodeFirstAddString(template, cseUrlPrefix);
testCodeFirstIsTrue(template, cseUrlPrefix);
testCodeFirstSayHi2(template, cseUrlPrefix);
testCodeFirstSayHi(template, cseUrlPrefix);
testCodeFirstSaySomething(template, cseUrlPrefix);
// testCodeFirstRawJsonString(template, cseUrlPrefix);
testCodeFirstSayHello(template, cseUrlPrefix);
- testCodeFirstReduce(template, cseUrlPrefix);
+// testCodeFirstReduce(template, cseUrlPrefix);
testTraceIdOnContextContainsTraceId(template, cseUrlPrefix);
@@ -91,10 +91,18 @@ public class CodeFirstRestTemplate {
}
- protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) {
- // TODO: highway unsupported until JAV-394 completed
- testModelFieldIgnore(template, cseUrlPrefix);
+ protected void testOnlyRest(String microserviceName, RestTemplate template, String cseUrlPrefix) {
+ testCodeFirstUserMap(template, cseUrlPrefix);
+ testCodeFirstTextPlain(template, cseUrlPrefix);
+ testCodeFirstAppXml(template, cseUrlPrefix);
+ testCodeFirstBytes(template, cseUrlPrefix);
+ testCseResponse(microserviceName, template, cseUrlPrefix);
+ testCodeFirstAddDate(template, cseUrlPrefix);
+ testCodeFirstAdd(template, cseUrlPrefix);
+ testCodeFirstAddString(template, cseUrlPrefix);
+ testModelFieldIgnore(template, cseUrlPrefix);
+ testCodeFirstReduce(template, cseUrlPrefix);
// only rest transport will set trace id
testTraceIdOnNotSetBefore(template, cseUrlPrefix);
}
@@ -184,7 +192,7 @@ public class CodeFirstRestTemplate {
TestMgr.check(new Date(date.getTime() + seconds * 1000), result);
}
- protected void testCodeFirstAddString(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstAddString(RestTemplate template, String cseUrlPrefix) {
ResponseEntity<String> responseEntity =
template.exchange(cseUrlPrefix + "addstring?s=a&s=b",
HttpMethod.DELETE,
@@ -193,25 +201,25 @@ public class CodeFirstRestTemplate {
TestMgr.check("ab", responseEntity.getBody());
}
- protected void testCodeFirstIsTrue(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstIsTrue(RestTemplate template, String cseUrlPrefix) {
boolean result = template.getForObject(cseUrlPrefix + "istrue", boolean.class);
TestMgr.check(true, result);
}
- protected void testCodeFirstSayHi2(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstSayHi2(RestTemplate template, String cseUrlPrefix) {
ResponseEntity<String> responseEntity =
template.exchange(cseUrlPrefix + "sayhi/{name}/v2", HttpMethod.PUT, null, String.class, "world");
TestMgr.check("world sayhi 2", responseEntity.getBody());
}
- protected void testCodeFirstSayHi(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstSayHi(RestTemplate template, String cseUrlPrefix) {
ResponseEntity<String> responseEntity =
template.exchange(cseUrlPrefix + "sayhi/{name}", HttpMethod.PUT, null, String.class, "world");
TestMgr.check(202, responseEntity.getStatusCodeValue());
TestMgr.check("world sayhi", responseEntity.getBody());
}
- protected void testCodeFirstSaySomething(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstSaySomething(RestTemplate template, String cseUrlPrefix) {
Person person = new Person();
person.setName("person name");
@@ -224,7 +232,7 @@ public class CodeFirstRestTemplate {
TestMgr.check("prefix prefix person name", result);
}
- protected void testCodeFirstSayHello(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstSayHello(RestTemplate template, String cseUrlPrefix) {
Map<String, String> persionFieldMap = new HashMap<>();
persionFieldMap.put("name", "person name from map");
Person result = template.postForObject(cseUrlPrefix + "sayhello", persionFieldMap, Person.class);
@@ -236,7 +244,7 @@ public class CodeFirstRestTemplate {
TestMgr.check("hello person name from Object", result);
}
- protected void testCodeFirstAdd(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstAdd(RestTemplate template, String cseUrlPrefix) {
Map<String, String> params = new HashMap<>();
params.put("a", "5");
params.put("b", "3");
@@ -245,7 +253,7 @@ public class CodeFirstRestTemplate {
TestMgr.check(8, result);
}
- protected void testCodeFirstReduce(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstReduce(RestTemplate template, String cseUrlPrefix) {
Map<String, String> params = new HashMap<>();
params.put("a", "5");
@@ -258,7 +266,7 @@ public class CodeFirstRestTemplate {
TestMgr.check(2, result.getBody());
}
- protected void testModelFieldIgnore(RestTemplate template, String cseUrlPrefix) {
+ private void testModelFieldIgnore(RestTemplate template, String cseUrlPrefix) {
InputModelForTestIgnore input = new InputModelForTestIgnore("input_id_rest", "input_id_content",
new Person("inputSomeone"), new JsonObject("{\"InputJsonKey\" : \"InputJsonValue\"}"), () -> {
});
@@ -278,19 +286,19 @@ public class CodeFirstRestTemplate {
TestMgr.check(null, output.getOutputObject());
}
- protected void testRawJson(RestTemplate template, String cseUrlPrefix) {
+ private void testRawJson(RestTemplate template, String cseUrlPrefix) {
String input = "{\"name\" : \"zyy\"}";
String output = template.postForObject(cseUrlPrefix + "rawJsonAnnotation", input, String.class);
TestMgr.check("hello zyy", output);
}
- protected void testTraceIdOnNotSetBefore(RestTemplate template, String cseUrlPrefix) {
+ private void testTraceIdOnNotSetBefore(RestTemplate template, String cseUrlPrefix) {
String traceIdUrl = cseUrlPrefix + "traceId";
String result = template.getForObject(traceIdUrl, String.class);
TestMgr.checkNotEmpty(result);
}
- protected void testTraceIdOnContextContainsTraceId(RestTemplate template, String cseUrlPrefix) {
+ private void testTraceIdOnContextContainsTraceId(RestTemplate template, String cseUrlPrefix) {
String traceIdUrl = cseUrlPrefix + "traceId";
InvocationContext invocationContext = new InvocationContext();
invocationContext.addContext(Const.TRACE_ID_NAME, String.valueOf(Long.MIN_VALUE));
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoConst.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoConst.java
index 2e12abc..c76d4c8 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoConst.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/DemoConst.java
@@ -20,6 +20,5 @@ package org.apache.servicecomb.demo;
import org.apache.servicecomb.core.Const;
public interface DemoConst {
- // String[] transports = new String[] {"highway", "rest", Const.ANY_TRANSPORT};
- String[] transports = new String[] {"rest", Const.ANY_TRANSPORT};
+ String[] transports = new String[] {"highway", "rest", Const.ANY_TRANSPORT};
}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index 47eaae4..6c3c18c 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -76,12 +76,15 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
private TestBizkeeper testBizkeeper = new TestBizkeeper();
@Override
- protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) {
+ protected void testOnlyRest(String microservcieName, RestTemplate template, String cseUrlPrefix) {
try {
testUpload(template, cseUrlPrefix);
} catch (IOException e) {
throw new IllegalStateException(e);
}
+ testResponseEntity("springmvc", template, cseUrlPrefix);
+ testCodeFirstTestForm(template, cseUrlPrefix);
+ testFallback(template, cseUrlPrefix);
testResponse.runRest();
testObject.runRest();
@@ -89,7 +92,7 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
testRestTemplate.runRest();
testContentType.runAllTest();
- super.testOnlyRest(template, cseUrlPrefix);
+ super.testOnlyRest(microservcieName, template, cseUrlPrefix);
}
@Override
@@ -108,10 +111,10 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
testGeneric.runAllTransport();
testRestTemplate.runAllTest();
testBizkeeper.runAllTest();
-
- testResponseEntity("springmvc", template, cseUrlPrefix);
- testCodeFirstTestForm(template, cseUrlPrefix);
- testFallback(template, cseUrlPrefix);
+ // TODO : WEAK not supported now in HIGHWAY
+// testResponseEntity("springmvc", template, cseUrlPrefix);
+// testCodeFirstTestForm(template, cseUrlPrefix);
+// testFallback(template, cseUrlPrefix);
super.testAllTransport(microserviceName, template, cseUrlPrefix);
}
@@ -236,7 +239,7 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
TestMgr.check(retryResult, 5);
}
- protected void testCodeFirstTestForm(RestTemplate template, String cseUrlPrefix) {
+ private void testCodeFirstTestForm(RestTemplate template, String cseUrlPrefix) {
HttpHeaders formHeaders = new HttpHeaders();
formHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
Map<String, String> map = new HashMap<>();
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index 694f8b1..c599253 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -59,14 +59,18 @@ public class SpringmvcClient {
BeanUtils.init();
run();
-
- TestMgr.summary();
} catch (Throwable e) {
TestMgr.check("success", "failed");
System.err.println("-------------- test failed -------------");
e.printStackTrace();
System.err.println("-------------- test failed -------------");
}
+ TestMgr.summary();
+ }
+
+ private static void changeTransport(String microserviceName, String transport) {
+ ArchaiusUtils.setProperty("servicecomb.references.transport." + microserviceName, transport);
+ TestMgr.setMsg(microserviceName, transport);
}
public static void run() {
@@ -78,6 +82,7 @@ public class SpringmvcClient {
controller = BeanUtils.getBean("controller");
String prefix = "cse://springmvc";
+ String microserviceName = "springmvc";
try {
// this test class is intended for retry hanging issue JAV-127
@@ -92,19 +97,17 @@ public class SpringmvcClient {
codeFirstClient.testCodeFirst(restTemplate, "springmvc", "/codeFirstSpringmvc/");
codeFirstClient.testCodeFirst(templateUrlWithProviderPrefix, "springmvc", "/pojo/rest/codeFirstSpringmvc/");
- String microserviceName = "springmvc";
- for (String transport : DemoConst.transports) {
- ArchaiusUtils.setProperty("servicecomb.reference.transport." + microserviceName, transport);
+ testAllTransport(microserviceName);
+ testRestTransport(microserviceName, prefix);
+ }
- TestMgr.setMsg(microserviceName, transport);
+ private static void testRestTransport(String microserviceName, String prefix) {
+ changeTransport(microserviceName, "rest");
- testController(templateUrlWithServiceName, microserviceName);
+ testControllerRest(templateUrlWithServiceName, microserviceName);
+ testSpringMvcDefaultValuesRest(templateUrlWithServiceName, microserviceName);
+ testSpringMvcDefaultValuesJavaPrimitiveRest(templateUrlWithServiceName, microserviceName);
- testController();
- testRequiredBody(templateUrlWithServiceName, microserviceName);
- testSpringMvcDefaultValues(templateUrlWithServiceName, microserviceName);
- testSpringMvcDefaultValuesJavaPrimitive(templateUrlWithServiceName, microserviceName);
- }
HttpHeaders headers = new HttpHeaders();
headers.set("Accept-Encoding", "gzip");
HttpEntity<String> entity = new HttpEntity<>(headers);
@@ -168,20 +171,23 @@ public class SpringmvcClient {
}
}
- private static void testController(RestTemplate template, String microserviceName) {
- String prefix = "cse://" + microserviceName;
+ private static void testAllTransport(String microserviceName) {
+ for (String transport : DemoConst.transports) {
+ changeTransport(microserviceName, transport);
- TestMgr.check(7,
- template.getForObject(prefix + "/controller/add?a=3&b=4",
- Integer.class));
+ TestMgr.setMsg(microserviceName, transport);
- try {
- template.getForObject(prefix + "/controller/add",
- Integer.class);
- TestMgr.check("failed", "success");
- } catch (InvocationException e) {
- TestMgr.check(e.getStatusCode(), 400);
+ testControllerAllTransport(templateUrlWithServiceName, microserviceName);
+
+ testController();
+ testRequiredBody(templateUrlWithServiceName, microserviceName);
+ testSpringMvcDefaultValuesAllTransport(templateUrlWithServiceName, microserviceName);
+ testSpringMvcDefaultValuesJavaPrimitiveAllTransport(templateUrlWithServiceName, microserviceName);
}
+ }
+
+ private static void testControllerRest(RestTemplate template, String microserviceName) {
+ String prefix = "cse://" + microserviceName;
TestMgr.check("hi world [world]",
template.getForObject(prefix + "/controller/sayhi?name=world",
@@ -203,6 +209,55 @@ public class SpringmvcClient {
String.class,
params));
+ try {
+ template.postForObject(prefix + "/controller/sayhello/{name}",
+ null,
+ String.class,
+ "exception");
+ TestMgr.check(true, false);
+ } catch (InvocationException e) {
+ TestMgr.check(e.getStatusCode(), 503);
+ }
+
+ TestMgr.check("hi world [world]", controller.sayHi("world"));
+ }
+
+ private static void testControllerAllTransport(RestTemplate template, String microserviceName) {
+ String prefix = "cse://" + microserviceName;
+
+ TestMgr.check(7,
+ template.getForObject(prefix + "/controller/add?a=3&b=4",
+ Integer.class));
+
+ try {
+ template.getForObject(prefix + "/controller/add",
+ Integer.class);
+ TestMgr.check("failed", "success");
+ } catch (InvocationException e) {
+ TestMgr.check(e.getStatusCode(), 400);
+ }
+
+ // TODO: WEAK HttpServletRequest not supported in highway
+// TestMgr.check("hi world [world]",
+// template.getForObject(prefix + "/controller/sayhi?name=world",
+// String.class));
+//
+// TestMgr.check("hi world1 [world1]",
+// template.getForObject(prefix + "/controller/sayhi?name={name}",
+// String.class,
+// "world1"));
+// TestMgr.check("hi hi 中国 [hi 中国]",
+// template.getForObject(prefix + "/controller/sayhi?name={name}",
+// String.class,
+// "hi 中国"));
+//
+// Map<String, String> params = new HashMap<>();
+// params.put("name", "world2");
+// TestMgr.check("hi world2 [world2]",
+// template.getForObject(prefix + "/controller/sayhi?name={name}",
+// String.class,
+// params));
+
TestMgr.check("hello world",
template.postForObject(prefix + "/controller/sayhello/{name}",
null,
@@ -214,15 +269,16 @@ public class SpringmvcClient {
String.class,
"hello 中国"));
- try {
- template.postForObject(prefix + "/controller/sayhello/{name}",
- null,
- String.class,
- "exception");
- TestMgr.check(true, false);
- } catch (InvocationException e) {
- TestMgr.check(e.getStatusCode(), 503);
- }
+ // TODO: WEAK throw InvocationiException not supported in highway
+// try {
+// template.postForObject(prefix + "/controller/sayhello/{name}",
+// null,
+// String.class,
+// "exception");
+// TestMgr.check(true, false);
+// } catch (InvocationException e) {
+// TestMgr.check(e.getStatusCode(), 503);
+// }
HttpHeaders headers = new HttpHeaders();
headers.add("name", "world");
@@ -244,7 +300,8 @@ public class SpringmvcClient {
}
private static void testController() {
- TestMgr.check("hi world [world]", controller.sayHi("world"));
+ // TODO: WEAK HttpServletRequest not supported in highway
+// TestMgr.check("hi world [world]", controller.sayHi("world"));
Person user = new Person();
user.setName("world");
TestMgr.check("ha world", controller.saySomething("ha", user));
@@ -300,22 +357,9 @@ public class SpringmvcClient {
"ha"));
}
- private static void testSpringMvcDefaultValues(RestTemplate template, String microserviceName) {
+ private static void testSpringMvcDefaultValuesRest(RestTemplate template, String microserviceName) {
String cseUrlPrefix = "cse://" + microserviceName + "/SpringMvcDefaultValues/";
- //default values
- HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
- MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
- HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
- String result = template.postForObject(cseUrlPrefix + "/form", request, String.class);
- TestMgr.check("Hello 20bobo", result);
-
- headers = new HttpHeaders();
- HttpEntity<String> entity = new HttpEntity<>(null, headers);
- result = template.postForObject(cseUrlPrefix + "/header", entity, String.class);
- TestMgr.check("Hello 20bobo30", result);
-
- result = template.getForObject(cseUrlPrefix + "/query?d=10", String.class);
+ String result = template.getForObject(cseUrlPrefix + "/query?d=10", String.class);
TestMgr.check("Hello 20bobo4010", result);
boolean failed = false;
try {
@@ -354,6 +398,63 @@ public class SpringmvcClient {
TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
}
TestMgr.check(failed, true);
+ }
+
+ private static void testSpringMvcDefaultValuesAllTransport(RestTemplate template, String microserviceName) {
+ String cseUrlPrefix = "cse://" + microserviceName + "/SpringMvcDefaultValues/";
+ //default values
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+ MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+ HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
+ String result = template.postForObject(cseUrlPrefix + "/form", request, String.class);
+ TestMgr.check("Hello 20bobo", result);
+
+ headers = new HttpHeaders();
+ HttpEntity<String> entity = new HttpEntity<>(null, headers);
+ result = template.postForObject(cseUrlPrefix + "/header", entity, String.class);
+ TestMgr.check("Hello 20bobo30", result);
+
+ // TODO: WEAK InvocationException not supported in highway
+// result = template.getForObject(cseUrlPrefix + "/query?d=10", String.class);
+// TestMgr.check("Hello 20bobo4010", result);
+// boolean failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2?d=2&e=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query2?a=&d=2&e=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
+//
+// result = template.getForObject(cseUrlPrefix + "/query2?d=30&e=2", String.class);
+// TestMgr.check("Hello 20bobo40302", result);
+//
+// failed = false;
+// try {
+// result = template.getForObject(cseUrlPrefix + "/query3?a=2&b=2", String.class);
+// } catch (InvocationException e) {
+// failed = true;
+// TestMgr.check(e.getStatusCode(), HttpStatus.SC_BAD_REQUEST);
+// }
+// TestMgr.check(failed, true);
result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2", String.class);
TestMgr.check("Hello 302", result);
@@ -383,7 +484,27 @@ public class SpringmvcClient {
TestMgr.check("Hello 345302", result);
}
- private static void testSpringMvcDefaultValuesJavaPrimitive(RestTemplate template, String microserviceName) {
+ private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestTemplate template, String microserviceName) {
+ // TODO: WEAK primitive default value not supported in highway
+// String cseUrlPrefix = "cse://" + microserviceName + "/SpringMvcDefaultValues/";
+// //default values with primitive
+// String result = template.postForObject(cseUrlPrefix + "/javaprimitiveint", null, String.class);
+// TestMgr.check("Hello 0bobo", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivenumber", null, String.class);
+// TestMgr.check("Hello 0.0false", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivestr", null, String.class);
+// TestMgr.check("Hello", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb", null, String.class);
+// TestMgr.check("Hello nullnull", result);
+//
+// result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null, String.class);
+// TestMgr.check("Hello false,\0,0,0,0,0,0.0,0.0,null", result);
+ }
+
+ private static void testSpringMvcDefaultValuesJavaPrimitiveRest(RestTemplate template, String microserviceName) {
String cseUrlPrefix = "cse://" + microserviceName + "/SpringMvcDefaultValues/";
//default values with primitive
String result = template.postForObject(cseUrlPrefix + "/javaprimitiveint", null, String.class);
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
index dd83639..5e42db7 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
@@ -27,6 +27,7 @@ import javax.xml.ws.Holder;
import org.apache.servicecomb.demo.EmptyObject;
import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
import org.apache.servicecomb.provider.pojo.Invoker;
import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;
import org.springframework.web.client.RestTemplate;
@@ -45,6 +46,9 @@ public class TestObject {
public void runRest() {
testEmptyObject_rest();
testMapObject_rest();
+ testObject();
+ testListObject();
+ testHolderObject();
}
public void runHighway() {
@@ -53,9 +57,10 @@ public class TestObject {
}
public void runAllTransport() {
- testObject();
- testListObject();
- testHolderObject();
+ // TODO : WEAK not supported now in HIGHWAY
+// testObject();
+// testListObject();
+// testHolderObject();
}
@SuppressWarnings("unchecked")
@@ -97,21 +102,21 @@ public class TestObject {
Map<String, Object> map = Collections.singletonMap("k", "v");
Map<String, Object> result = intf.testMapObject(map);
TestMgr.check("{k=v}", result);
- TestMgr.check(HashMap.class, result.getClass());
+ // This is a behavior change in 2.0.0, before 2.0.0 runtime type of RAW is HashMap
+ TestMgr.check(LinkedHashMap.class, result.getClass());
result = restTemplate.postForObject(prefix + "/mapObject", map, Map.class);
TestMgr.check("{k=v}", result);
- TestMgr.check(HashMap.class, result.getClass());
+ TestMgr.check(LinkedHashMap.class, result.getClass());
}
private void testEmptyObject_highway() {
- // protobuf can not express empty/null
- // everything empty will be null
+ // This is a behavior change in 2.0.0, before 2.0.0 this return null
EmptyObject result = intf.testEmpty(new EmptyObject());
- TestMgr.check(null, result);
+ TestMgr.check(result instanceof EmptyObject, true);
result = restTemplate.postForObject(prefix + "/emptyObject", new EmptyObject(), EmptyObject.class);
- TestMgr.check(null, result);
+ TestMgr.check(result instanceof EmptyObject, true);
}
private void testEmptyObject_rest() {
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
index c7c2f8c..eb5968d 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
@@ -43,17 +43,21 @@ public class TestResponse {
testDelay();
testAbort();
testDecodeResponseError();
+ checkQueryObject();
+ testCseResponse();
+ testResponseEntity();
}
public void runHighway() {
}
public void runAllTransport() {
- testResponseEntity();
- testCseResponse();
testvoidResponse();
testVoidResponse();
- checkQueryObject();
+ // TODO : WEAK not supported now in HIGHWAY
+ // checkQueryObject();
+ // testCseResponse();
+ // testResponseEntity();
}
private void testCseResponse() {
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java
index 2e2925d..0e67baa 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestRestTemplate.java
@@ -34,12 +34,14 @@ public class TestRestTemplate {
testvoidResponse();
testVoidResponse();
checkAllVoidTestResult();
- checkQueryObject();
+ // TODO : WEAK not supported now in HIGHWAY
+ //checkQueryObject();
}
public void runRest() {
checkQueryGenericObject();
checkQueryGenericString();
+ checkQueryObject();
}
private void testvoidResponse() {
diff --git a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
index 8be0880..dcb8ae8 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-server/src/main/resources/microservice.yaml
@@ -47,7 +47,7 @@ servicecomb:
# can download config center from https://cse-bucket.obs.myhwclouds.com/LocalCSE/Local-CSE-1.0.0.zip to test dynamic config
config:
client:
- serverUri: http://127.0.0.1:30113
+ # serverUri: http://127.0.0.1:30113
refreshMode: 0
refresh_interval: 5000
refreshPort: 30114
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
index 2362655..1bb21e6 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
@@ -16,16 +16,12 @@
*/
package org.apache.servicecomb.foundation.protobuf;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
-import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptorManager;
-import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
import org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.DeserializerSchemaManager;
-import org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.RootPropertyWrapperDeserializer;
import org.apache.servicecomb.foundation.protobuf.internal.schema.serializer.SerializerSchemaManager;
import com.fasterxml.jackson.databind.JavaType;
@@ -121,6 +117,14 @@ public class ProtoMapper {
return createRootSerializer(message, type);
}
+ public synchronized RequestRootSerializer createRequestRootSerializer(Message message, Map<String, Type> types, boolean noTypesInfo) {
+ return serializerSchemaManager.createRequestRootSerializer(message, types, noTypesInfo);
+ }
+
+ public synchronized RootSerializer createRootSerializer(Message message, Map<String, Type> types) {
+ return serializerSchemaManager.createRootSerializer(message, types);
+ }
+
public synchronized RootSerializer createRootSerializer(Message message, Type type) {
return serializerSchemaManager.createRootSerializer(message, type);
}
@@ -134,26 +138,20 @@ public class ProtoMapper {
return createRootDeserializer(message, type);
}
- public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Type type, Method method) {
- return deserializerSchemaManager.createRootDeserializer(message, type, method);
+ public synchronized <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message,
+ Map<String, Type> types) {
+ return deserializerSchemaManager.createRequestRootDeserializer(message, types);
}
- public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {
- return deserializerSchemaManager.createRootDeserializer(message, type);
+ public synchronized <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Type type) {
+ return deserializerSchemaManager.createRequestRootDeserializer(message, type);
}
- public synchronized <T> RootDeserializer<T> createPropertyRootDeserializer(String shortMessageName,
- Type propertyType) {
- Message message = proto.getMessage(shortMessageName);
- if (!ProtoUtils.isWrapProperty(message)) {
- return createRootDeserializer(shortMessageName, propertyType);
- }
+ public synchronized <T> ResponseRootDeserializer<T> createResponseRootDeserializer(Message message, Type type) {
+ return deserializerSchemaManager.createResponseRootDeserializer(message, type);
+ }
- JavaType propertyWrapJavaType = TypeFactory.defaultInstance().constructParametricType(
- PropertyWrapper.class,
- TypeFactory.defaultInstance().constructType(propertyType));
- RootDeserializer<PropertyWrapper<T>> deserializer = deserializerSchemaManager
- .createRootDeserializer(message, propertyWrapJavaType);
- return new RootPropertyWrapperDeserializer<>(deserializer);
+ public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {
+ return deserializerSchemaManager.createRootDeserializer(message, type);
}
}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java
new file mode 100644
index 0000000..462fca2
--- /dev/null
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class RequestRootDeserializer<T> {
+ private boolean wrapArgument;
+
+ private String parameterName;
+
+ private RootDeserializer<T> rootDeserializer;
+
+ public RequestRootDeserializer(RootDeserializer<T> rootDeserializer) {
+ this(rootDeserializer, true, null);
+ }
+
+ public RequestRootDeserializer(RootDeserializer<T> rootDeserializer, boolean wrapArgument, String parameterName) {
+ this.rootDeserializer = rootDeserializer;
+ this.wrapArgument = wrapArgument;
+ this.parameterName = parameterName;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map<String, Object> deserialize(byte[] bytes) throws IOException {
+ if (!wrapArgument) {
+ if (parameterName == null) {
+ return null;
+ }
+ Map<String, Object> result = new HashMap<>(1);
+ result.put(parameterName, rootDeserializer.deserialize(bytes));
+ return result;
+ } else {
+ return (Map<String, Object>) rootDeserializer.deserialize(bytes);
+ }
+ }
+}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
new file mode 100644
index 0000000..f18fbf5
--- /dev/null
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+
+public class RequestRootSerializer {
+ private RootSerializer rootSerializer;
+
+ private boolean noTypesInfo;
+
+ private boolean isWrap;
+
+ public RequestRootSerializer(RootSerializer serializer, boolean isWrapp, boolean noTypesInfo) {
+ this.rootSerializer = serializer;
+ this.noTypesInfo = noTypesInfo;
+ this.isWrap = isWrapp;
+ }
+
+ @SuppressWarnings("unchecked")
+ public byte[] serialize(Object value) throws IOException {
+ if (noTypesInfo && !isWrap) {
+ return this.rootSerializer.serialize(((Map<String, Object>) value).values().iterator().next());
+ } else {
+ return this.rootSerializer.serialize(value);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void serialize(OutputStream outputStream, Object value) throws IOException {
+ if (noTypesInfo && !isWrap) {
+ this.rootSerializer.serialize(outputStream, ((Map<String, Object>) value).values().iterator().next());
+ } else {
+ this.rootSerializer.serialize(outputStream, value);
+ }
+ }
+}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java
new file mode 100644
index 0000000..b852725
--- /dev/null
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
+
+public class ResponseRootDeserializer<T> {
+ private boolean wrapProperty;
+
+ private RootDeserializer<T> rootDeserializer;
+
+ private boolean empty;
+
+ public ResponseRootDeserializer(RootDeserializer<T> rootDeserializer, boolean wrapProperty, boolean empty) {
+ this.rootDeserializer = rootDeserializer;
+ this.wrapProperty = wrapProperty;
+ this.empty = empty;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T deserialize(byte[] bytes) throws IOException {
+ if (empty) {
+ T a = rootDeserializer.deserialize(bytes); // read buffers if possible.
+ return null;
+ }
+
+ if (wrapProperty) {
+ return ((PropertyWrapper<T>) rootDeserializer.deserialize(bytes)).getValue();
+ } else {
+ return rootDeserializer.deserialize(bytes);
+ }
+ }
+}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoUtils.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoUtils.java
index 2afbe9d..55fcd30 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoUtils.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoUtils.java
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JavaType;
import io.protostuff.compiler.model.DynamicMessage;
import io.protostuff.compiler.model.Field;
import io.protostuff.compiler.model.FieldContainer;
+import io.protostuff.compiler.model.Message;
import io.protostuff.compiler.model.ScalarFieldType;
import io.protostuff.compiler.model.Type;
@@ -28,10 +29,18 @@ public final class ProtoUtils {
private ProtoUtils() {
}
+ public static boolean isEmptyMessage(Message protoField) {
+ return protoField.getCanonicalName().equals(ProtoConst.EMPTY.getCanonicalName());
+ }
+
public static boolean isAnyField(Field protoField) {
return protoField.getType().getCanonicalName().equals(ProtoConst.ANY.getCanonicalName());
}
+ public static boolean isWrapArguments(FieldContainer fieldContainer) {
+ return fieldContainer.getCommentLines().contains(ProtoConst.ANNOTATION_WRAP_ARGUMENTS);
+ }
+
public static boolean isWrapProperty(FieldContainer fieldContainer) {
return fieldContainer.getCommentLines().contains(ProtoConst.ANNOTATION_WRAP_PROPERTY);
}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
index 0b7e6ad..ca7b0e2 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
@@ -19,8 +19,7 @@ package org.apache.servicecomb.foundation.protobuf.internal.schema;
import static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isAnyField;
import static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -71,7 +70,7 @@ public abstract class SchemaManager {
protected abstract <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType);
- protected abstract <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType, Method method);
+ protected abstract <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types);
/**
*
@@ -82,12 +81,12 @@ public abstract class SchemaManager {
protected abstract <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor);
@SuppressWarnings("unchecked")
- protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message, JavaType javaType, Method method) {
- String cacheKey = generateCacheKey(message, javaType);
+ protected <T> SchemaEx<T> getOrCreateMessageSchema(Message message, Map<String, Type> types) {
+ String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);
SchemaEx<T> messageSchema = (SchemaEx<T>) canonicalSchemas.get(cacheKey);
if (messageSchema == null) {
// messageSchema already put into canonicalSchemas inside createMessageSchema
- messageSchema = createMessageSchema(message, javaType, method);
+ messageSchema = createMessageSchema(message, types);
}
return messageSchema;
}
@@ -108,14 +107,14 @@ public abstract class SchemaManager {
return (SchemaEx<T>) canonicalSchemas.get(key);
}
- protected <T> SchemaEx<T> createMessageSchema(Message message, JavaType javaType, Method method) {
- String cacheKey = generateCacheKey(message, javaType);
+ protected <T> SchemaEx<T> createMessageSchema(Message message, Map<String, Type> types) {
+ String cacheKey = generateCacheKey(message, ProtoConst.MAP_TYPE);
SchemaEx<T> schema = findSchema(cacheKey);
if (schema != null) {
return schema;
}
- schema = newMessageSchema(message, javaType, method);
+ schema = newMessageSchema(message, types);
canonicalSchemas.put(cacheKey, schema);
schema.init();
@@ -166,24 +165,18 @@ public abstract class SchemaManager {
return FieldMapEx.createFieldMap(fieldSchemas);
}
- public FieldMapEx<Map<Object, Object>> createMapFields(Message message, Method method) {
+ public FieldMapEx<Map<Object, Object>> createMapFields(Message message, Map<String, Type> types) {
List<FieldSchema<Map<Object, Object>>> fieldSchemas = new ArrayList<>();
for (Field protoField : message.getFields()) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor();
- JavaType javaType = ProtoConst.OBJECT_TYPE;
- if (method != null) {
- javaType = getParameterType(method, protoField.getName());
- if (javaType.isPrimitive()) {
- javaType = TypeFactory.defaultInstance().constructType(ClassUtils.primitiveToWrapper(javaType.getRawClass()));
- }
- propertyDescriptor.setJavaType(javaType);
- propertyDescriptor.setGetter(new MapGetter<>(protoField.getName()));
- propertyDescriptor.setSetter(new MapSetter<>(protoField.getName()));
- } else {
- propertyDescriptor.setJavaType(javaType);
- propertyDescriptor.setGetter(new MapGetter<>(protoField.getName()));
- propertyDescriptor.setSetter(new MapSetter<>(protoField.getName()));
+
+ JavaType javaType = getParameterType(types, protoField.getName());
+ if (javaType.isPrimitive()) {
+ javaType = TypeFactory.defaultInstance().constructType(ClassUtils.primitiveToWrapper(javaType.getRawClass()));
}
+ propertyDescriptor.setJavaType(javaType);
+ propertyDescriptor.setGetter(new MapGetter<>(protoField.getName()));
+ propertyDescriptor.setSetter(new MapSetter<>(protoField.getName()));
FieldSchema<Map<Object, Object>> fieldSchema = createSchemaField(protoField, propertyDescriptor);
fieldSchemas.add(fieldSchema);
@@ -192,15 +185,14 @@ public abstract class SchemaManager {
return FieldMapEx.createFieldMap(fieldSchemas);
}
- private JavaType getParameterType(Method method, String operationId) {
- for (Parameter parameter : method.getParameters()) {
- // TODO: add ApiOperation check
- if (operationId.equals(parameter.getName())) {
- return TypeFactory.defaultInstance().constructType(parameter.getParameterizedType());
- }
+ private JavaType getParameterType(Map<String, Type> types, String perameterName) {
+
+ if (types.get(perameterName) != null) {
+ return TypeFactory.defaultInstance().constructType(types.get(perameterName));
}
+
throw new IllegalArgumentException(
- String.format("not found operation id %s from method %s", operationId, method.getName()));
+ String.format("not found type info for parameter name [%s]", perameterName));
}
public <T> FieldSchema<T> createSchemaField(Field protoField, PropertyDescriptor propertyDescriptor) {
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
index 595e50a..60ee422 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
@@ -18,10 +18,12 @@ package org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer;
import static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import java.util.Map;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -93,10 +95,23 @@ public class DeserializerSchemaManager extends SchemaManager {
super(protoMapper);
}
- public <T> RootDeserializer<T> createRootDeserializer(Message message, Type type, Method method) {
+ public <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Type type) {
JavaType javaType = TypeFactory.defaultInstance().constructType(type);
- SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType, method);
- return new RootDeserializer<>(messageSchema);
+ SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType);
+ RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
+ return new RequestRootDeserializer<>(rootDeserializer);
+ }
+
+ public <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Map<String, Type> types) {
+ SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, types);
+ RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
+ if (!ProtoUtils.isWrapArguments(message)) {
+ if (types == null || types.size() == 0) {
+ return new RequestRootDeserializer<>(rootDeserializer, false, null);
+ }
+ return new RequestRootDeserializer<>(rootDeserializer, false, types.keySet().iterator().next());
+ }
+ return new RequestRootDeserializer<>(rootDeserializer);
}
public <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {
@@ -105,23 +120,17 @@ public class DeserializerSchemaManager extends SchemaManager {
return new RootDeserializer<>(messageSchema);
}
- @Override
- protected <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType, Method method) {
- if (ProtoUtils.isWrapProperty(message) && javaType.getRawClass() != PropertyWrapper.class) {
- Field protoField = message.getField(1);
- if (javaType.isJavaLangObject()) {
- javaType =
- protoField.isRepeated() && protoField.getType().isMessage() && !protoField.isMap() ? ProtoConst.LIST_TYPE
- : ProtoConst.MAP_TYPE;
- }
- javaType = TypeFactory.defaultInstance().constructParametricType(PropertyWrapper.class, javaType);
- }
-
- if (javaType.isJavaLangObject()) {
- javaType = ProtoConst.MAP_TYPE;
- }
+ public <T> ResponseRootDeserializer<T> createResponseRootDeserializer(Message message, Type type) {
+ JavaType javaType = TypeFactory.defaultInstance().constructType(type);
+ SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType);
+ RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
+ return new ResponseRootDeserializer<>(rootDeserializer, ProtoUtils.isWrapProperty(message),
+ ProtoUtils.isEmptyMessage(message));
+ }
- return new MessageReadSchema<>(protoMapper, message, javaType, method);
+ @Override
+ protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {
+ return new MessageReadSchema<>(protoMapper, message, types);
}
@Override
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
index 4877192..acdc01c 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
@@ -18,19 +18,21 @@
package org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer;
import java.io.IOException;
-import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
+import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;
import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
import io.protostuff.InputEx;
import io.protostuff.OutputEx;
@@ -60,27 +62,32 @@ public class MessageReadSchema<T> implements SchemaEx<T> {
private Instantiator<T> instantiator;
- private JavaType javaType;
+ private final JavaType javaType;
- private Method method;
+ private final Map<String, Type> types;
@SuppressWarnings("unchecked")
- public MessageReadSchema(ProtoMapper protoMapper, Message message, JavaType javaType, Method method) {
+ // construct for request parameters
+ public MessageReadSchema(ProtoMapper protoMapper, Message message, Map<String, Type> types) {
this.protoMapper = protoMapper;
this.message = message;
- this.javaType = javaType;
- this.method = method;
- if (javaType.isJavaLangObject() || Map.class.isAssignableFrom(javaType.getRawClass())) {
- javaType = ProtoConst.MAP_TYPE;
+ this.types = types;
+ if (!ProtoUtils.isWrapArguments(message) && types.size() > 0) {
+ this.javaType = TypeFactory.defaultInstance().constructType(types.values().iterator().next());
+ this.instantiator = RuntimeEnv.newInstantiator((Class<T>) javaType.getRawClass());
+ } else {
+ this.javaType = ProtoConst.MAP_TYPE;
+ this.instantiator = RuntimeEnv.newInstantiator((Class<T>) ProtoConst.MAP_TYPE.getRawClass());
}
- this.instantiator = RuntimeEnv.newInstantiator((Class<T>) javaType.getRawClass());
}
@SuppressWarnings("unchecked")
+ // construct for response type
public MessageReadSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {
this.protoMapper = protoMapper;
this.message = message;
this.javaType = javaType;
+ this.types = null;
if (javaType.isJavaLangObject() || Map.class.isAssignableFrom(javaType.getRawClass())) {
javaType = ProtoConst.MAP_TYPE;
}
@@ -108,14 +115,13 @@ public class MessageReadSchema<T> implements SchemaEx<T> {
@SuppressWarnings("unchecked")
@Override
public void init() {
- if (Map.class.isAssignableFrom(javaType.getRawClass())) {
- if (this.method == null) {
- this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()
- .createMapFields(message);
- } else {
+ if (types != null) {
+ if (ProtoUtils.isWrapArguments(message)) {
this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()
- .createMapFields(message, method);
+ .createMapFields(message, types);
+ return;
}
+ this.createFieldMap();
return;
}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
index 24717a2..5adb200 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
@@ -27,11 +27,13 @@ import java.util.Map.Entry;
import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;
import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
import io.protostuff.InputEx;
import io.protostuff.OutputEx;
@@ -53,7 +55,9 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
protected Message message;
- private JavaType javaType;
+ private final JavaType javaType;
+
+ private final Map<String, Type> types;
// mostly, one message only relate to one pojo
private final Class<T> mainPojoCls;
@@ -66,10 +70,24 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
private final Map<Class<?>, FieldMapEx<?>> pojoFieldMaps = new ConcurrentHashMapEx<>();
@SuppressWarnings("unchecked")
+ public MessageWriteSchema(ProtoMapper protoMapper, Message message, Map<String, Type> types) {
+ this.protoMapper = protoMapper;
+ this.message = message;
+ this.types = types;
+ if (this.types == null || this.types.isEmpty()) {
+ this.javaType = ProtoConst.MAP_TYPE;
+ } else {
+ this.javaType = TypeFactory.defaultInstance().constructType(types.values().iterator().next());
+ }
+ this.mainPojoCls = (Class<T>) javaType.getRawClass();
+ }
+
+ @SuppressWarnings("unchecked")
public MessageWriteSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {
this.protoMapper = protoMapper;
this.message = message;
this.javaType = javaType;
+ this.types = null;
this.mainPojoCls = (Class<T>) javaType.getRawClass();
}
@@ -101,12 +119,24 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
@Override
public void init() {
+ if (types != null && !types.isEmpty()) {
+ if (ProtoUtils.isWrapProperty(message)) {
+ this.mapFieldMaps = protoMapper.getDeserializerSchemaManager()
+ .createMapFields(message, types);
+ return;
+ }
+ this.mainPojoFieldMaps = createPojoFields(javaType);
+ this.mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
+ return;
+ }
+
if (ProtoUtils.isWrapProperty(message)) {
this.mainPojoFieldMaps = createPropertyWrapperFields(javaType);
return;
}
this.mainPojoFieldMaps = createPojoFields(javaType);
+ this.mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
}
private FieldMapEx<T> createPropertyWrapperFields(JavaType javaType) {
@@ -147,6 +177,16 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
@SuppressWarnings("unchecked")
@Override
public void writeTo(OutputEx output, Object value) throws IOException {
+ if (types != null && !types.isEmpty()) {
+ if (ProtoUtils.isWrapArguments(message)) {
+ writeFromMap(output, (Map<String, Object>) value);
+ return;
+ } else {
+ value = ((Map<String, Object>) value).values().iterator().next();
+ }
+ }
+
+ // write a POJO from map
if (value instanceof Map) {
writeFromMap(output, (Map<String, Object>) value);
return;
@@ -178,10 +218,6 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
}
protected final void writeFromMap(OutputEx output, Map<String, Object> map) throws IOException {
- if (mapFieldMaps == null) {
- mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
- }
-
for (Entry<String, Object> entry : map.entrySet()) {
if (entry.getValue() == null) {
continue;
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
index d205bfc..838d92f 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
@@ -18,10 +18,11 @@ package org.apache.servicecomb.foundation.protobuf.internal.schema.serializer;
import static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isWrapProperty;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
+import java.util.Map;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -92,6 +93,21 @@ public class SerializerSchemaManager extends SchemaManager {
super(protoMapper);
}
+ public RequestRootSerializer createRequestRootSerializer(Message message, Map<String, Type> types,
+ boolean noTypesInfo) {
+ SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, types);
+
+ RootSerializer rootSerializer = new RootSerializer(messageSchema);
+ return new RequestRootSerializer(rootSerializer,
+ ProtoUtils.isWrapArguments(message) || ProtoUtils.isEmptyMessage(message), noTypesInfo);
+ }
+
+ public RootSerializer createRootSerializer(Message message, Map<String, Type> types) {
+ SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, types);
+
+ return new RootSerializer(messageSchema);
+ }
+
public RootSerializer createRootSerializer(Message message, Type type) {
JavaType javaType = TypeFactory.defaultInstance().constructType(type);
SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, javaType);
@@ -109,8 +125,8 @@ public class SerializerSchemaManager extends SchemaManager {
}
@Override
- protected <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType, Method method) {
- return newMessageSchema(message, javaType);
+ protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {
+ return new MessageWriteSchema<>(protoMapper, message, types);
}
protected <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor) {
diff --git a/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestMethodWrap.java b/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestMethodWrap.java
deleted file mode 100644
index b359706..0000000
--- a/foundations/foundation-protobuf/src/test/java/org/apache/servicecomb/foundation/protobuf/internal/TestMethodWrap.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.internal;
-
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.ProtoMapperFactory;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
-import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.fasterxml.jackson.databind.type.TypeFactory;
-
-public class TestMethodWrap {
- protected static ProtoMapperFactory factory = new ProtoMapperFactory();
-
- protected static ProtoMapper methodProtoMapper = factory.createFromName("method.proto");
-
- @Test
- public void arguments() throws IOException {
- // serialize
-// RootSerializer argumentsSerializer = methodProtoMapper
-// .createArgumentsRootSerializer("RequestWrap", boolean.class, Integer[].class);
-// RootSerializer protoSerializer = methodProtoMapper.createRootSerializer("Request", Map.class);
-//
-// Integer[] intArr = new Integer[] {1, 2};
-//
-// Map<String, Object> request = new LinkedHashMap<>();
-// request.put("boolValue", true);
-// request.put("iArr", intArr);
-// byte[] bytes = protoSerializer.serialize(request);
-//
-// Assert.assertArrayEquals(bytes, argumentsSerializer.serialize(new Object[] {true, intArr}));
-
- // deserialize
-// Object[] arguments = methodProtoMapper
-// .createArgumentsRootDeserializer(
-// "RequestWrap",
-// boolean.class,
-// TypeFactory.defaultInstance().constructParametricType(List.class, Integer.class))
-// .deserialize(bytes);
-// Assert.assertTrue((Boolean) arguments[0]);
-// Assert.assertEquals(Arrays.asList(intArr), arguments[1]);
- }
-
- @Test
- public void response() throws IOException {
- Type type = TypeFactory.defaultInstance().constructCollectionType(List.class, Integer.class);
- // serialize
- RootSerializer responseSerializer = methodProtoMapper.createRootSerializer("ResponseWrap", type);
- RootSerializer protoSerializer = methodProtoMapper.createRootSerializer("Response", PropertyWrapper.class);
-
- List<Integer> list = Arrays.asList(1, 2);
-
- Map<String, Object> response = new HashMap<>();
- response.put("value", list);
- byte[] bytes = protoSerializer.serialize(response);
-
- Assert.assertArrayEquals(bytes, responseSerializer.serialize(list));
-
- @SuppressWarnings("unchecked")
- PropertyWrapper<Object> propertyWrapper = (PropertyWrapper<Object>) methodProtoMapper
- .createRootDeserializer("Response", PropertyWrapper.class)
- .deserialize(bytes);
- Assert.assertEquals(list, propertyWrapper.getValue());
-
- Assert.assertEquals(list,
- methodProtoMapper.createPropertyRootDeserializer("ResponseWrap", type).deserialize(bytes));
- }
-}
diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java
index c186381..d89e8f0 100644
--- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java
+++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/server/TcpParser.java
@@ -32,6 +32,8 @@ import io.vertx.core.parsetools.RecordParser;
public class TcpParser implements Handler<Buffer> {
public static final byte[] TCP_MAGIC;
+ public static final int TCP_MAX_REQUEST_LENGTH = 20 * 1024 * 1024;
+
public static final int TCP_HEADER_LENGTH = 23;
static {
@@ -100,6 +102,9 @@ public class TcpParser implements Handler<Buffer> {
msgId = buf.readLong();
totalLen = buf.readInt();
headerLen = buf.readInt();
+ if (headerLen > totalLen || headerLen <= 0 || totalLen > TCP_MAX_REQUEST_LENGTH) {
+ throw new IllegalStateException("possibly attack.");
+ }
if (totalLen == 0) {
onReadOnePackage(null, null);
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
index 536fb37..56d13b6 100644
--- a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
@@ -23,6 +23,7 @@ import java.lang.reflect.Type;
import javax.servlet.http.Part;
import javax.ws.rs.core.Response.Status;
+import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;
import org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;
@@ -49,6 +50,7 @@ public class PojoConsumerOperationMeta {
this.swaggerConsumerOperation = swaggerConsumerOperation;
operationMeta.getResponsesMeta().cloneTo(responsesMeta);
+ operationMeta.putExtData(Const.CONSUMER_OPERATION, swaggerConsumerOperation);
responsesMeta.init(intfSwagger, intfOperation);
Type intfResponseType = swaggerConsumerOperation.getConsumerMethod().getGenericReturnType();
if (intfResponseType instanceof Class && Part.class.isAssignableFrom((Class<?>) intfResponseType)) {
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
index 5301868..47a5994 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
@@ -63,6 +63,10 @@ public class SwaggerInvocation extends InvocationContext {
}
public void setSwaggerArgument(int idx, Object swaggerArgument) {
+ if(swaggerArguments == null) {
+ // not request parameters. e.g. void test()
+ return;
+ }
this.swaggerArguments[idx] = swaggerArgument;
}
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPackage.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPackage.java
index df27f81..d1e14e4 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPackage.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClientPackage.java
@@ -20,8 +20,12 @@ import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.vertx.client.tcp.AbstractTcpClientPackage;
import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class HighwayClientPackage extends AbstractTcpClientPackage {
+ private static final Logger LOGGER = LoggerFactory.getLogger(HighwayClientPackage.class);
+
private Invocation invocation;
private OperationProtobuf operationProtobuf;
@@ -40,6 +44,7 @@ public class HighwayClientPackage extends AbstractTcpClientPackage {
String msg = String.format("encode request failed. appid=%s, qualifiedName=%s",
invocation.getAppId(),
invocation.getOperationMeta().getMicroserviceQualifiedName());
+ LOGGER.error(msg, e);
throw new Error(msg, e);
}
}
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 dc09c3f..b8ca139 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
@@ -21,6 +21,8 @@ import java.util.Map;
import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.vertx.client.tcp.TcpData;
@@ -54,13 +56,9 @@ public final class HighwayCodec {
@SuppressWarnings({"rawtypes", "unchecked"})
public static void decodeRequest(Invocation invocation, RequestHeader header, OperationProtobuf operationProtobuf,
Buffer bodyBuffer) throws Exception {
- RootDeserializer<Object> schema = operationProtobuf.findRequestDesirializer();
- Object args = schema.deserialize(bodyBuffer.getBytes());
- if (args instanceof Map) {
- invocation.setArguments((Map<String, Object>) args);
- } else {
- invocation.setSwaggerArgument(0, args);
- }
+ RequestRootDeserializer<Object> requestDesirializer = operationProtobuf.findRequestDesirializer();
+ Map<String, Object> args = requestDesirializer.deserialize(bodyBuffer.getBytes());
+ invocation.setArguments(args);
invocation.mergeContext(header.getContext());
}
@@ -83,7 +81,7 @@ public final class HighwayCodec {
invocation.getContext().putAll(header.getContext());
}
- RootDeserializer<Object> bodySchema = operationProtobuf.findResponseDesirialize(header.getStatusCode());
+ ResponseRootDeserializer<Object> bodySchema = operationProtobuf.findResponseDesirialize(header.getStatusCode());
Object body = bodySchema.deserialize(tcpData.getBodyBuffer().getBytes());
Response response = Response.create(header.getStatusCode(), header.getReasonPhrase(), body);
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
index 0535eb1..815796e 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
@@ -16,19 +16,21 @@
*/
package org.apache.servicecomb.transport.highway;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
import org.apache.servicecomb.transport.highway.message.RequestHeader;
import org.apache.servicecomb.transport.highway.message.ResponseHeader;
-import io.protostuff.LinkedBuffer;
-import io.protostuff.ProtobufOutput;
-
public class HighwayOutputStream extends TcpOutputStream {
public HighwayOutputStream(long msgId) {
super(msgId);
}
+ public void write(RequestHeader header, RequestRootSerializer requestRootSerializer, Object body) throws Exception {
+ write(RequestHeader.getRootSerializer().serialize(header), requestRootSerializer.serialize(body));
+ }
+
public void write(RequestHeader header, RootSerializer bodySchema, Object body) throws Exception {
write(RequestHeader.getRootSerializer(), header, bodySchema, body);
}
@@ -39,19 +41,39 @@ public class HighwayOutputStream extends TcpOutputStream {
public void write(RootSerializer headerSchema, Object header, RootSerializer bodySchema, Object body)
throws Exception {
- // 写protobuf数据
- LinkedBuffer linkedBuffer = LinkedBuffer.allocate();
- ProtobufOutput output = new ProtobufOutput(linkedBuffer);
+ byte[] headerBytes = new byte[0];
+ byte[] bodyBytes = new byte[0];
// 写header
if (headerSchema != null) {
- headerSchema.serialize(this, header);
+ headerBytes = headerSchema.serialize(header);
}
// 写body
// void时bodySchema为null
if (bodySchema != null) {
- bodySchema.serialize(this, body);
+ bodyBytes = bodySchema.serialize(body);
+ }
+
+ write(headerBytes, bodyBytes);
+ }
+
+ private void write(byte[] headerBytes, byte[] bodyBytes)
+ throws Exception {
+ int headerLength = 0;
+ int totalLength = 0;
+
+ if (headerBytes != null) {
+ headerLength = headerBytes.length;
+ totalLength = totalLength + headerLength;
}
+
+ if (bodyBytes != null) {
+ totalLength = totalLength + bodyBytes.length;
+ }
+
+ this.writeLength(totalLength, headerLength);
+ this.write(headerBytes);
+ this.write(bodyBytes);
}
}
diff --git a/transports/transport-highway/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport b/transports/transport-highway/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport
index 3b28c76..3e91266 100644
--- a/transports/transport-highway/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport
+++ b/transports/transport-highway/src/main/resources/META-INF/services/org.apache.servicecomb.core.Transport
@@ -16,4 +16,4 @@
#
# TODO: turn on highway transport
-# org.apache.servicecomb.transport.highway.HighwayTransport
+org.apache.servicecomb.transport.highway.HighwayTransport
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
index 5142620..16d8c2d 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
@@ -18,12 +18,15 @@
package org.apache.servicecomb.transport.highway;
import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.vertx.server.TcpParser;
import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
@@ -51,7 +54,7 @@ public class TestHighwayCodec {
private Buffer bodyBuffer = null;
- private RootSerializer requestSerializer = null;
+ private RequestRootSerializer requestSerializer = null;
private SchemaMeta schemaMeta = null;
@@ -80,7 +83,7 @@ public class TestHighwayCodec {
bodyBuffer = Mockito.mock(Buffer.class);
- requestSerializer = Mockito.mock(RootSerializer.class);
+ requestSerializer = Mockito.mock(RequestRootSerializer.class);
schemaMeta = Mockito.mock(SchemaMeta.class);
@@ -183,8 +186,11 @@ public class TestHighwayCodec {
RootSerializer bodySchema = Mockito.mock(RootSerializer.class);
try {
commonMock();
- HighwayCodec.encodeResponse(23432142, null, bodySchema, new Object());
+ Object data = new Object();
+ Mockito.when(bodySchema.serialize(data)).thenReturn(new byte[0]);
+ HighwayCodec.encodeResponse(23432142, null, bodySchema, data);
} catch (Exception e) {
+ e.printStackTrace();
status = false;
}
Assert.assertTrue(status);
@@ -195,10 +201,14 @@ public class TestHighwayCodec {
boolean status = true;
try {
commonMock();
+ Map<String, Object> args = new HashMap<>(0);
+ Mockito.when(invocation.getArguments()).thenReturn(args);
+ Mockito.when(requestSerializer.serialize(args)).thenReturn(new byte[0]);
TcpOutputStream os = HighwayCodec.encodeRequest(0, invocation, operationProtobuf);
Assert.assertNotNull(os);
Assert.assertArrayEquals(TcpParser.TCP_MAGIC, os.getBuffer().getBytes(0, 7));
} catch (Exception e) {
+ e.printStackTrace();
status = false;
}
Assert.assertTrue(status);
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
index 6c27df9..f9c04a3 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
@@ -24,6 +24,7 @@ import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
@@ -103,7 +104,7 @@ public class TestHighwayTransport {
Mockito.when(operationMeta.getExtData("protobuf")).thenReturn(operationProtobuf);
Endpoint lEndpoint = Mockito.mock(Endpoint.class);
Mockito.when(invocation.getEndpoint()).thenReturn(lEndpoint);
- RootSerializer lWrapSchema = Mockito.mock(RootSerializer.class);
+ RequestRootSerializer lWrapSchema = Mockito.mock(RequestRootSerializer.class);
Mockito.when(operationProtobuf.findRequestSerializer()).thenReturn(lWrapSchema);
URIEndpointObject ep = Mockito.mock(URIEndpointObject.class);
Mockito.when(lEndpoint.getAddress()).thenReturn(ep);