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/04/21 03:05:00 UTC
[servicecomb-java-chassis] branch master updated: [SCB-1869]
highway should use consumer type to avoid deserialization convertion
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new abcae31 [SCB-1869] highway should use consumer type to avoid deserialization convertion
abcae31 is described below
commit abcae3142c69b54cf8d2ce9235ea51f49959bf23
Author: liubao <bi...@qq.com>
AuthorDate: Mon Apr 20 15:36:22 2020 +0800
[SCB-1869] highway should use consumer type to avoid deserialization convertion
---
.../protobuf/definition/OperationProtobuf.java | 159 +++++++++++----------
.../codec/protobuf/definition/ProtobufManager.java | 79 +++++++++-
.../internal/converter/TestSchemaMetaCodec.java | 99 +++++++++----
.../converter/TestSchemaMetaCodecRestTemplate.java | 60 +++++++-
.../org/apache/servicecomb/core/Invocation.java | 4 +
.../foundation/common/utils/RestObjectMapper.java | 2 +-
.../foundation/common/utils/TypesUtil.java | 130 +++++++++++++++++
.../foundation/common/utils/TestTypesUtil.java | 32 +++++
.../deserializer/DeserializerSchemaManager.java | 10 +-
.../transport/highway/HighwayClient.java | 2 +-
.../transport/highway/HighwayCodec.java | 12 +-
.../transport/highway/HighwayServerInvoke.java | 17 ++-
.../transport/highway/TestHighwayClient.java | 2 +-
.../transport/highway/TestHighwayCodec.java | 2 +-
14 files changed, 477 insertions(+), 133 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 9d12a9b..2f0579f 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
@@ -25,7 +25,7 @@ import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.Response.Status.Family;
import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
-import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -36,8 +36,6 @@ import io.protostuff.compiler.model.Message;
@SuppressWarnings("rawtypes")
public class OperationProtobuf {
- private OperationMeta operationMeta;
-
private RequestRootSerializer requestRootSerializer;
private RequestRootDeserializer<Object> requestRootDeserializer;
@@ -50,10 +48,9 @@ public class OperationProtobuf {
private ResponseRootDeserializer<Object> anyResponseRootDeserializer;
- public OperationProtobuf(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
- this.operationMeta = operationMeta;
- initRequestCodec(scopedProtobufSchemaManager, operationMeta);
- initResponseCodec(scopedProtobufSchemaManager, operationMeta);
+ public OperationProtobuf(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {
+ initRequestCodec(scopedProtobufSchemaManager, invocation);
+ initResponseCodec(scopedProtobufSchemaManager, invocation);
}
public RequestRootSerializer getRequestRootSerializer() {
@@ -78,90 +75,104 @@ public class OperationProtobuf {
return anyResponseRootDeserializer;
}
- public OperationMeta getOperationMeta() {
- return operationMeta;
- }
-
- private void initRequestCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
- ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
- Message requestMessage = mapper.getRequestMessage(operationMeta.getOperationId());
-
- if (operationMeta.getSwaggerProducerOperation() != null) {
- Map<String, Type> swaggerParameterTypes = operationMeta.getSwaggerProducerOperation()
- .getSwaggerParameterTypes();
- if (ProtoUtils.isWrapArguments(requestMessage)) {
+ private void initProducerRequestCodec(Invocation invocation, Message requestMessage, ProtoMapper mapper) {
+ Map<String, Type> swaggerParameterTypes = invocation.getOperationMeta().getSwaggerProducerOperation()
+ .getSwaggerParameterTypes();
+ if (ProtoUtils.isWrapArguments(requestMessage)) {
+ requestRootDeserializer = new RequestRootDeserializer<>(
+ mapper.createRootDeserializer(requestMessage, swaggerParameterTypes), true, null);
+ } else {
+ if (swaggerParameterTypes.isEmpty()) {
requestRootDeserializer = new RequestRootDeserializer<>(
- mapper.createRootDeserializer(requestMessage, swaggerParameterTypes), true, null);
+ mapper.createRootDeserializer(requestMessage, Object.class), false, null);
+ } else if (swaggerParameterTypes.size() == 1) {
+ Entry<String, Type> entry = swaggerParameterTypes.entrySet().iterator().next();
+ requestRootDeserializer = new RequestRootDeserializer<>(mapper.createRootDeserializer(requestMessage,
+ entry.getValue()), false, entry.getKey());
} else {
- if (swaggerParameterTypes.isEmpty()) {
- requestRootDeserializer = new RequestRootDeserializer<>(
- mapper.createRootDeserializer(requestMessage, Object.class), false, null);
- } else if (swaggerParameterTypes.size() == 1) {
- Entry<String, Type> entry = swaggerParameterTypes.entrySet().iterator().next();
- requestRootDeserializer = new RequestRootDeserializer<>(mapper.createRootDeserializer(requestMessage,
- entry.getValue()), false, entry.getKey());
- } else {
- throw new IllegalStateException(
- "unexpected operation definition " + operationMeta.getMicroserviceQualifiedName());
- }
+ throw new IllegalStateException(
+ "unexpected operation definition " + invocation.getOperationMeta().getMicroserviceQualifiedName());
}
+ }
+ }
+
+ private void initConsumerRequestCodec(Invocation invocation, Message requestMessage, ProtoMapper mapper) {
+ if (ProtoUtils.isWrapArguments(requestMessage)) {
+ requestRootSerializer = new RequestRootSerializer(
+ mapper.createRootSerializer(requestMessage, Object.class), true, false);
} else {
- if (ProtoUtils.isWrapArguments(requestMessage)) {
- requestRootSerializer = new RequestRootSerializer(
- mapper.createRootSerializer(requestMessage, Object.class), true, false);
+ if (invocation.getOperationMeta().getSwaggerOperation().getParameters().isEmpty()) {
+ requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage, Object.class),
+ false, false);
+ } else if (invocation.getOperationMeta().getSwaggerOperation().getParameters().size() == 1) {
+ requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage,
+ Object.class), false, true);
} else {
- if (operationMeta.getSwaggerOperation().getParameters().isEmpty()) {
- requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage, Object.class),
- false, false);
- } else if (operationMeta.getSwaggerOperation().getParameters().size() == 1) {
- requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage,
- Object.class), false, true);
- } else {
- throw new IllegalStateException(
- "unexpected operation definition " + operationMeta.getMicroserviceQualifiedName());
- }
+ throw new IllegalStateException(
+ "unexpected operation definition " + invocation.getOperationMeta().getMicroserviceQualifiedName());
}
}
}
- private void initResponseCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
- ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
- Message responseMessage = mapper.getResponseMessage(operationMeta.getOperationId());
+ private void initRequestCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {
+ ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(invocation.getSchemaMeta());
+ Message requestMessage = mapper.getRequestMessage(invocation.getOperationMeta().getOperationId());
+
+ if (!invocation.isConsumer()) {
+ initProducerRequestCodec(invocation, requestMessage, mapper);
+ } else {
+ initConsumerRequestCodec(invocation, requestMessage, mapper);
+ }
+ }
- JavaType responseType = operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode());
- if (operationMeta.getSwaggerProducerOperation() != null) {
- if (ProtoUtils.isWrapProperty(responseMessage)) {
- responseRootSerializer = new ResponseRootSerializer(
- mapper.createRootSerializer(responseMessage, responseType), true, false);
+ private void initProviderResponseCode(Message responseMessage, ProtoMapper mapper,
+ JavaType responseType) {
+ if (ProtoUtils.isWrapProperty(responseMessage)) {
+ responseRootSerializer = new ResponseRootSerializer(
+ mapper.createRootSerializer(responseMessage, responseType), true, false);
+ } else {
+ if (ProtoUtils.isEmptyMessage(responseMessage)) {
+ responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+ Object.class), false, false);
} else {
- if (ProtoUtils.isEmptyMessage(responseMessage)) {
- responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
- Object.class), false, false);
- } else {
- responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
- responseType), false, true);
- }
+ responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+ responseType), false, true);
}
+ }
+ }
+
+ private void initConsumerResponseCode(Message responseMessage, ProtoMapper mapper,
+ JavaType responseType) {
+ if (ProtoUtils.isWrapProperty(responseMessage)) {
+ responseRootSerializer = new ResponseRootSerializer(
+ mapper.createRootSerializer(responseMessage, responseType), true, false);
+ responseRootDeserializer = new ResponseRootDeserializer<>(
+ mapper.createRootDeserializer(responseMessage, responseType), false);
} else {
- if (ProtoUtils.isWrapProperty(responseMessage)) {
- responseRootSerializer = new ResponseRootSerializer(
- mapper.createRootSerializer(responseMessage, responseType), true, false);
+ if (ProtoUtils.isEmptyMessage(responseMessage)) {
+ responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+ Object.class), false, false);
responseRootDeserializer = new ResponseRootDeserializer<>(
- mapper.createRootDeserializer(responseMessage, responseType), false);
+ mapper.createRootDeserializer(responseMessage, Object.class), true);
} else {
- if (ProtoUtils.isEmptyMessage(responseMessage)) {
- responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
- Object.class), false, false);
- responseRootDeserializer = new ResponseRootDeserializer<>(
- mapper.createRootDeserializer(responseMessage, Object.class), true);
- } else {
- responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
- responseType), false, false);
- responseRootDeserializer = new ResponseRootDeserializer<>(
- mapper.createRootDeserializer(responseMessage, responseType), false);
- }
+ responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+ responseType), false, false);
+ responseRootDeserializer = new ResponseRootDeserializer<>(
+ mapper.createRootDeserializer(responseMessage, responseType), false);
}
}
+ }
+
+ private void initResponseCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, Invocation invocation) {
+ ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(invocation.getSchemaMeta());
+ Message responseMessage = mapper.getResponseMessage(invocation.getOperationMeta().getOperationId());
+
+ JavaType responseType = invocation.findResponseType(Status.OK.getStatusCode());
+ if (!invocation.isConsumer()) {
+ initProviderResponseCode(responseMessage, mapper, responseType);
+ } else {
+ initConsumerResponseCode(responseMessage, mapper, responseType);
+ }
anyResponseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(ProtoConst.ANY,
Object.class), false, true);
anyResponseRootDeserializer = new ResponseRootDeserializer<>(
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
index 86ef301..f0b0fd2 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ProtobufManager.java
@@ -17,34 +17,99 @@
package org.apache.servicecomb.codec.protobuf.definition;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
+import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
-import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.swagger.invocation.InvocationType;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.google.common.annotations.VisibleForTesting;
public final class ProtobufManager {
public static final String EXT_ID = "protobuf";
private static final Object LOCK = new Object();
- public static OperationProtobuf getOrCreateOperation(OperationMeta operationMeta) {
- OperationProtobuf operationProtobuf = operationMeta.getExtData(EXT_ID);
+ static class RuntimeCacheKey {
+ final InvocationType invocationType;
+
+ final String uniqueOperationId;
+
+ // Using response type as the cache key.
+ // May consider request type as well, but now not implemented
+ final JavaType responseType;
+
+ public RuntimeCacheKey(InvocationType invocationType, String operationId, JavaType responseType) {
+ this.invocationType = invocationType;
+ this.uniqueOperationId = operationId;
+ this.responseType = responseType;
+ }
+
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ RuntimeCacheKey that = (RuntimeCacheKey) o;
+
+ if (invocationType != that.invocationType) {
+ return false;
+ }
+ if (!uniqueOperationId.equals(that.uniqueOperationId)) {
+ return false;
+ }
+ return responseType != null ? responseType.equals(that.responseType)
+ : that.responseType == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = invocationType.hashCode();
+ result = 31 * result + uniqueOperationId.hashCode();
+ result = 31 * result + (responseType != null ? responseType.hashCode() : 0);
+ return result;
+ }
+ }
+
+ private static final Map<RuntimeCacheKey, OperationProtobuf> RUNTIME_CACHE = new HashMap<>();
+
+ public static OperationProtobuf getOrCreateOperation(Invocation invocation) {
+ RuntimeCacheKey cacheKey = new RuntimeCacheKey(invocation.getInvocationType(),
+ invocation.getOperationMeta().getMicroserviceQualifiedName(),
+ invocation.findResponseType(Status.OK.getStatusCode()));
+ OperationProtobuf operationProtobuf = RUNTIME_CACHE.get(cacheKey);
if (operationProtobuf == null) {
synchronized (LOCK) {
- MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();
+ MicroserviceMeta microserviceMeta = invocation.getMicroserviceMeta();
ScopedProtobufSchemaManager scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);
if (scopedProtobufSchemaManager == null) {
scopedProtobufSchemaManager = new ScopedProtobufSchemaManager();
microserviceMeta.putExtData(EXT_ID, scopedProtobufSchemaManager);
}
- operationProtobuf = operationMeta.getExtData(EXT_ID);
+ operationProtobuf = RUNTIME_CACHE.get(cacheKey);
if (operationProtobuf == null) {
- operationProtobuf = new OperationProtobuf(scopedProtobufSchemaManager, operationMeta);
- operationMeta.putExtData(EXT_ID, operationProtobuf);
+ operationProtobuf = new OperationProtobuf(scopedProtobufSchemaManager, invocation);
+ RUNTIME_CACHE.put(cacheKey, operationProtobuf);
}
}
}
return operationProtobuf;
}
+
+ @VisibleForTesting
+ public static void clear() {
+ RUNTIME_CACHE.clear();
+ }
}
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 2fd0ec0..822d4d8 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
@@ -34,6 +34,8 @@ import org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer
import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchemaPojo;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.InvocationRuntimeType;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
@@ -48,9 +50,11 @@ import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
import org.apache.servicecomb.swagger.generator.core.AbstractSwaggerGenerator;
import org.apache.servicecomb.swagger.generator.pojo.PojoSwaggerGenerator;
import org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGenerator;
+import org.apache.servicecomb.swagger.invocation.InvocationType;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -75,10 +79,11 @@ public class TestSchemaMetaCodec {
@Before
public void setUp() {
-
+ ProtobufManager.clear();
}
- private void mockSchemaMeta(AbstractSwaggerGenerator swaggerGenerator, Object producerInstance) throws Exception {
+ private void mockSchemaMeta(String schemaId, AbstractSwaggerGenerator swaggerGenerator, Object producerInstance)
+ throws Exception {
new Expectations() {
{
providerMicroserviceMeta.getMicroserviceName();
@@ -94,33 +99,67 @@ public class TestSchemaMetaCodec {
Swagger swagger = swaggerGenerator.generate();
SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
- providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, "ProtoSchema", swagger);
+ providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, schemaId, swagger);
SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(producerInstance, swagger);
for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());
operationMeta.setSwaggerProducerOperation(producerOperation);
}
- consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, "ProtoSchema", swagger);
+ consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, schemaId, swagger);
}
@Test
public void testProtoSchemaOperationUserSpringMVC() throws Exception {
- mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+ mockSchemaMeta("ProtoSchema", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
testProtoSchemaOperationUserImpl();
}
@Test
public void testProtoSchemaOperationUserPOJO() throws Exception {
- mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+ mockSchemaMeta("ProtoSchemaPojo", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
testProtoSchemaOperationUserImpl();
}
+ private Invocation mockInvocation(String operation, InvocationType invocationType) {
+ OperationMeta operationMeta;
+ boolean isConsumer;
+ Invocation invocation = Mockito.mock(Invocation.class);
+ InvocationRuntimeType invocationRuntimeType;
+
+ if (InvocationType.CONSUMER == invocationType) {
+ operationMeta = consumerSchemaMeta.getOperations().get(operation);
+ isConsumer = true;
+ Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);
+ invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();
+ } else {
+ operationMeta = providerSchemaMeta.getOperations().get(operation);
+ isConsumer = false;
+ Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);
+ invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();
+ }
+
+ MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();
+ Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ Mockito.when(invocation.getInvocationRuntimeType())
+ .thenReturn(invocationRuntimeType);
+ Mockito.when(invocation.findResponseType(200))
+ .thenReturn(invocationRuntimeType.findResponseType(200));
+ Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);
+ Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);
+
+ Mockito.when(invocation.isConsumer()).thenReturn(isConsumer);
+ return invocation;
+ }
+
private void testProtoSchemaOperationUserImpl() throws IOException {
+ Invocation consumerInvocation = mockInvocation("user", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("user", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("user"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("user"));
+ .getOrCreateOperation(consumerInvocation);
User user = new User();
user.name = "user";
User friend = new User();
@@ -178,21 +217,24 @@ public class TestSchemaMetaCodec {
@Test
public void testProtoSchemaOperationmapUserSpringMVC() throws Exception {
- mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+ mockSchemaMeta("ProtoSchema", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
testProtoSchemaOperationmapUserImpl(false);
}
@Test
public void testProtoSchemaOperationmapUserPOJO() throws Exception {
- mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+ mockSchemaMeta("ProtoSchemaPojo", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
testProtoSchemaOperationmapUserImpl(true);
}
private void testProtoSchemaOperationmapUserImpl(boolean isPojo) throws IOException {
+ Invocation consumerInvocation = mockInvocation("mapUser", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("mapUser", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("mapUser"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("mapUser"));
+ .getOrCreateOperation(consumerInvocation);
User user = new User();
user.name = "user";
User friend = new User();
@@ -248,21 +290,24 @@ public class TestSchemaMetaCodec {
@Test
public void testProtoSchemaOperationBaseSpringMVC() throws Exception {
- mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+ mockSchemaMeta("ProtoSchema", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
testProtoSchemaOperationBaseImpl(false);
}
@Test
public void testProtoSchemaOperationBasePOJO() throws Exception {
- mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+ mockSchemaMeta("ProtoSchemaPojo", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
testProtoSchemaOperationBaseImpl(true);
}
private void testProtoSchemaOperationBaseImpl(boolean isPojo) throws IOException {
+ Invocation consumerInvocation = mockInvocation("base", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("base", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("base"));
+ .getOrCreateOperation(consumerInvocation);
byte[] values;
// request message
@@ -364,21 +409,24 @@ public class TestSchemaMetaCodec {
@Test
public void testProtoSchemaOperationlistListUserSpringMVC() throws Exception {
- mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+ mockSchemaMeta("ProtoSchema", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
testProtoSchemaOperationlistListUserImpl(false);
}
@Test
public void testProtoSchemaOperationlistListUserPOJO() throws Exception {
- mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+ mockSchemaMeta("ProtoSchemaPojo", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
testProtoSchemaOperationlistListUserImpl(true);
}
private void testProtoSchemaOperationlistListUserImpl(boolean isPojo) throws IOException {
+ Invocation consumerInvocation = mockInvocation("listListUser", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("listListUser", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("listListUser"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("listListUser"));
+ .getOrCreateOperation(consumerInvocation);
byte[] values;
// request message
@@ -434,21 +482,24 @@ public class TestSchemaMetaCodec {
@Test
public void testProtoSchemaOperationObjSpringMVC() throws Exception {
- mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+ mockSchemaMeta("ProtoSchema", new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
testProtoSchemaOperationObjImpl(false);
}
@Test
public void testProtoSchemaOperationObjPOJO() throws Exception {
- mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+ mockSchemaMeta("ProtoSchemaPojo", new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
testProtoSchemaOperationObjImpl(true);
}
private void testProtoSchemaOperationObjImpl(boolean isPojo) throws IOException {
+ Invocation consumerInvocation = mockInvocation("obj", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("obj", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("obj"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("obj"));
+ .getOrCreateOperation(consumerInvocation);
byte[] values;
// request message
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
index 191a419..c638e8c 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
@@ -31,6 +31,8 @@ import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
import org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;
import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.InvocationRuntimeType;
import org.apache.servicecomb.core.definition.MicroserviceMeta;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
@@ -41,9 +43,11 @@ 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.apache.servicecomb.swagger.invocation.InvocationType;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -67,6 +71,8 @@ public class TestSchemaMetaCodecRestTemplate {
@Before
public void setUp() {
+ ProtobufManager.clear();
+
new Expectations() {
{
providerMicroserviceMeta.getMicroserviceName();
@@ -93,12 +99,46 @@ public class TestSchemaMetaCodecRestTemplate {
consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, "ProtoSchema", swagger);
}
+ private Invocation mockInvocation(String operation, InvocationType invocationType) {
+ OperationMeta operationMeta;
+ boolean isConsumer;
+ Invocation invocation = Mockito.mock(Invocation.class);
+ InvocationRuntimeType invocationRuntimeType;
+
+ if (InvocationType.CONSUMER == invocationType) {
+ operationMeta = consumerSchemaMeta.getOperations().get(operation);
+ isConsumer = true;
+ Mockito.when(invocation.getSchemaMeta()).thenReturn(consumerSchemaMeta);
+ invocationRuntimeType = operationMeta.buildBaseConsumerRuntimeType();
+ } else {
+ operationMeta = providerSchemaMeta.getOperations().get(operation);
+ isConsumer = false;
+ Mockito.when(invocation.getSchemaMeta()).thenReturn(providerSchemaMeta);
+ invocationRuntimeType = operationMeta.buildBaseProviderRuntimeType();
+ }
+
+ MicroserviceMeta microserviceMeta = operationMeta.getMicroserviceMeta();
+ Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ Mockito.when(invocation.getInvocationRuntimeType())
+ .thenReturn(invocationRuntimeType);
+ Mockito.when(invocation.findResponseType(200))
+ .thenReturn(invocationRuntimeType.findResponseType(200));
+ Mockito.when(invocation.getInvocationType()).thenReturn(invocationType);
+ Mockito.when(invocation.getMicroserviceMeta()).thenReturn(microserviceMeta);
+
+ Mockito.when(invocation.isConsumer()).thenReturn(isConsumer);
+ return invocation;
+ }
+
@Test
public void testProtoSchemaOperationUser() throws Exception {
+ Invocation consumerInvocation = mockInvocation("user", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("user", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("user"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("user"));
+ .getOrCreateOperation(consumerInvocation);
User user = new User();
user.name = "user";
User friend = new User();
@@ -124,13 +164,15 @@ public class TestSchemaMetaCodecRestTemplate {
ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
values = responseSerializer.serialize(user);
ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
- User decodedUser = (User) responseDeserializer.deserialize(values, TypeFactory.defaultInstance().constructType(User.class));
+ User decodedUser = (User) responseDeserializer
+ .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));
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);
- decodedUser = (User) responseDeserializer.deserialize(values, TypeFactory.defaultInstance().constructType(User.class));
+ decodedUser = (User) responseDeserializer
+ .deserialize(values, TypeFactory.defaultInstance().constructType(User.class));
Assert.assertEquals(user.name, decodedUser.name);
// proto buffer encode and decode empty list to be null
Assert.assertEquals(null, decodedUser.friends);
@@ -139,10 +181,13 @@ public class TestSchemaMetaCodecRestTemplate {
@Test
@SuppressWarnings({"rawtypes", "unchecked"})
public void testProtoSchemaOperationBase() throws Exception {
+ Invocation consumerInvocation = mockInvocation("base", InvocationType.CONSUMER);
+ Invocation providerInvocation = mockInvocation("base", InvocationType.PRODUCER);
+
OperationProtobuf providerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
+ .getOrCreateOperation(providerInvocation);
OperationProtobuf consumerOperationProtobuf = ProtobufManager
- .getOrCreateOperation(consumerSchemaMeta.getOperations().get("base"));
+ .getOrCreateOperation(consumerInvocation);
byte[] values;
// request message
@@ -214,7 +259,8 @@ public class TestSchemaMetaCodecRestTemplate {
ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
values = responseSerializer.serialize(30);
ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
- Object decodedValue = responseDeserializer.deserialize(values, TypeFactory.defaultInstance().constructType(int.class));
+ Object decodedValue = responseDeserializer
+ .deserialize(values, TypeFactory.defaultInstance().constructType(int.class));
Assert.assertEquals(30, (int) decodedValue);
}
}
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 75b1ddb..38dbeb6 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -324,6 +324,10 @@ public class Invocation extends SwaggerInvocation {
return referenceConfig.getVersionRule();
}
+ public InvocationRuntimeType getInvocationRuntimeType() {
+ return this.invocationRuntimeType;
+ }
+
public JavaType findResponseType(int statusCode) {
return this.invocationRuntimeType.findResponseType(statusCode);
}
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/RestObjectMapper.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/RestObjectMapper.java
index ec03ef8..4fd41fc 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/RestObjectMapper.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/RestObjectMapper.java
@@ -74,7 +74,7 @@ public class RestObjectMapper extends AbstractRestObjectMapper {
@SuppressWarnings("unchecked")
public <T> T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException {
// After jackson 2.10.*, will by pass the following check when convert value. But this is useful
- // for java chassis applications and do not need to convert. So add the check here.(conversion is
+ // for java chassis applications and do not need to convert to keep performance. So add the check here.(conversion is
// not necessary and will cause some trouble in some user applications that depend on this)
if (fromValue == null) {
return null;
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/TypesUtil.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/TypesUtil.java
new file mode 100644
index 0000000..5f72a1d
--- /dev/null
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/TypesUtil.java
@@ -0,0 +1,130 @@
+/*
+ * 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.common.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+/**
+ * common utils to convert java types.
+ */
+public class TypesUtil {
+ private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER = new HashMap<>();
+
+ static {
+ PRIMITIVE_TO_WRAPPER.put(byte.class, Byte.class);
+ PRIMITIVE_TO_WRAPPER.put(short.class, Short.class);
+ PRIMITIVE_TO_WRAPPER.put(int.class, Integer.class);
+ PRIMITIVE_TO_WRAPPER.put(long.class, Long.class);
+ PRIMITIVE_TO_WRAPPER.put(float.class, Float.class);
+ PRIMITIVE_TO_WRAPPER.put(double.class, Double.class);
+ PRIMITIVE_TO_WRAPPER.put(boolean.class, Boolean.class);
+ PRIMITIVE_TO_WRAPPER.put(char.class, Character.class);
+ }
+
+
+ private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE = new HashMap<>();
+
+ static {
+ WRAPPER_TO_PRIMITIVE.put(Byte.class, byte.class);
+ WRAPPER_TO_PRIMITIVE.put(Short.class, short.class);
+ WRAPPER_TO_PRIMITIVE.put(Integer.class, int.class);
+ WRAPPER_TO_PRIMITIVE.put(Long.class, long.class);
+ WRAPPER_TO_PRIMITIVE.put(Float.class, float.class);
+ WRAPPER_TO_PRIMITIVE.put(Double.class, double.class);
+ WRAPPER_TO_PRIMITIVE.put(Boolean.class, boolean.class);
+ WRAPPER_TO_PRIMITIVE.put(Character.class, char.class);
+ }
+
+ public static final JavaType PRIMITIVE_BYTE = TypeFactory.defaultInstance().constructType(byte.class);
+
+ public static final JavaType PRIMITIVE_SHORT = TypeFactory.defaultInstance().constructType(short.class);
+
+ public static final JavaType PRIMITIVE_INT = TypeFactory.defaultInstance().constructType(int.class);
+
+ public static final JavaType PRIMITIVE_LONG = TypeFactory.defaultInstance().constructType(long.class);
+
+ public static final JavaType PRIMITIVE_FLOAT = TypeFactory.defaultInstance().constructType(float.class);
+
+ public static final JavaType PRIMITIVE_DOUBLE = TypeFactory.defaultInstance().constructType(double.class);
+
+ public static final JavaType PRIMITIVE_BOOLEAN = TypeFactory.defaultInstance().constructType(boolean.class);
+
+ public static final JavaType PRIMITIVE_CHAR = TypeFactory.defaultInstance().constructType(char.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_BYTE = TypeFactory.defaultInstance().constructType(Byte.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_SHORT = TypeFactory.defaultInstance().constructType(Short.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_INT = TypeFactory.defaultInstance().constructType(Integer.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_LONG = TypeFactory.defaultInstance().constructType(Long.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_FLOAT = TypeFactory.defaultInstance().constructType(Float.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_DOUBLE = TypeFactory.defaultInstance().constructType(Double.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_BOOLEAN = TypeFactory.defaultInstance().constructType(Boolean.class);
+
+ public static final JavaType PRIMITIVE_WRAPPER_CHAR = TypeFactory.defaultInstance().constructType(Character.class);
+
+
+ private static final Map<JavaType, JavaType> PRIMITIVE_TO_WRAPPER_JAVATYPE = new HashMap<>();
+
+ static {
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_BYTE, PRIMITIVE_WRAPPER_BYTE);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_SHORT, PRIMITIVE_WRAPPER_SHORT);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_INT, PRIMITIVE_WRAPPER_INT);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_LONG, PRIMITIVE_WRAPPER_LONG);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_FLOAT, PRIMITIVE_WRAPPER_FLOAT);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_DOUBLE, PRIMITIVE_WRAPPER_DOUBLE);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_BOOLEAN, PRIMITIVE_WRAPPER_BOOLEAN);
+ PRIMITIVE_TO_WRAPPER_JAVATYPE.put(PRIMITIVE_CHAR, PRIMITIVE_WRAPPER_CHAR);
+ }
+
+ private static final Map<JavaType, JavaType> WRAPPER_TO_PRIMITIVE_JAVATYPE = new HashMap<>();
+
+ static {
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_BYTE, PRIMITIVE_BYTE);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_SHORT, PRIMITIVE_SHORT);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_INT, PRIMITIVE_INT);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_LONG, PRIMITIVE_LONG);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_FLOAT, PRIMITIVE_FLOAT);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_DOUBLE, PRIMITIVE_DOUBLE);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_BOOLEAN, PRIMITIVE_BOOLEAN);
+ WRAPPER_TO_PRIMITIVE_JAVATYPE.put(PRIMITIVE_WRAPPER_CHAR, PRIMITIVE_CHAR);
+ }
+
+ public static Class<?> primitiveTypeToWrapper(Class<?> primitiveType) {
+ return PRIMITIVE_TO_WRAPPER.get(primitiveType);
+ }
+
+ public static Class<?> wrapperTypeToPrimitive(Class<?> wrapperType) {
+ return WRAPPER_TO_PRIMITIVE.get(wrapperType);
+ }
+
+ public static JavaType primitiveJavaTypeToWrapper(JavaType primitiveType) {
+ return PRIMITIVE_TO_WRAPPER_JAVATYPE.get(primitiveType);
+ }
+
+ public static JavaType wrapperJavaTypeToPrimitive(JavaType wrapperType) {
+ return WRAPPER_TO_PRIMITIVE_JAVATYPE.get(wrapperType);
+ }
+}
diff --git a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestTypesUtil.java b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestTypesUtil.java
new file mode 100644
index 0000000..c2fe52c
--- /dev/null
+++ b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/utils/TestTypesUtil.java
@@ -0,0 +1,32 @@
+/*
+ * 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.common.utils;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestTypesUtil {
+ @Test
+ public void testTypesUtil() {
+ Assert.assertEquals(double.class, TypesUtil.wrapperTypeToPrimitive(Double.class));
+ Assert.assertEquals(Float.class, TypesUtil.primitiveTypeToWrapper(float.class));
+ Assert
+ .assertEquals(TypesUtil.PRIMITIVE_CHAR, TypesUtil.wrapperJavaTypeToPrimitive(TypesUtil.PRIMITIVE_WRAPPER_CHAR));
+ Assert
+ .assertEquals(TypesUtil.PRIMITIVE_WRAPPER_BYTE, TypesUtil.primitiveJavaTypeToWrapper(TypesUtil.PRIMITIVE_BYTE));
+ }
+}
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 9965a62..cf47f8f 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
@@ -21,9 +21,9 @@ import static org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils.isW
import java.lang.reflect.Type;
import java.util.Map;
+import org.apache.servicecomb.foundation.common.utils.TypesUtil;
import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
@@ -124,7 +124,13 @@ public class DeserializerSchemaManager extends SchemaManager {
protoField.isRepeated() && !protoField.isMap() ? ProtoConst.LIST_TYPE
: ProtoConst.MAP_TYPE;
}
- javaType = TypeFactory.defaultInstance().constructParametricType(PropertyWrapper.class, javaType);
+
+ if (javaType.isPrimitive()) {
+ javaType = TypeFactory.defaultInstance()
+ .constructParametricType(PropertyWrapper.class, TypesUtil.primitiveJavaTypeToWrapper(javaType));
+ } else {
+ javaType = TypeFactory.defaultInstance().constructParametricType(PropertyWrapper.class, javaType);
+ }
}
if (javaType.isJavaLangObject()) {
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
index 56c61e2..b80cd43 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayClient.java
@@ -92,7 +92,7 @@ public class HighwayClient {
HighwayClientConnectionPool tcpClientPool = clientMgr.findClientPool(invocation.isSync());
OperationMeta operationMeta = invocation.getOperationMeta();
- OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(operationMeta);
+ OperationProtobuf operationProtobuf = ProtobufManager.getOrCreateOperation(invocation);
HighwayClientConnection tcpClient =
tcpClientPool.findOrCreateClient(invocation.getEndpoint().getEndpoint());
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 61423f2..ea8fd0b 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
@@ -60,16 +60,16 @@ public final class HighwayCodec {
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private static Map<String, Object> addPrimitiveTypeDefaultValues(Invocation invocation, OperationMeta operationMeta,
+ private static Map<String, Object> addPrimitiveTypeDefaultValues(Invocation invocation,
Map<String, Object> swaggerArguments) {
// proto buffer never serialize default values, put it back in provider
- SwaggerProducerOperation swaggerProducerOperation = operationMeta.getSwaggerProducerOperation();
- if (swaggerProducerOperation != null && !invocation.isEdge()) {
- List<Parameter> swaggerParameters = operationMeta.getSwaggerOperation()
+ if (invocation.getOperationMeta().getSwaggerProducerOperation() != null && !invocation.isEdge()) {
+ List<Parameter> swaggerParameters = invocation.getOperationMeta().getSwaggerOperation()
.getParameters();
for (Parameter parameter : swaggerParameters) {
if (swaggerArguments.get(parameter.getName()) == null) {
- Type type = swaggerProducerOperation.getSwaggerParameterType(parameter.getName());
+ Type type = invocation.getOperationMeta().getSwaggerProducerOperation()
+ .getSwaggerParameterType(parameter.getName());
if (type instanceof Class) {
if (((Class) type).isPrimitive()) {
swaggerArguments.put(parameter.getName(), Defaults.defaultValue((Class) type));
@@ -86,7 +86,7 @@ public final class HighwayCodec {
Buffer bodyBuffer) throws Exception {
RequestRootDeserializer<Object> requestDeserializer = operationProtobuf.getRequestRootDeserializer();
Map<String, Object> swaggerArguments = requestDeserializer.deserialize(bodyBuffer.getBytes());
- addPrimitiveTypeDefaultValues(invocation, operationProtobuf.getOperationMeta(), swaggerArguments);
+ addPrimitiveTypeDefaultValues(invocation, swaggerArguments);
invocation.setSwaggerArguments(swaggerArguments);
invocation.mergeContext(header.getContext());
}
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
index d8a6cd3..47c9afa 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
@@ -52,8 +52,6 @@ public class HighwayServerInvoke {
private OperationMeta operationMeta;
- private OperationProtobuf operationProtobuf;
-
private TcpConnection connection;
private long msgId;
@@ -62,9 +60,11 @@ public class HighwayServerInvoke {
private Endpoint endpoint;
- Invocation invocation;
+ private Invocation invocation;
- protected long start;
+ private OperationProtobuf operationProtobuf;
+
+ private long start;
public HighwayServerInvoke(Endpoint endpoint) {
this.start = System.nanoTime();
@@ -97,8 +97,6 @@ public class HighwayServerInvoke {
MicroserviceMeta microserviceMeta = SCBEngine.getInstance().getProducerMicroserviceMeta();
SchemaMeta schemaMeta = microserviceMeta.ensureFindSchemaMeta(header.getSchemaId());
this.operationMeta = schemaMeta.ensureFindOperation(header.getOperationName());
- this.operationProtobuf = ProtobufManager.getOrCreateOperation(operationMeta);
-
this.bodyBuffer = bodyBuffer;
}
@@ -154,9 +152,9 @@ public class HighwayServerInvoke {
invocation.getInvocationStageTrace().finishServerFiltersResponse();
connection.write(respBuffer.getByteBuf());
} catch (Exception e) {
- // 没招了,直接打日志
+ // keep highway performance and simple, this encoding/decoding error not need handle by client
String msg = String.format("encode response failed, %s, msgId=%d",
- operationProtobuf.getOperationMeta().getMicroserviceQualifiedName(),
+ invocation.getOperationMeta().getMicroserviceQualifiedName(),
msgId);
LOGGER.error(msg, e);
} finally {
@@ -172,8 +170,9 @@ public class HighwayServerInvoke {
public void execute() {
try {
invocation = InvocationFactory.forProvider(endpoint,
- operationProtobuf.getOperationMeta(),
+ operationMeta,
null);
+ operationProtobuf = ProtobufManager.getOrCreateOperation(invocation);
invocation.onStart(null, start);
invocation.getInvocationStageTrace().startSchedule();
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
index 914f9b7..baaef46 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
@@ -130,7 +130,7 @@ public class TestHighwayClient {
new MockUp<ProtobufManager>() {
@Mock
- public OperationProtobuf getOrCreateOperation(OperationMeta operationMeta) {
+ public OperationProtobuf getOrCreateOperation(Invocation operationMeta) {
return operationProtobuf;
}
};
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 e0cd2df..55f29d9 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
@@ -181,7 +181,7 @@ public class TestHighwayCodec {
Mockito.when(bodyBuffer.getByteBuf()).thenReturn(lByteBuf);
Mockito.when(bodyBuffer.getBytes()).thenReturn(new byte[0]);
Mockito.when(lByteBuf.nioBuffer()).thenReturn(nioBuffer);
- Mockito.when(operationProtobuf.getOperationMeta()).thenReturn(operationMeta);
+
Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
}