From 9199dbec80a55f861a8a36f184090944c7790e35 Mon Sep 17 00:00:00 2001 From: wujimin Date: Thu, 23 Nov 2017 09:49:56 +0800 Subject: [PATCH 1/5] resolve eclipse compile warnings --- .../foundation/metrics/TestMetricsServoRegistry.java | 1 - .../test/java/io/servicecomb/serviceregistry/api/TestConst.java | 2 -- 2 files changed, 3 deletions(-) diff --git a/foundations/foundation-metrics/src/test/java/io/servicecomb/foundation/metrics/TestMetricsServoRegistry.java b/foundations/foundation-metrics/src/test/java/io/servicecomb/foundation/metrics/TestMetricsServoRegistry.java index fbdd33a984b..84e0def62d1 100644 --- a/foundations/foundation-metrics/src/test/java/io/servicecomb/foundation/metrics/TestMetricsServoRegistry.java +++ b/foundations/foundation-metrics/src/test/java/io/servicecomb/foundation/metrics/TestMetricsServoRegistry.java @@ -19,7 +19,6 @@ import java.util.Map; import org.junit.After; -import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; diff --git a/service-registry/src/test/java/io/servicecomb/serviceregistry/api/TestConst.java b/service-registry/src/test/java/io/servicecomb/serviceregistry/api/TestConst.java index d4ab7302007..a71996b97a4 100644 --- a/service-registry/src/test/java/io/servicecomb/serviceregistry/api/TestConst.java +++ b/service-registry/src/test/java/io/servicecomb/serviceregistry/api/TestConst.java @@ -21,8 +21,6 @@ import org.junit.Test; import io.servicecomb.config.ConfigUtil; -import io.servicecomb.serviceregistry.api.Const.REGISTRY_API; -import io.servicecomb.serviceregistry.definition.DefinitionConst; public class TestConst { @Before From cd61489edc04de1ba29465711f3070a5ee430a84 Mon Sep 17 00:00:00 2001 From: wujimin Date: Thu, 23 Nov 2017 14:42:23 +0800 Subject: [PATCH 2/5] JAV-524 move some logic from RestProducerInvocation to AbstractRestInvocation --- .../common/rest/AbstractRestInvocation.java | 113 +++++++- .../common/rest/RestProducerInvocation.java | 122 +------- .../rest/TestAbstractRestInvocation.java | 264 ++++++++++++++++-- .../rest/TestRestProducerInvocation.java | 205 +------------- 4 files changed, 375 insertions(+), 329 deletions(-) diff --git a/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java index 12232828eb7..fda2bb75fbf 100644 --- a/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java +++ b/common/common-rest/src/main/java/io/servicecomb/common/rest/AbstractRestInvocation.java @@ -30,13 +30,21 @@ import org.slf4j.LoggerFactory; import io.netty.buffer.Unpooled; +import io.servicecomb.common.rest.codec.RestCodec; import io.servicecomb.common.rest.codec.produce.ProduceProcessor; import io.servicecomb.common.rest.codec.produce.ProduceProcessorManager; import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; +import io.servicecomb.common.rest.locator.OperationLocator; +import io.servicecomb.common.rest.locator.ServicePathManager; import io.servicecomb.core.Const; import io.servicecomb.core.Invocation; +import io.servicecomb.core.definition.MicroserviceMeta; +import io.servicecomb.core.definition.OperationMeta; import io.servicecomb.foundation.common.utils.JsonUtils; +import io.servicecomb.foundation.metrics.MetricsServoRegistry; +import io.servicecomb.foundation.metrics.performance.QueueMetrics; +import io.servicecomb.foundation.metrics.performance.QueueMetricsData; import io.servicecomb.foundation.vertx.http.HttpServletRequestEx; import io.servicecomb.foundation.vertx.http.HttpServletResponseEx; import io.servicecomb.foundation.vertx.stream.BufferOutputStream; @@ -62,6 +70,18 @@ public void setHttpServerFilters(List httpServerFilters) { this.httpServerFilters = httpServerFilters; } + protected void findRestOperation(MicroserviceMeta microserviceMeta) { + ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(microserviceMeta); + if (servicePathManager == null) { + LOGGER.error("No schema defined for {}:{}.", microserviceMeta.getAppId(), microserviceMeta.getName()); + throw new InvocationException(Status.NOT_FOUND, Status.NOT_FOUND.getReasonPhrase()); + } + + OperationLocator locator = locateOperation(servicePathManager); + requestEx.setAttribute(RestConst.PATH_PARAMETERS, locator.getPathVarMap()); + this.restOperationMeta = locator.getOperation(); + } + protected void initProduceProcessor() { produceProcessor = restOperationMeta.ensureFindProduceProcessor(requestEx); if (produceProcessor == null) { @@ -82,6 +102,44 @@ protected void setContext() throws Exception { invocation.setContext(cseContext); } + protected void scheduleInvocation() { + OperationMeta operationMeta = restOperationMeta.getOperationMeta(); + QueueMetrics metricsData = initMetrics(operationMeta); + operationMeta.getExecutor().execute(() -> { + synchronized (this.requestEx) { + try { + if (requestEx.getAttribute(RestConst.REST_REQUEST) != requestEx) { + // already timeout + // in this time, request maybe recycled and reused by web container, do not use requestEx + LOGGER.error("Rest request already timeout, abandon execute, method {}, operation {}.", + operationMeta.getHttpMethod(), + operationMeta.getMicroserviceQualifiedName()); + return; + } + + runOnExecutor(metricsData); + } catch (Throwable e) { + LOGGER.error("rest server onRequest error", e); + sendFailResponse(e); + } + } + }); + } + + protected void runOnExecutor(QueueMetrics metricsData) { + Object[] args = RestCodec.restToArgs(requestEx, restOperationMeta); + createInvocation(args); + + this.invocation.setMetricsData(metricsData); + updateMetrics(); + + invoke(); + } + + protected abstract OperationLocator locateOperation(ServicePathManager servicePathManager); + + protected abstract void createInvocation(Object[] args); + public void invoke() { try { Response response = prepareInvoke(); @@ -113,7 +171,12 @@ protected Response prepareInvoke() throws Throwable { return null; } - protected abstract void doInvoke() throws Throwable; + protected void doInvoke() throws Throwable { + invocation.next(resp -> { + sendResponseQuietly(resp); + endMetrics(); + }); + } public void sendFailResponse(Throwable throwable) { if (produceProcessor == null) { @@ -166,4 +229,52 @@ protected void sendResponse(Response response) throws Exception { responseEx.flushBuffer(); } } + + /** + * Init the metrics. Note down the queue count and start time. + * @param operationMeta Operation data + * @return QueueMetrics + */ + private QueueMetrics initMetrics(OperationMeta operationMeta) { + QueueMetrics metricsData = new QueueMetrics(); + metricsData.setQueueStartTime(System.currentTimeMillis()); + metricsData.setOperQualifiedName(operationMeta.getMicroserviceQualifiedName()); + QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() + .getOrCreateQueueMetrics(operationMeta.getMicroserviceQualifiedName()); + reqQueue.incrementCountInQueue(); + return metricsData; + } + + /** + * Update the queue metrics. + */ + private void updateMetrics() { + QueueMetrics metricsData = (QueueMetrics) this.invocation.getMetricsData(); + if (null != metricsData) { + metricsData.setQueueEndTime(System.currentTimeMillis()); + QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() + .getOrCreateQueueMetrics(restOperationMeta.getOperationMeta().getMicroserviceQualifiedName()); + reqQueue.incrementTotalCount(); + Long timeInQueue = metricsData.getQueueEndTime() - metricsData.getQueueStartTime(); + reqQueue.setTotalTime(reqQueue.getTotalTime() + timeInQueue); + reqQueue.setMinLifeTimeInQueue(timeInQueue); + reqQueue.setMaxLifeTimeInQueue(timeInQueue); + reqQueue.decrementCountInQueue(); + } + } + + /** + * Prepare the end time of queue metrics. + */ + private void endMetrics() { + QueueMetrics metricsData = (QueueMetrics) this.invocation.getMetricsData(); + if (null != metricsData) { + metricsData.setEndOperTime(System.currentTimeMillis()); + QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() + .getOrCreateQueueMetrics(restOperationMeta.getOperationMeta().getMicroserviceQualifiedName()); + reqQueue.incrementTotalServExecutionCount(); + reqQueue.setTotalServExecutionTime( + reqQueue.getTotalServExecutionTime() + (metricsData.getEndOperTime() - metricsData.getQueueEndTime())); + } + } } diff --git a/common/common-rest/src/main/java/io/servicecomb/common/rest/RestProducerInvocation.java b/common/common-rest/src/main/java/io/servicecomb/common/rest/RestProducerInvocation.java index 628fc5e8b79..4afbc06962e 100644 --- a/common/common-rest/src/main/java/io/servicecomb/common/rest/RestProducerInvocation.java +++ b/common/common-rest/src/main/java/io/servicecomb/common/rest/RestProducerInvocation.java @@ -18,13 +18,6 @@ import java.util.List; -import javax.ws.rs.core.Response.Status; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import io.servicecomb.common.rest.codec.RestCodec; -import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; import io.servicecomb.common.rest.locator.OperationLocator; import io.servicecomb.common.rest.locator.ServicePathManager; @@ -32,19 +25,13 @@ import io.servicecomb.core.CseContext; import io.servicecomb.core.Transport; import io.servicecomb.core.definition.MicroserviceMeta; -import io.servicecomb.core.definition.OperationMeta; import io.servicecomb.core.invocation.InvocationFactory; -import io.servicecomb.foundation.metrics.MetricsServoRegistry; -import io.servicecomb.foundation.metrics.performance.QueueMetrics; -import io.servicecomb.foundation.metrics.performance.QueueMetricsData; import io.servicecomb.foundation.vertx.http.HttpServletRequestEx; import io.servicecomb.foundation.vertx.http.HttpServletResponseEx; import io.servicecomb.serviceregistry.RegistryUtils; import io.servicecomb.swagger.invocation.exception.InvocationException; public class RestProducerInvocation extends AbstractRestInvocation { - private static final Logger LOGGER = LoggerFactory.getLogger(RestProducerInvocation.class); - protected Transport transport; public void invoke(Transport transport, HttpServletRequestEx requestEx, HttpServletResponseEx responseEx, @@ -56,7 +43,7 @@ public void invoke(Transport transport, HttpServletRequestEx requestEx, HttpServ requestEx.setAttribute(RestConst.REST_REQUEST, requestEx); try { - this.restOperationMeta = findRestOperation(); + findRestOperation(); } catch (InvocationException e) { sendFailResponse(e); return; @@ -65,41 +52,7 @@ public void invoke(Transport transport, HttpServletRequestEx requestEx, HttpServ scheduleInvocation(); } - protected void scheduleInvocation() { - OperationMeta operationMeta = restOperationMeta.getOperationMeta(); - QueueMetrics metricsData = initMetrics(operationMeta); - operationMeta.getExecutor().execute(() -> { - synchronized (this.requestEx) { - try { - if (requestEx.getAttribute(RestConst.REST_REQUEST) != requestEx) { - // already timeout - // in this time, request maybe recycled and reused by web container, do not use requestEx - LOGGER.error("Rest request already timeout, abandon execute, method {}, operation {}.", - operationMeta.getHttpMethod(), - operationMeta.getMicroserviceQualifiedName()); - return; - } - - runOnExecutor(metricsData); - } catch (Throwable e) { - LOGGER.error("rest server onRequest error", e); - sendFailResponse(e); - } - } - }); - } - - protected void runOnExecutor(QueueMetrics metricsData) { - Object[] args = RestCodec.restToArgs(requestEx, restOperationMeta); - this.invocation = InvocationFactory.forProvider(transport.getEndpoint(), - restOperationMeta.getOperationMeta(), - args); - this.invocation.setMetricsData(metricsData); - updateMetrics(); - invoke(); - } - - protected RestOperationMeta findRestOperation() { + protected void findRestOperation() { String targetMicroserviceName = requestEx.getHeader(Const.TARGET_MICROSERVICE); if (targetMicroserviceName == null) { // for compatible @@ -107,73 +60,18 @@ protected RestOperationMeta findRestOperation() { } MicroserviceMeta selfMicroserviceMeta = CseContext.getInstance().getMicroserviceMetaManager().ensureFindValue(targetMicroserviceName); - ServicePathManager servicePathManager = ServicePathManager.getServicePathManager(selfMicroserviceMeta); - if (servicePathManager == null) { - LOGGER.error("No schema in microservice"); - throw new InvocationException(Status.NOT_FOUND, Status.NOT_FOUND.getReasonPhrase()); - } - - OperationLocator locator = - servicePathManager.producerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod()); - requestEx.setAttribute(RestConst.PATH_PARAMETERS, locator.getPathVarMap()); - - return locator.getOperation(); + findRestOperation(selfMicroserviceMeta); } @Override - protected void doInvoke() throws Throwable { - invocation.next(resp -> { - sendResponseQuietly(resp); - endMetrics(); - - }); - } - - /** - * Init the metrics. Note down the queue count and start time. - * @param operationMeta Operation data - * @return QueueMetrics - */ - private QueueMetrics initMetrics(OperationMeta operationMeta) { - QueueMetrics metricsData = new QueueMetrics(); - metricsData.setQueueStartTime(System.currentTimeMillis()); - metricsData.setOperQualifiedName(operationMeta.getMicroserviceQualifiedName()); - QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() - .getOrCreateQueueMetrics(operationMeta.getMicroserviceQualifiedName()); - reqQueue.incrementCountInQueue(); - return metricsData; - } - - /** - * Update the queue metrics. - */ - private void updateMetrics() { - QueueMetrics metricsData = (QueueMetrics) this.invocation.getMetricsData(); - if (null != metricsData) { - metricsData.setQueueEndTime(System.currentTimeMillis()); - QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() - .getOrCreateQueueMetrics(restOperationMeta.getOperationMeta().getMicroserviceQualifiedName()); - reqQueue.incrementTotalCount(); - Long timeInQueue = metricsData.getQueueEndTime() - metricsData.getQueueStartTime(); - reqQueue.setTotalTime(reqQueue.getTotalTime() + timeInQueue); - reqQueue.setMinLifeTimeInQueue(timeInQueue); - reqQueue.setMaxLifeTimeInQueue(timeInQueue); - reqQueue.decrementCountInQueue(); - } + protected OperationLocator locateOperation(ServicePathManager servicePathManager) { + return servicePathManager.producerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod()); } - /** - * Prepare the end time of queue metrics. - */ - private void endMetrics() { - QueueMetrics metricsData = (QueueMetrics) this.invocation.getMetricsData(); - if (null != metricsData) { - metricsData.setEndOperTime(System.currentTimeMillis()); - QueueMetricsData reqQueue = MetricsServoRegistry.getOrCreateLocalMetrics() - .getOrCreateQueueMetrics(restOperationMeta.getOperationMeta().getMicroserviceQualifiedName()); - reqQueue.incrementTotalServExecutionCount(); - reqQueue.setTotalServExecutionTime( - reqQueue.getTotalServExecutionTime() + (metricsData.getEndOperTime() - metricsData.getQueueEndTime())); - } + @Override + protected void createInvocation(Object[] args) { + this.invocation = InvocationFactory.forProvider(transport.getEndpoint(), + restOperationMeta.getOperationMeta(), + args); } } diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java index 0304acc49c7..105dd9fbd13 100644 --- a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java +++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestAbstractRestInvocation.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; import javax.ws.rs.core.Response.Status; import javax.xml.ws.Holder; @@ -27,24 +28,38 @@ import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import io.servicecomb.common.rest.codec.RestCodec; import io.servicecomb.common.rest.codec.produce.ProduceProcessorManager; import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; +import io.servicecomb.common.rest.locator.OperationLocator; +import io.servicecomb.common.rest.locator.ServicePathManager; import io.servicecomb.core.Const; +import io.servicecomb.core.Endpoint; +import io.servicecomb.core.Handler; import io.servicecomb.core.Invocation; +import io.servicecomb.core.definition.MicroserviceMeta; +import io.servicecomb.core.definition.MicroserviceMetaManager; import io.servicecomb.core.definition.OperationMeta; import io.servicecomb.core.definition.SchemaMeta; +import io.servicecomb.core.executor.ReactiveExecutor; import io.servicecomb.core.provider.consumer.ReferenceConfig; import io.servicecomb.foundation.common.utils.JsonUtils; +import io.servicecomb.foundation.metrics.performance.QueueMetrics; +import io.servicecomb.foundation.vertx.http.AbstractHttpServletRequest; import io.servicecomb.foundation.vertx.http.HttpServletRequestEx; import io.servicecomb.foundation.vertx.http.HttpServletResponseEx; +import io.servicecomb.swagger.invocation.AsyncResponse; import io.servicecomb.swagger.invocation.Response; import io.servicecomb.swagger.invocation.exception.CommonExceptionData; import io.servicecomb.swagger.invocation.exception.InvocationException; import io.servicecomb.swagger.invocation.response.Headers; import io.vertx.core.buffer.Buffer; +import mockit.Deencapsulation; import mockit.Expectations; import mockit.Mock; import mockit.MockUp; @@ -60,6 +75,9 @@ public class TestAbstractRestInvocation { @Mocked ReferenceConfig endpoint; + @Mocked + MicroserviceMetaManager microserviceMetaManager; + @Mocked SchemaMeta schemaMeta; @@ -74,11 +92,22 @@ public class TestAbstractRestInvocation { Invocation invocation; - AbstractRestInvocation restInvocation = new AbstractRestInvocation() { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + class AbstractRestInvocationForTest extends AbstractRestInvocation { @Override - protected void doInvoke() throws Throwable { + protected OperationLocator locateOperation(ServicePathManager servicePathManager) { + return null; } - }; + + @Override + protected void createInvocation(Object[] args) { + this.invocation = TestAbstractRestInvocation.this.invocation; + } + } + + AbstractRestInvocation restInvocation = new AbstractRestInvocationForTest(); @Before public void setup() { @@ -111,11 +140,7 @@ public void initProduceProcessorNull() { } }; - restInvocation = new AbstractRestInvocation() { - @Override - protected void doInvoke() throws Throwable { - } - + restInvocation = new AbstractRestInvocationForTest() { @Override public void sendFailResponse(Throwable throwable) { } @@ -199,7 +224,7 @@ public void invokeFilterHaveResponse(@Mocked HttpServerFilter filter) { }; Holder result = new Holder<>(); - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { result.value = Response.ok("not run to here"); @@ -228,7 +253,7 @@ public void invokeFilterNoResponse(@Mocked HttpServerFilter filter) { }; Holder result = new Holder<>(); - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { result.value = true; @@ -253,7 +278,7 @@ public void invokeFilterException(@Mocked HttpServerFilter filter) { }; Holder result = new Holder<>(); - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override public void sendFailResponse(Throwable throwable) { result.value = throwable; @@ -281,14 +306,13 @@ public void invokeNormal(@Mocked HttpServerFilter filter) { } }; - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { } @Override public void sendFailResponse(Throwable throwable) { - throwable.printStackTrace(); Assert.fail("must not fail"); } }; @@ -309,7 +333,7 @@ public void sendFailResponseNoProduceProcessor() { @Test public void sendFailResponseHaveProduceProcessor() { Holder result = new Holder<>(); - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { } @@ -331,7 +355,7 @@ protected void sendResponseQuietly(Response response) { @Test public void sendResponseQuietlyNormal(@Mocked Response response) { Holder result = new Holder<>(); - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { } @@ -350,7 +374,7 @@ protected void sendResponse(Response response) throws Exception { @Test public void sendResponseQuietlyException(@Mocked Response response) { - restInvocation = new AbstractRestInvocation() { + restInvocation = new AbstractRestInvocationForTest() { @Override protected void doInvoke() throws Throwable { } @@ -526,4 +550,212 @@ void beforeSendResponse(Invocation invocation, HttpServletResponseEx responseEx) restInvocation.sendResponse(response); Assert.assertEquals("\"ok\"-filter", buffer.toString()); } + + @Test + public void findRestOperationServicePathManagerNull(@Mocked MicroserviceMeta microserviceMeta) { + new Expectations(ServicePathManager.class) { + { + requestEx.getHeader(Const.TARGET_MICROSERVICE); + result = "ms"; + microserviceMetaManager.ensureFindValue("ms"); + result = microserviceMeta; + ServicePathManager.getServicePathManager(microserviceMeta); + result = null; + } + }; + + expectedException.expect(InvocationException.class); + expectedException.expectMessage("CommonExceptionData [message=Not Found]"); + restInvocation.findRestOperation(microserviceMeta); + } + + @Test + public void findRestOperationNormal(@Mocked MicroserviceMeta microserviceMeta, + @Mocked ServicePathManager servicePathManager, @Mocked OperationLocator locator) { + restInvocation = new AbstractRestInvocationForTest() { + @Override + protected OperationLocator locateOperation(ServicePathManager servicePathManager) { + return locator; + } + }; + + requestEx = new AbstractHttpServletRequest() { + }; + restInvocation.requestEx = requestEx; + Map pathVars = new HashMap<>(); + new Expectations(ServicePathManager.class) { + { + ServicePathManager.getServicePathManager(microserviceMeta); + result = servicePathManager; + locator.getPathVarMap(); + result = pathVars; + locator.getOperation(); + result = restOperation; + } + }; + + restInvocation.findRestOperation(microserviceMeta); + Assert.assertSame(restOperation, restInvocation.restOperationMeta); + Assert.assertSame(pathVars, requestEx.getAttribute(RestConst.PATH_PARAMETERS)); + } + + @Test + public void scheduleInvocationException(@Mocked OperationMeta operationMeta) { + Executor executor = new ReactiveExecutor(); + requestEx = new AbstractHttpServletRequest() { + }; + requestEx.setAttribute(RestConst.REST_REQUEST, requestEx); + new Expectations() { + { + restOperation.getOperationMeta(); + result = operationMeta; + operationMeta.getExecutor(); + result = executor; + operationMeta.getMicroserviceQualifiedName(); + result = "sayHi"; + } + }; + + Holder result = new Holder<>(); + Error error = new Error("run on executor"); + restInvocation = new AbstractRestInvocationForTest() { + @Override + protected void runOnExecutor(QueueMetrics metricsData) { + throw error; + } + + @Override + public void sendFailResponse(Throwable throwable) { + result.value = throwable; + } + }; + restInvocation.requestEx = requestEx; + restInvocation.restOperationMeta = restOperation; + + restInvocation.scheduleInvocation(); + + Assert.assertSame(error, result.value); + } + + @Test + public void scheduleInvocationTimeout(@Mocked OperationMeta operationMeta) { + Executor executor = cmd -> { + cmd.run(); + }; + + new Expectations() { + { + restOperation.getOperationMeta(); + result = operationMeta; + operationMeta.getExecutor(); + result = executor; + operationMeta.getMicroserviceQualifiedName(); + result = "sayHi"; + } + }; + + requestEx = new AbstractHttpServletRequest() { + }; + + restInvocation = new AbstractRestInvocationForTest() { + @Override + protected void runOnExecutor(QueueMetrics metricsData) { + throw new Error("run on executor"); + } + + @Override + public void sendFailResponse(Throwable throwable) { + throw (Error) throwable; + } + }; + restInvocation.requestEx = requestEx; + restInvocation.restOperationMeta = restOperation; + + // will not throw exception + restInvocation.scheduleInvocation(); + } + + @Test + public void scheduleInvocationNormal(@Mocked OperationMeta operationMeta) { + Executor executor = new ReactiveExecutor(); + requestEx = new AbstractHttpServletRequest() { + }; + requestEx.setAttribute(RestConst.REST_REQUEST, requestEx); + new Expectations() { + { + restOperation.getOperationMeta(); + result = operationMeta; + operationMeta.getExecutor(); + result = executor; + operationMeta.getMicroserviceQualifiedName(); + result = "sayHi"; + } + }; + + Holder result = new Holder<>(); + restInvocation = new AbstractRestInvocationForTest() { + @Override + protected void runOnExecutor(QueueMetrics metricsData) { + result.value = true; + } + }; + restInvocation.requestEx = requestEx; + restInvocation.restOperationMeta = restOperation; + + restInvocation.scheduleInvocation(); + + Assert.assertTrue(result.value); + } + + @Test + public void runOnExecutor() { + new Expectations(RestCodec.class) { + { + RestCodec.restToArgs(requestEx, restOperation); + result = null; + } + }; + + Holder result = new Holder<>(); + restInvocation = new AbstractRestInvocationForTest() { + @Override + public void invoke() { + result.value = true; + } + }; + restInvocation.requestEx = requestEx; + restInvocation.restOperationMeta = restOperation; + + restInvocation.runOnExecutor(null); + Assert.assertTrue(result.value); + Assert.assertSame(invocation, restInvocation.invocation); + } + + @Test + public void doInvoke(@Mocked Endpoint endpoint, @Mocked OperationMeta operationMeta, + @Mocked Object[] swaggerArguments, @Mocked SchemaMeta schemaMeta) throws Throwable { + Response response = Response.ok("ok"); + Handler handler = new Handler() { + @Override + public void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { + asyncResp.complete(response); + } + }; + List handlerChain = Arrays.asList(handler); + invocation.setMetricsData(null); + Deencapsulation.setField(invocation, "handlerList", handlerChain); + + Holder result = new Holder<>(); + restInvocation = new AbstractRestInvocationForTest() { + @Override + protected void sendResponseQuietly(Response response) { + result.value = response; + } + }; + restInvocation.invocation = invocation; + + restInvocation.doInvoke(); + + Assert.assertSame(response, result.value); + } } diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestRestProducerInvocation.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestRestProducerInvocation.java index bd6f6517485..77a2daa9390 100644 --- a/common/common-rest/src/test/java/io/servicecomb/common/rest/TestRestProducerInvocation.java +++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/TestRestProducerInvocation.java @@ -16,14 +16,10 @@ package io.servicecomb.common.rest; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Executor; - -import javax.xml.ws.Holder; import org.junit.After; import org.junit.Assert; @@ -32,30 +28,20 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import io.servicecomb.common.rest.codec.RestCodec; import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; import io.servicecomb.common.rest.locator.OperationLocator; import io.servicecomb.common.rest.locator.ServicePathManager; import io.servicecomb.core.Const; import io.servicecomb.core.CseContext; -import io.servicecomb.core.Endpoint; -import io.servicecomb.core.Handler; -import io.servicecomb.core.Invocation; import io.servicecomb.core.Transport; import io.servicecomb.core.definition.MicroserviceMeta; import io.servicecomb.core.definition.MicroserviceMetaManager; -import io.servicecomb.core.definition.OperationMeta; -import io.servicecomb.core.definition.SchemaMeta; -import io.servicecomb.core.executor.ReactiveExecutor; -import io.servicecomb.foundation.metrics.performance.QueueMetrics; import io.servicecomb.foundation.vertx.http.AbstractHttpServletRequest; import io.servicecomb.foundation.vertx.http.HttpServletRequestEx; import io.servicecomb.foundation.vertx.http.HttpServletResponseEx; import io.servicecomb.serviceregistry.RegistryUtils; import io.servicecomb.serviceregistry.api.registry.Microservice; -import io.servicecomb.swagger.invocation.AsyncResponse; -import io.servicecomb.swagger.invocation.Response; import io.servicecomb.swagger.invocation.exception.InvocationException; import mockit.Expectations; import mockit.Mock; @@ -120,7 +106,7 @@ void sendFailResponse(Throwable throwable) { } @Mock - RestOperationMeta findRestOperation() { + void findRestOperation() { throw expected; } @@ -139,8 +125,8 @@ void scheduleInvocation() { public void invokeNormal() { restProducerInvocation = new MockUp() { @Mock - RestOperationMeta findRestOperation() { - return restOperationMeta; + void findRestOperation() { + restProducerInvocation.restOperationMeta = restOperationMeta; } @Mock @@ -157,129 +143,6 @@ void scheduleInvocation() { Assert.assertSame(requestEx, requestEx.getAttribute(RestConst.REST_REQUEST)); } - @Test - public void scheduleInvocationNormal(@Mocked OperationMeta operationMeta) { - Executor executor = cmd -> { - cmd.run(); - }; - requestEx = new AbstractHttpServletRequest() { - }; - requestEx.setAttribute(RestConst.REST_REQUEST, requestEx); - new Expectations() { - { - restOperationMeta.getOperationMeta(); - result = operationMeta; - operationMeta.getExecutor(); - result = executor; - operationMeta.getMicroserviceQualifiedName(); - result = "sayHi"; - } - }; - - restProducerInvocation = new MockUp() { - @Mock - void runOnExecutor(QueueMetrics metricsData) { - runOnExecutor = true; - } - }.getMockInstance(); - initRestProducerInvocation(); - - restProducerInvocation.scheduleInvocation(); - - Assert.assertTrue(runOnExecutor); - - } - - @Test - public void scheduleInvocationTimeout(@Mocked OperationMeta operationMeta) { - Executor executor = cmd -> { - cmd.run(); - }; - - new Expectations() { - { - restOperationMeta.getOperationMeta(); - result = operationMeta; - operationMeta.getExecutor(); - result = executor; - operationMeta.getMicroserviceQualifiedName(); - result = "sayHi"; - } - }; - - requestEx = new AbstractHttpServletRequest() { - }; - - restProducerInvocation = new MockUp() { - @Mock - void runOnExecutor() { - runOnExecutor = true; - } - }.getMockInstance(); - initRestProducerInvocation(); - - restProducerInvocation.scheduleInvocation(); - - Assert.assertFalse(runOnExecutor); - - } - - @Test - public void scheduleInvocationException(@Mocked OperationMeta operationMeta) { - Executor executor = new ReactiveExecutor(); - Throwable e = new Exception("Param error"); - new Expectations(RestCodec.class) { - { - restOperationMeta.getOperationMeta(); - result = operationMeta; - operationMeta.getExecutor(); - result = executor; - operationMeta.getMicroserviceQualifiedName(); - result = "sayHi"; - requestEx.getAttribute(RestConst.REST_REQUEST); - result = requestEx; - RestCodec.restToArgs(requestEx, restOperationMeta); - result = e; - } - }; - - Holder result = new Holder<>(); - restProducerInvocation = new MockUp() { - @Mock - void sendFailResponse(Throwable throwable) { - result.value = throwable; - } - }.getMockInstance(); - - initRestProducerInvocation(); - restProducerInvocation.scheduleInvocation(); - - Assert.assertSame(e, result.value); - } - - @Test - public void runOnExecutor() { - Object[] args = new Object[] {}; - new Expectations(RestCodec.class) { - { - restOperationMeta.getOperationMeta().getMicroserviceQualifiedName(); - result = "sayHi"; - RestCodec.restToArgs(requestEx, restOperationMeta); - result = args; - } - }; - restProducerInvocation = new MockUp() { - @Mock - void invoke() { - invokeNoParam = true; - } - }.getMockInstance(); - initRestProducerInvocation(); - restProducerInvocation.runOnExecutor(new QueueMetrics()); - Assert.assertTrue(invokeNoParam); - Assert.assertSame(args, restProducerInvocation.invocation.getSwaggerArguments()); - } - @Test public void findRestOperationNameFromRegistry() { Microservice microservice = new Microservice(); @@ -304,26 +167,6 @@ public void findRestOperationNameFromRegistry() { restProducerInvocation.findRestOperation(); } - @Test - public void findRestOperationServicePathManagerNull(@Mocked MicroserviceMeta microserviceMeta) { - new Expectations(ServicePathManager.class) { - { - requestEx.getHeader(Const.TARGET_MICROSERVICE); - result = "ms"; - microserviceMetaManager.ensureFindValue("ms"); - result = microserviceMeta; - ServicePathManager.getServicePathManager(microserviceMeta); - result = null; - } - }; - restProducerInvocation = new RestProducerInvocation(); - initRestProducerInvocation(); - - expectedException.expect(InvocationException.class); - expectedException.expectMessage("CommonExceptionData [message=Not Found]"); - restProducerInvocation.findRestOperation(); - } - @Test public void findRestOperationNormal(@Mocked MicroserviceMeta microserviceMeta, @Mocked ServicePathManager servicePathManager, @Mocked OperationLocator locator) { @@ -361,46 +204,8 @@ public String getHeader(String name) { restProducerInvocation = new RestProducerInvocation(); initRestProducerInvocation(); - Assert.assertSame(restOperationMeta, restProducerInvocation.findRestOperation()); + restProducerInvocation.findRestOperation(); + Assert.assertSame(restOperationMeta, restProducerInvocation.restOperationMeta); Assert.assertSame(pathVars, requestEx.getAttribute(RestConst.PATH_PARAMETERS)); } - - @Test - public void doInvoke(@Mocked Endpoint endpoint, @Mocked OperationMeta operationMeta, - @Mocked Object[] swaggerArguments, @Mocked SchemaMeta schemaMeta) throws Throwable { - Response response = Response.ok("ok"); - Handler handler = new MockUp() { - @Mock - void handle(Invocation invocation, AsyncResponse asyncResp) throws Exception { - asyncResp.complete(response); - } - }.getMockInstance(); - List handlerChain = Arrays.asList(handler); - - new Expectations() { - { - operationMeta.getSchemaMeta(); - result = schemaMeta; - schemaMeta.getProviderHandlerChain(); - result = handlerChain; - operationMeta.getMicroserviceQualifiedName(); - result = "sayHi"; - } - }; - - Invocation invocation = new Invocation(endpoint, operationMeta, swaggerArguments); - - Holder result = new Holder<>(); - restProducerInvocation = new RestProducerInvocation() { - protected void sendResponseQuietly(Response response) { - result.value = response; - } - }; - initRestProducerInvocation(); - invocation.setMetricsData(new QueueMetrics()); - restProducerInvocation.invocation = invocation; - restProducerInvocation.doInvoke(); - - Assert.assertSame(response, result.value); - } } From d352be215ed804c8ecc45bbba171cd6b3e6190c5 Mon Sep 17 00:00:00 2001 From: wujimin Date: Thu, 23 Nov 2017 14:50:32 +0800 Subject: [PATCH 3/5] JAV-524 RestServletProducerInvocation follow new parent method usage --- .../rest/servlet/RestServletProducerInvocation.java | 7 ++----- .../rest/servlet/TestRestServletProducerInvocation.java | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/transports/transport-rest/transport-rest-servlet/src/main/java/io/servicecomb/transport/rest/servlet/RestServletProducerInvocation.java b/transports/transport-rest/transport-rest-servlet/src/main/java/io/servicecomb/transport/rest/servlet/RestServletProducerInvocation.java index 934965097a4..ccc6fdcbc95 100644 --- a/transports/transport-rest/transport-rest-servlet/src/main/java/io/servicecomb/transport/rest/servlet/RestServletProducerInvocation.java +++ b/transports/transport-rest/transport-rest-servlet/src/main/java/io/servicecomb/transport/rest/servlet/RestServletProducerInvocation.java @@ -17,20 +17,17 @@ package io.servicecomb.transport.rest.servlet; import io.servicecomb.common.rest.RestProducerInvocation; -import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; import io.servicecomb.core.definition.OperationMeta; import io.servicecomb.foundation.vertx.http.StandardHttpServletRequestEx; public class RestServletProducerInvocation extends RestProducerInvocation { @Override - protected RestOperationMeta findRestOperation() { - RestOperationMeta restOperationMeta = super.findRestOperation(); + protected void findRestOperation() { + super.findRestOperation(); boolean cacheRequest = collectCacheRequest(restOperationMeta.getOperationMeta()); ((StandardHttpServletRequestEx) requestEx).setCacheRequest(cacheRequest); - - return restOperationMeta; } protected boolean collectCacheRequest(OperationMeta operationMeta) { diff --git a/transports/transport-rest/transport-rest-servlet/src/test/java/io/servicecomb/transport/rest/servlet/TestRestServletProducerInvocation.java b/transports/transport-rest/transport-rest-servlet/src/test/java/io/servicecomb/transport/rest/servlet/TestRestServletProducerInvocation.java index 20bf7f7efc6..03d0a8a6b89 100644 --- a/transports/transport-rest/transport-rest-servlet/src/test/java/io/servicecomb/transport/rest/servlet/TestRestServletProducerInvocation.java +++ b/transports/transport-rest/transport-rest-servlet/src/test/java/io/servicecomb/transport/rest/servlet/TestRestServletProducerInvocation.java @@ -53,8 +53,8 @@ public void findRestOperationCacheTrue(@Mocked HttpServletRequest request, @Mock new MockUp() { @Mock - RestOperationMeta findRestOperation() { - return restOperationMeta; + void findRestOperation() { + Deencapsulation.setField(getMockInstance(), "restOperationMeta", restOperationMeta); } }; From 8477edfba9b56a1ee359bdcfa3aa90b397dae40e Mon Sep 17 00:00:00 2001 From: wujimin Date: Thu, 23 Nov 2017 15:26:05 +0800 Subject: [PATCH 4/5] JAV-524 EdgeInvocation reuse executor logic --- .../servicecomb/edge/core/EdgeInvocation.java | 73 +---- .../edge/core/TestEdgeInvocation.java | 295 +++--------------- 2 files changed, 53 insertions(+), 315 deletions(-) diff --git a/edge/edge-core/src/main/java/io/servicecomb/edge/core/EdgeInvocation.java b/edge/edge-core/src/main/java/io/servicecomb/edge/core/EdgeInvocation.java index bf3069c2491..43d9d23bad8 100644 --- a/edge/edge-core/src/main/java/io/servicecomb/edge/core/EdgeInvocation.java +++ b/edge/edge-core/src/main/java/io/servicecomb/edge/core/EdgeInvocation.java @@ -17,11 +17,9 @@ package io.servicecomb.edge.core; import java.util.List; -import java.util.Map; import io.servicecomb.common.rest.AbstractRestInvocation; import io.servicecomb.common.rest.RestConst; -import io.servicecomb.common.rest.codec.RestCodec; import io.servicecomb.common.rest.filter.HttpServerFilter; import io.servicecomb.common.rest.locator.OperationLocator; import io.servicecomb.common.rest.locator.ServicePathManager; @@ -36,8 +34,6 @@ import io.servicecomb.serviceregistry.RegistryUtils; import io.servicecomb.serviceregistry.consumer.MicroserviceVersionRule; import io.servicecomb.serviceregistry.definition.DefinitionConst; -import io.servicecomb.swagger.invocation.Response; -import io.servicecomb.swagger.invocation.exception.InvocationException; import io.vertx.ext.web.RoutingContext; public class EdgeInvocation extends AbstractRestInvocation { @@ -57,32 +53,14 @@ public void init(String microserviceName, RoutingContext context, String path, this.requestEx = new VertxServerRequestToHttpServletRequest(context, path); this.responseEx = new VertxServerResponseToHttpServletResponse(context.response()); this.httpServerFilters = httpServerFilters; + requestEx.setAttribute(RestConst.REST_REQUEST, requestEx); } - @Override - public void invoke() { + public void edgeInvoke() { findMicroserviceVersionMeta(); + findRestOperation(latestMicroserviceVersionMeta.getMicroserviceMeta()); - ClassLoader orgClassLoader = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(latestMicroserviceVersionMeta.getMicroserviceMeta().getClassLoader()); - try { - // not handle edge unknown exception - // all unknow exception will be handled by io.servicecomb.edge.core.AbstractEdgeDispatcher.onFailure(RoutingContext) - prepareEdgeInvoke(); - Response response = prepareInvoke(); - if (response != null) { - sendResponse(response); - return; - } - - doInvoke(); - } catch (InvocationException e) { - sendFailResponse(e); - } catch (Throwable e) { - throw new ServiceCombException("unknown edge exception.", e); - } finally { - Thread.currentThread().setContextClassLoader(orgClassLoader); - } + scheduleInvocation(); } protected void findMicroserviceVersionMeta() { @@ -126,48 +104,21 @@ protected String chooseVersionRule() { return versionRule; } - protected void prepareEdgeInvoke() throws Throwable { + @Override + protected OperationLocator locateOperation(ServicePathManager servicePathManager) { + return servicePathManager.consumerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod()); + } + + @Override + protected void createInvocation(Object[] args) { ReferenceConfig referenceConfig = new ReferenceConfig(); referenceConfig.setMicroserviceMeta(latestMicroserviceVersionMeta.getMicroserviceMeta()); referenceConfig.setMicroserviceVersionRule(microserviceVersionRule.getVersionRule().getVersionRule()); referenceConfig.setTransport(Const.ANY_TRANSPORT); - ServicePathManager servicePathManager = - ServicePathManager.getServicePathManager(latestMicroserviceVersionMeta.getMicroserviceMeta()); - if (servicePathManager == null) { - throw new ServiceCombException(String.format("no schema defined for %s:%s", - latestMicroserviceVersionMeta.getMicroserviceMeta().getAppId(), - latestMicroserviceVersionMeta.getMicroserviceMeta().getName())); - } - - OperationLocator locator = - servicePathManager.consumerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod()); - this.restOperationMeta = locator.getOperation(); - - Map pathParams = locator.getPathVarMap(); - requestEx.setAttribute(RestConst.PATH_PARAMETERS, pathParams); - - Object args[] = RestCodec.restToArgs(requestEx, restOperationMeta); this.invocation = InvocationFactory.forConsumer(referenceConfig, restOperationMeta.getOperationMeta(), args); - } - - @Override - protected void doInvoke() { - invocation.setResponseExecutor(new ReactiveResponseExecutor()); - invocation.getOperationMeta().getExecutor().execute(() -> { - doInvokeInExecutor(); - }); - } - - protected void doInvokeInExecutor() { - try { - invocation.next(resp -> { - sendResponseQuietly(resp); - }); - } catch (Throwable e) { - sendFailResponse(e); - } + this.invocation.setResponseExecutor(new ReactiveResponseExecutor()); } } diff --git a/edge/edge-core/src/test/java/io/servicecomb/edge/core/TestEdgeInvocation.java b/edge/edge-core/src/test/java/io/servicecomb/edge/core/TestEdgeInvocation.java index f889f8e1d83..bd547a50be5 100644 --- a/edge/edge-core/src/test/java/io/servicecomb/edge/core/TestEdgeInvocation.java +++ b/edge/edge-core/src/test/java/io/servicecomb/edge/core/TestEdgeInvocation.java @@ -16,15 +16,11 @@ package io.servicecomb.edge.core; -import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import javax.ws.rs.core.Response.Status; -import javax.xml.ws.Holder; - import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; @@ -32,19 +28,13 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import io.servicecomb.common.rest.RestConst; -import io.servicecomb.common.rest.codec.RestCodec; import io.servicecomb.common.rest.definition.RestOperationMeta; import io.servicecomb.common.rest.filter.HttpServerFilter; import io.servicecomb.common.rest.locator.OperationLocator; import io.servicecomb.common.rest.locator.ServicePathManager; -import io.servicecomb.core.Handler; import io.servicecomb.core.Invocation; import io.servicecomb.core.definition.MicroserviceMeta; import io.servicecomb.core.definition.MicroserviceVersionMeta; -import io.servicecomb.core.definition.OperationMeta; -import io.servicecomb.core.definition.SchemaMeta; -import io.servicecomb.core.executor.ReactiveExecutor; import io.servicecomb.core.provider.consumer.ReactiveResponseExecutor; import io.servicecomb.core.provider.consumer.ReferenceConfig; import io.servicecomb.foundation.common.exceptions.ServiceCombException; @@ -56,8 +46,6 @@ import io.servicecomb.serviceregistry.consumer.AppManager; import io.servicecomb.serviceregistry.consumer.MicroserviceVersionRule; import io.servicecomb.serviceregistry.definition.DefinitionConst; -import io.servicecomb.swagger.invocation.Response; -import io.servicecomb.swagger.invocation.exception.InvocationException; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.impl.HttpServerRequestWrapperForTest; import mockit.Deencapsulation; @@ -101,75 +89,31 @@ public void setup() { } @Test - public void prepareEdgeInvokeNoPath(@Mocked MicroserviceVersionMeta microserviceVersionMeta) throws Throwable { - edgeInvocation.latestMicroserviceVersionMeta = microserviceVersionMeta; - edgeInvocation.microserviceVersionRule = new MicroserviceVersionRule("app", "ms", "1.0.0"); - - new Expectations(ServicePathManager.class) { - { - microserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - ServicePathManager.getServicePathManager(microserviceMeta); - result = null; - } - }; - - expectedException.expect(ServiceCombException.class); - expectedException.expectMessage("no schema defined for app:app:ms"); - - edgeInvocation.prepareEdgeInvoke(); - } - - @Test - public void prepareEdgeInvokeNormal(@Mocked MicroserviceVersionMeta microserviceVersionMeta, - @Mocked ServicePathManager servicePathManager, @Mocked OperationLocator locator, - @Mocked RestOperationMeta restOperationMeta) throws Throwable { - edgeInvocation.latestMicroserviceVersionMeta = microserviceVersionMeta; - edgeInvocation.microserviceVersionRule = new MicroserviceVersionRule("app", "ms", "1.0.0"); - - Microservice microservice = new Microservice(); - microservice.setServiceName(microserviceName); - new Expectations(RegistryUtils.class) { - { - microserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - RegistryUtils.getMicroservice(); - result = microservice; + public void edgeInvoke(@Mocked MicroserviceVersionMeta microserviceVersionMeta) { + Map result = new LinkedHashMap<>(); + edgeInvocation = new EdgeInvocation() { + @Override + protected void findMicroserviceVersionMeta() { + result.put("findMicroserviceVersionMeta", true); } - }; - Object args[] = new Object[0]; - new Expectations(RestCodec.class) { - { - RestCodec.restToArgs(requestEx, restOperationMeta); - result = args; + @Override + protected void findRestOperation(MicroserviceMeta microserviceMeta) { + result.put("findRestOperation", true); } - }; - Map pathParams = new HashMap<>(); - new Expectations(ServicePathManager.class) { - { - ServicePathManager.getServicePathManager(microserviceMeta); - result = servicePathManager; - servicePathManager.consumerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod()); - result = locator; - locator.getOperation(); - result = restOperationMeta; - locator.getPathVarMap(); - result = pathParams; + @Override + protected void scheduleInvocation() { + result.put("scheduleInvocation", true); } }; + edgeInvocation.latestMicroserviceVersionMeta = microserviceVersionMeta; - edgeInvocation.prepareEdgeInvoke(); + edgeInvocation.edgeInvoke(); - Assert.assertSame(pathParams, requestEx.getAttribute(RestConst.PATH_PARAMETERS)); - Invocation invocation = Deencapsulation.getField(edgeInvocation, "invocation"); - Assert.assertSame(args, invocation.getSwaggerArguments()); - } - - @Test - public void chooseVersionRule() { - Assert.assertEquals(DefinitionConst.VERSION_RULE_ALL, edgeInvocation.chooseVersionRule()); + Assert.assertTrue(result.get("findMicroserviceVersionMeta")); + Assert.assertTrue(result.get("findRestOperation")); + Assert.assertTrue(result.get("scheduleInvocation")); } @Test @@ -226,207 +170,50 @@ public void findMicroserviceVersionMetaNormal(@Mocked AppManager appManager, Assert.assertSame(latestMicroserviceVersionMeta, edgeInvocation.latestMicroserviceVersionMeta); } - class EdgeInvocationForTestClassLoader extends EdgeInvocation { - ClassLoader findMicroserviceVersionMetaClassLoader; - - ClassLoader prepareEdgeInvokeClassLoader; - - ClassLoader prepareInvokeClassLoader; - - ClassLoader doInvokeClassLoader; - - ClassLoader doSendFailResponse; - - RuntimeException doInvokeException; - - Throwable doInvocationException; - - @Override - protected void findMicroserviceVersionMeta() { - findMicroserviceVersionMetaClassLoader = Thread.currentThread().getContextClassLoader(); - } - - @Override - protected void prepareEdgeInvoke() throws Throwable { - prepareEdgeInvokeClassLoader = Thread.currentThread().getContextClassLoader(); - if (doInvocationException != null) { - throw doInvocationException; - } - } - - @Override - protected Response prepareInvoke() throws Throwable { - prepareInvokeClassLoader = Thread.currentThread().getContextClassLoader(); - return null; - } - - @Override - protected void doInvoke() { - if (doInvokeException != null) { - throw doInvokeException; - } - - doInvokeClassLoader = Thread.currentThread().getContextClassLoader(); - } - - @Override - public void sendFailResponse(Throwable throwable) { - doSendFailResponse = Thread.currentThread().getContextClassLoader(); - } - } - @Test - public void invokeNormal(@Mocked MicroserviceVersionMeta latestMicroserviceVersionMeta, - @Mocked MicroserviceMeta microserviceMeta) { - ClassLoader org = Thread.currentThread().getContextClassLoader(); - ClassLoader microserviceClassLoader = new ClassLoader() { - }; - - new Expectations() { - { - latestMicroserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - microserviceMeta.getClassLoader(); - result = microserviceClassLoader; - } - }; - EdgeInvocationForTestClassLoader invocation = new EdgeInvocationForTestClassLoader(); - invocation.latestMicroserviceVersionMeta = latestMicroserviceVersionMeta; - - invocation.invoke(); - - Assert.assertSame(org, invocation.findMicroserviceVersionMetaClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.prepareEdgeInvokeClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.prepareInvokeClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.doInvokeClassLoader); - Assert.assertSame(org, Thread.currentThread().getContextClassLoader()); + public void chooseVersionRule_default() { + Assert.assertEquals(DefinitionConst.VERSION_RULE_ALL, edgeInvocation.chooseVersionRule()); } @Test - public void invokePrepareHaveResponse(@Mocked MicroserviceVersionMeta latestMicroserviceVersionMeta, - @Mocked MicroserviceMeta microserviceMeta, @Mocked Response response) { - ClassLoader microserviceClassLoader = new ClassLoader() { - }; + public void chooseVersionRule_set() { + String versionRule = "1.0.0"; + edgeInvocation.setVersionRule(versionRule); - new Expectations() { - { - latestMicroserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - microserviceMeta.getClassLoader(); - result = microserviceClassLoader; - } - }; - - Holder result = new Holder<>(); - EdgeInvocationForTestClassLoader invocation = new EdgeInvocationForTestClassLoader() { - @Override - protected Response prepareInvoke() throws Throwable { - return response; - } - - @Override - protected void sendResponse(Response response) throws Exception { - result.value = response; - } - - @Override - protected void doInvoke() { - result.value = Response.ok("do not run to here"); - } - }; - invocation.latestMicroserviceVersionMeta = latestMicroserviceVersionMeta; - - invocation.invoke(); - - Assert.assertSame(response, result.value); + Assert.assertEquals(versionRule, edgeInvocation.chooseVersionRule()); } @Test - public void invocationException(@Mocked MicroserviceVersionMeta latestMicroserviceVersionMeta, - @Mocked MicroserviceMeta microserviceMeta) { - ClassLoader org = Thread.currentThread().getContextClassLoader(); - ClassLoader microserviceClassLoader = new ClassLoader() { - }; - + public void locateOperation(@Mocked ServicePathManager servicePathManager, + @Mocked OperationLocator operationLocator) { new Expectations() { { - latestMicroserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - microserviceMeta.getClassLoader(); - result = microserviceClassLoader; + servicePathManager.consumerLocateOperation(anyString, anyString); + result = operationLocator; } }; - Throwable doInvocationException = new InvocationException(Status.NOT_FOUND, "Not Found"); - - EdgeInvocationForTestClassLoader invocation = new EdgeInvocationForTestClassLoader(); - invocation.latestMicroserviceVersionMeta = latestMicroserviceVersionMeta; - invocation.doInvocationException = doInvocationException; - - invocation.invoke(); - - Assert.assertSame(org, invocation.findMicroserviceVersionMetaClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.prepareEdgeInvokeClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.doSendFailResponse); - Assert.assertSame(null, invocation.prepareInvokeClassLoader); - Assert.assertSame(null, invocation.doInvokeClassLoader); - Assert.assertSame(org, Thread.currentThread().getContextClassLoader()); + Assert.assertSame(operationLocator, edgeInvocation.locateOperation(servicePathManager)); } @Test - public void invokeException(@Mocked MicroserviceVersionMeta latestMicroserviceVersionMeta, - @Mocked MicroserviceMeta microserviceMeta) { - ClassLoader org = Thread.currentThread().getContextClassLoader(); - ClassLoader microserviceClassLoader = new ClassLoader() { - }; - - new Expectations() { - { - latestMicroserviceVersionMeta.getMicroserviceMeta(); - result = microserviceMeta; - microserviceMeta.getClassLoader(); - result = microserviceClassLoader; - } - }; - - RuntimeException doInvokeException = new RuntimeException(); - - EdgeInvocationForTestClassLoader invocation = new EdgeInvocationForTestClassLoader(); - invocation.latestMicroserviceVersionMeta = latestMicroserviceVersionMeta; - invocation.doInvokeException = doInvokeException; - - expectedException.expect(ServiceCombException.class); - expectedException.expectMessage(Matchers.is("unknown edge exception.")); - expectedException.expectCause(Matchers.sameInstance(doInvokeException)); - - invocation.invoke(); - - Assert.assertSame(org, invocation.findMicroserviceVersionMetaClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.prepareEdgeInvokeClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.prepareInvokeClassLoader); - Assert.assertSame(microserviceClassLoader, invocation.doInvokeClassLoader); - Assert.assertSame(org, Thread.currentThread().getContextClassLoader()); - } + public void createInvocation(@Mocked MicroserviceVersionMeta microserviceVersionMeta, + @Mocked MicroserviceVersionRule microserviceVersionRule, @Mocked RestOperationMeta restOperationMeta, + @Mocked Microservice microservice) { + edgeInvocation.latestMicroserviceVersionMeta = microserviceVersionMeta; + edgeInvocation.microserviceVersionRule = microserviceVersionRule; + Deencapsulation.setField(edgeInvocation, "restOperationMeta", restOperationMeta); - @Test - public void doInvoke(@Mocked SchemaMeta schemaMeta, @Mocked OperationMeta operationMeta, @Mocked Handler handler) - throws Throwable { - new Expectations() { + Object[] args = new Object[] {}; + new Expectations(RegistryUtils.class) { { - operationMeta.getExecutor(); - result = new ReactiveExecutor(); - operationMeta.getSchemaMeta(); - result = schemaMeta; - schemaMeta.getConsumerHandlerChain(); - result = Arrays.asList(handler); + RegistryUtils.getMicroservice(); + result = microservice; } }; - Invocation invocation = new Invocation(referenceConfig, operationMeta, null); - Deencapsulation.setField(edgeInvocation, "invocation", invocation); - - edgeInvocation.doInvoke(); - + edgeInvocation.createInvocation(args); + Invocation invocation = Deencapsulation.getField(edgeInvocation, "invocation"); Assert.assertThat(invocation.getResponseExecutor(), Matchers.instanceOf(ReactiveResponseExecutor.class)); } } From a4b90cb3b87ce17f7a4753432dd686ed28b9fa3f Mon Sep 17 00:00:00 2001 From: wujimin Date: Thu, 23 Nov 2017 15:26:36 +0800 Subject: [PATCH 5/5] JAV-524 change edge demo to use new method --- .../java/io/servicecomb/demo/edge/service/EdgeDispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/demo-edge/edge-service/src/main/java/io/servicecomb/demo/edge/service/EdgeDispatcher.java b/demo/demo-edge/edge-service/src/main/java/io/servicecomb/demo/edge/service/EdgeDispatcher.java index 58e3c9d2f24..fc09c99041a 100644 --- a/demo/demo-edge/edge-service/src/main/java/io/servicecomb/demo/edge/service/EdgeDispatcher.java +++ b/demo/demo-edge/edge-service/src/main/java/io/servicecomb/demo/edge/service/EdgeDispatcher.java @@ -51,6 +51,6 @@ protected void onRequest(RoutingContext context) { edgeInvocation.setVersionRule(versionMapper.getOrCreate(pathVersion).getVersionRule()); edgeInvocation.init(microserviceName, context, path, httpServerFilters); - edgeInvocation.invoke(); + edgeInvocation.edgeInvoke(); } }