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/03/27 03:54:06 UTC
[servicecomb-java-chassis] 01/02: [SCB-1822]fix problems when using
multiple consumer interface for one operation and using CseHttpEntity to
set localcontext
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 06e7c07ba0e6475c2bd651ece33c29580fe90aa6
Author: liubao <bi...@qq.com>
AuthorDate: Wed Mar 25 17:27:18 2020 +0800
[SCB-1822]fix problems when using multiple consumer interface for one operation and using CseHttpEntity to set localcontext
---
.../client/CustomEndpointDiscoveryFilter.java | 41 ++++++++++++++
.../demo/springmvc/client/TestDateTimeSchema.java | 62 +++++++++++++++++++++
.../src/main/resources/microservice.yaml | 1 +
.../apache/servicecomb/provider/pojo/Invoker.java | 4 +-
.../pojo/definition/PojoConsumerMapKey.java | 65 ++++++++++++++++++++++
.../provider/pojo/definition/PojoConsumerMeta.java | 19 +++----
.../servicecomb/provider/pojo/TestInvoker.java | 2 +-
.../springmvc/reference/CseClientHttpRequest.java | 3 +-
8 files changed, 182 insertions(+), 15 deletions(-)
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CustomEndpointDiscoveryFilter.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CustomEndpointDiscoveryFilter.java
new file mode 100644
index 0000000..126a7d4
--- /dev/null
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CustomEndpointDiscoveryFilter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.demo.springmvc.client;
+
+import org.apache.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import org.apache.servicecomb.serviceregistry.discovery.AbstractEndpointDiscoveryFilter;
+import org.apache.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import org.apache.servicecomb.serviceregistry.discovery.DiscoveryTreeNode;
+
+public class CustomEndpointDiscoveryFilter extends AbstractEndpointDiscoveryFilter {
+ @Override
+ protected String findTransportName(DiscoveryContext context, DiscoveryTreeNode parent) {
+ //only need rest endpoints
+ return "rest";
+ }
+
+ @Override
+ protected Object createEndpoint(String transportName, String endpoint, MicroserviceInstance instance) {
+ return endpoint;
+ }
+
+ @Override
+ public int getOrder() {
+ return 0;
+ }
+}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDateTimeSchema.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDateTimeSchema.java
index b22f8c7..4762f36 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDateTimeSchema.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDateTimeSchema.java
@@ -21,11 +21,22 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
+import java.util.List;
+import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import org.apache.servicecomb.demo.CategorizedTestCase;
import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.foundation.common.cache.VersionedCache;
+import org.apache.servicecomb.loadbalance.LoadbalanceHandler;
import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.apache.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import org.apache.servicecomb.serviceregistry.discovery.DiscoveryTree;
+import org.apache.servicecomb.swagger.invocation.context.InvocationContext;
+import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
interface DateTimeSchemaInf {
Date getDate(Date date);
@@ -47,11 +58,25 @@ interface DateTimeSchemaInf {
LocalDateTime postLocalDateTime(LocalDateTime date);
}
+interface DateTimeSchemaWithContextInf {
+ Date getDate(InvocationContext context, Date date);
+}
+
@Component
public class TestDateTimeSchema implements CategorizedTestCase {
@RpcReference(microserviceName = "springmvc", schemaId = "DateTimeSchema")
private DateTimeSchemaInf dateTimeSchemaInf;
+ @RpcReference(microserviceName = "springmvc", schemaId = "DateTimeSchema")
+ private DateTimeSchemaWithContextInf dateTimeSchemaWithContextInf;
+
+ private DiscoveryTree discoveryTree = new DiscoveryTree();
+
+ public TestDateTimeSchema() {
+ discoveryTree.addFilter(new CustomEndpointDiscoveryFilter());
+ discoveryTree.sort();
+ }
+
@Override
public void testRestTransport() throws Exception {
@@ -65,6 +90,8 @@ public class TestDateTimeSchema implements CategorizedTestCase {
@Override
public void testAllTransport() throws Exception {
testDateTimeSchema();
+ testDateTimeSchemaMulticast();
+ testDateTimeSchemaMulticastRestTemplate();
}
private void testDateTimeSchema() {
@@ -92,4 +119,39 @@ public class TestDateTimeSchema implements CategorizedTestCase {
dateTimeSchemaInf.postLocalDateTime(localDateTime)
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")));
}
+
+ private void testDateTimeSchemaMulticast() {
+ DiscoveryContext context = new DiscoveryContext();
+ VersionedCache serversVersionedCache = discoveryTree.discovery(context, "springmvctest", "springmvc", "0+");
+ List<String> enpoints = serversVersionedCache.data();
+
+ for (String endpoint : enpoints) {
+ InvocationContext invocationContext = new InvocationContext();
+ invocationContext.addLocalContext(LoadbalanceHandler.SERVICECOMB_SERVER_ENDPOINT, endpoint);
+ Date date = new Date();
+ TestMgr.check(date.getTime(), dateTimeSchemaWithContextInf.getDate(invocationContext, date).getTime());
+ }
+ }
+
+ private void testDateTimeSchemaMulticastRestTemplate() throws Exception {
+ DiscoveryContext context = new DiscoveryContext();
+ VersionedCache serversVersionedCache = discoveryTree.discovery(context, "springmvctest", "springmvc", "0+");
+ List<String> enpoints = serversVersionedCache.data();
+
+ RestTemplate restTemplate = RestTemplateBuilder.create();
+
+ for (String endpoint : enpoints) {
+ CseHttpEntity<?> entity = new CseHttpEntity<>(null);
+ InvocationContext invocationContext = new InvocationContext();
+ invocationContext.addLocalContext(LoadbalanceHandler.SERVICECOMB_SERVER_ENDPOINT, endpoint);
+ entity.setContext(invocationContext);
+
+ Date date = new Date();
+ String dateValue = RestObjectMapperFactory.getRestObjectMapper().convertToString(date);
+ TestMgr.check(date.getTime(),
+ restTemplate
+ .exchange("cse://springmvc/dateTime/getDate?date={1}", HttpMethod.GET,
+ entity, Date.class, dateValue).getBody().getTime());
+ }
+ }
}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
index c8c33bc..95b2b43 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
+++ b/demo/demo-springmvc/springmvc-client/src/main/resources/microservice.yaml
@@ -56,6 +56,7 @@ servicecomb:
enabled: true
samplingRate: 0.5
loadbalance:
+ userDefinedEndpoint.enabled: true
strategy:
name: WeightedResponse
retryEnabled: true
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/Invoker.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/Invoker.java
index 89cf49d..f254ad9 100644
--- a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/Invoker.java
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/Invoker.java
@@ -148,7 +148,7 @@ public class Invoker implements InvocationHandler {
}
PojoConsumerOperationMeta pojoConsumerOperationMeta = consumerMeta
- .findOperationMeta(MethodUtils.findSwaggerMethodName(method));
+ .findOperationMeta(MethodUtils.findSwaggerMethodName(method), consumerIntf);
if (pojoConsumerOperationMeta == null) {
throw new IllegalStateException(
String.format(
@@ -162,6 +162,8 @@ public class Invoker implements InvocationHandler {
SwaggerConsumerOperation consumerOperation = pojoConsumerOperationMeta.getSwaggerConsumerOperation();
OperationMeta operationMeta = pojoConsumerOperationMeta.getOperationMeta();
+ // operation meta is static data based on swagger, while consumer operation based on invoker, have interface info
+ operationMeta.setSwaggerConsumerOperation(consumerOperation);
Invocation invocation = InvocationFactory.forConsumer(
findReferenceConfig(operationMeta),
operationMeta,
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMapKey.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMapKey.java
new file mode 100644
index 0000000..26a8c09
--- /dev/null
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMapKey.java
@@ -0,0 +1,65 @@
+/*
+ * 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.provider.pojo.definition;
+
+/**
+ * In consumer, every schema may have many consumer interfaces, each interface may contain part of the
+ * scheme operations.
+ */
+public class PojoConsumerMapKey {
+ private final String operationId;
+
+ private final Class<?> consumerIntf;
+
+ public PojoConsumerMapKey(String operationId, Class<?> consumerIntf) {
+ this.operationId = operationId;
+ this.consumerIntf = consumerIntf;
+ }
+
+ public String getOperationId() {
+ return operationId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ PojoConsumerMapKey that = (PojoConsumerMapKey) o;
+
+ if (!operationId.equals(that.operationId)) {
+ return false;
+ }
+ return consumerIntf.equals(that.consumerIntf);
+ }
+
+ @Override
+ public int hashCode() {
+ int result = operationId.hashCode();
+ result = 31 * result + consumerIntf.hashCode();
+ return result;
+ }
+
+ public Class<?> getConsumerIntf() {
+ return consumerIntf;
+ }
+}
diff --git a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMeta.java b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMeta.java
index 7436ad4..1587a92 100644
--- a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMeta.java
+++ b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerMeta.java
@@ -31,20 +31,17 @@ import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
public class PojoConsumerMeta {
private MicroserviceReferenceConfig microserviceReferenceConfig;
- private Class<?> consumerIntf;
-
private SchemaMeta schemaMeta;
// key is consumer method name
- private Map<String, PojoConsumerOperationMeta> operationMetas = new HashMap<>();
+ private Map<PojoConsumerMapKey, PojoConsumerOperationMeta> operationMetas = new HashMap<>();
public PojoConsumerMeta(MicroserviceReferenceConfig microserviceReferenceConfig, SwaggerConsumer swaggerConsumer,
SchemaMeta schemaMeta) {
this.microserviceReferenceConfig = microserviceReferenceConfig;
- this.consumerIntf = swaggerConsumer.getConsumerIntf();
this.schemaMeta = schemaMeta;
- SwaggerGenerator intfSwaggerGenerator = SwaggerGenerator.create(consumerIntf);
+ SwaggerGenerator intfSwaggerGenerator = SwaggerGenerator.create(swaggerConsumer.getConsumerIntf());
intfSwaggerGenerator.scanClassAnnotation();
for (SwaggerConsumerOperation swaggerConsumerOperation : swaggerConsumer.getOperations().values()) {
String operationId = swaggerConsumerOperation.getSwaggerOperation().getOperationId();
@@ -57,7 +54,9 @@ public class PojoConsumerMeta {
PojoConsumerOperationMeta pojoConsumerOperationMeta = new PojoConsumerOperationMeta(this, operationMeta,
swaggerConsumerOperation, intfSwaggerGenerator.getSwagger(), intfOperationGenerator.getOperation());
- operationMetas.put(swaggerConsumerOperation.getSchemaOperationId(), pojoConsumerOperationMeta);
+ operationMetas.put(
+ new PojoConsumerMapKey(swaggerConsumerOperation.getSchemaOperationId(), swaggerConsumer.getConsumerIntf()),
+ pojoConsumerOperationMeta);
}
}
@@ -65,10 +64,6 @@ public class PojoConsumerMeta {
return microserviceReferenceConfig;
}
- public Class<?> getConsumerIntf() {
- return consumerIntf;
- }
-
public boolean isExpired() {
return microserviceReferenceConfig.isExpired();
}
@@ -81,7 +76,7 @@ public class PojoConsumerMeta {
return schemaMeta;
}
- public PojoConsumerOperationMeta findOperationMeta(String consumerMethodName) {
- return operationMetas.get(consumerMethodName);
+ public PojoConsumerOperationMeta findOperationMeta(String consumerMethodName, Class<?> consumerInf) {
+ return operationMetas.get(new PojoConsumerMapKey(consumerMethodName, consumerInf));
}
}
diff --git a/providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/TestInvoker.java b/providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/TestInvoker.java
index c85b725..88167a1 100644
--- a/providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/TestInvoker.java
+++ b/providers/provider-pojo/src/test/java/org/apache/servicecomb/provider/pojo/TestInvoker.java
@@ -277,7 +277,7 @@ public class TestInvoker {
Deencapsulation.invoke(invoker, "ensureStatusUp");
PojoConsumerMeta meta = Deencapsulation.invoke(invoker, "refreshMeta");
- JavaType javaType = meta.findOperationMeta("download").getResponsesMeta().findResponseType(200);
+ JavaType javaType = meta.findOperationMeta("download", DownloadIntf.class).getResponsesMeta().findResponseType(200);
Assert.assertSame(Part.class, javaType.getRawClass());
scbEngine.destroy();
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
index 14b4bfe..6e42671 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
@@ -218,7 +218,8 @@ public class CseClientHttpRequest implements ClientHttpRequest {
path + (this.uri.getRawQuery() == null ? "" : "?" + this.uri.getRawQuery()));
if (context != null) {
- invocation.addContext(context);
+ invocation.addContext(context.getContext());
+ invocation.addLocalContext(context.getLocalContext());
}
if (responseType != null &&