[
https://issues.apache.org/jira/browse/SCB-881?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16611456#comment-16611456
]
ASF GitHub Bot commented on SCB-881:
------------------------------------
liubao68 closed pull request #900: [SCB-881] More invocation stage measurement
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/900
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
index 88d524aea..09b7fc72c 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
@@ -49,11 +49,12 @@
import org.slf4j.LoggerFactory;
public abstract class AbstractRestInvocation {
-
private static final Logger LOGGER =
LoggerFactory.getLogger(AbstractRestInvocation.class);
public static final String UNKNOWN_OPERATION_ID = "UNKNOWN_OPERATION";
+ protected long start;
+
protected RestOperationMeta restOperationMeta;
protected Invocation invocation;
@@ -66,6 +67,10 @@
protected List<HttpServerFilter> httpServerFilters = Collections.emptyList();
+ public AbstractRestInvocation() {
+ this.start = System.nanoTime();
+ }
+
public void setHttpServerFilters(List<HttpServerFilter> httpServerFilters) {
this.httpServerFilters = httpServerFilters;
}
@@ -118,7 +123,8 @@ protected void scheduleInvocation() {
return;
}
- invocation.onStart(requestEx);
+ invocation.onStart(requestEx, start);
+ invocation.getInvocationStageTrace().startSchedule();
OperationMeta operationMeta = restOperationMeta.getOperationMeta();
operationMeta.getExecutor().execute(() -> {
@@ -146,12 +152,12 @@ protected void scheduleInvocation() {
}
private boolean isInQueueTimeout() {
- return System.nanoTime() - invocation.getStartTime() >
+ return System.nanoTime() - invocation.getInvocationStageTrace().getStart()
>
CommonRestConfig.getRequestWaitInPoolTimeout() * 1_000_000;
}
protected void runOnExecutor() {
- invocation.onStartExecute();
+ invocation.onExecuteStart();
invoke();
}
@@ -181,6 +187,7 @@ protected Response prepareInvoke() throws Throwable {
this.setContext();
invocation.getHandlerContext().put(RestConst.REST_REQUEST, requestEx);
+ invocation.getInvocationStageTrace().startServerFiltersRequest();
for (HttpServerFilter filter : httpServerFilters) {
Response response = filter.afterReceiveRequest(invocation, requestEx);
if (response != null) {
@@ -192,6 +199,7 @@ protected Response prepareInvoke() throws Throwable {
}
protected void doInvoke() throws Throwable {
+ invocation.getInvocationStageTrace().startHandlersRequest();
invocation.next(resp -> {
sendResponseQuietly(resp);
});
@@ -207,6 +215,9 @@ public void sendFailResponse(Throwable throwable) {
}
protected void sendResponseQuietly(Response response) {
+ if (invocation != null) {
+ invocation.getInvocationStageTrace().finishHandlersResponse();
+ }
try {
sendResponse(response);
} catch (Throwable e) {
@@ -239,6 +250,10 @@ protected void executeHttpServerFilters(Response response)
{
new HttpServerFilterBeforeSendResponseExecutor(httpServerFilters,
invocation, responseEx);
CompletableFuture<Void> future = exec.run();
future.whenComplete((v, e) -> {
+ if (invocation != null) {
+ invocation.getInvocationStageTrace().finishServerFiltersResponse();
+ }
+
onExecuteHttpServerFiltersFinish(response, e);
});
}
diff --git
a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
index dcc6110f8..f0b2513c9 100644
---
a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
+++
b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
@@ -123,10 +123,19 @@ protected void createInvocation() {
AbstractRestInvocation restInvocation = new AbstractRestInvocationForTest();
+ static long nanoTime = 123;
+
@BeforeClass
public static void classSetup() {
EventManager.eventBus = new EventBus();
SCBEngine.getInstance().setStatus(SCBStatus.UP);
+
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
}
@AfterClass
@@ -359,6 +368,8 @@ public void sendFailResponse(Throwable throwable) {
restInvocation.httpServerFilters = Arrays.asList(filter);
restInvocation.invoke();
+
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartServerFiltersRequest());
}
@Test
@@ -463,6 +474,24 @@ protected void sendResponse(Response response) {
// just log, check nothing, and should not throw NPE
}
+ @Test
+ public void executeHttpServerFiltersNullInvocation(@Mocked Response
response) {
+ Holder<Boolean> flag = new Holder<>();
+ restInvocation = new AbstractRestInvocationForTest() {
+ @Override
+ protected void onExecuteHttpServerFiltersFinish(Response response,
Throwable e) {
+ super.onExecuteHttpServerFiltersFinish(response, e);
+ flag.value = true;
+ }
+ };
+ initRestInvocation();
+ restInvocation.invocation = null;
+
+ restInvocation.executeHttpServerFilters(response);
+
+ Assert.assertTrue(flag.value);
+ }
+
@Test
public void sendResponseStatusAndContentTypeAndHeader(@Mocked Response
response) {
new Expectations() {
@@ -633,6 +662,7 @@ void setBodyBuffer(Buffer bodyBuffer) {
restInvocation.sendResponse(response);
Assert.assertEquals("\"ok\"", buffer.toString());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishServerFiltersResponse());
}
@Test
@@ -806,13 +836,6 @@ public void sendFailResponse(Throwable throwable) {
@Test
public void scheduleInvocationNormal(@Mocked OperationMeta operationMeta) {
- long time = 123;
- new MockUp<System>() {
- @Mock
- long nanoTime() {
- return time;
- }
- };
Holder<InvocationStartEvent> eventHolder = new Holder<>();
Object subscriber = new Object() {
@Subscribe
@@ -850,7 +873,8 @@ protected void runOnExecutor() {
EventManager.unregister(subscriber);
Assert.assertTrue(result.value);
- Assert.assertEquals(time, invocation.getStartTime());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStart());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartSchedule());
Assert.assertSame(invocation, eventHolder.value.getInvocation());
Assert.assertEquals("tid", invocation.getTraceId());
}
@@ -880,7 +904,7 @@ public void invoke() {
Assert.assertTrue(result.value);
Assert.assertSame(invocation, restInvocation.invocation);
- Assert.assertEquals(time, invocation.getStartExecutionTime());
+ Assert.assertEquals(time,
invocation.getInvocationStageTrace().getStartExecution());
}
@Test
@@ -899,7 +923,7 @@ public void handle(Invocation invocation, AsyncResponse
asyncResp) {
Holder<Response> result = new Holder<>();
restInvocation = new AbstractRestInvocationForTest() {
@Override
- protected void sendResponseQuietly(Response response) {
+ protected void sendResponse(Response response) {
result.value = response;
}
};
@@ -908,5 +932,7 @@ protected void sendResponseQuietly(Response response) {
restInvocation.doInvoke();
Assert.assertSame(response, result.value);
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishHandlersResponse());
}
}
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index ceb5f928e..97cc86920 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -25,8 +25,11 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
+import org.apache.servicecomb.core.event.InvocationBusinessMethodFinishEvent;
+import org.apache.servicecomb.core.event.InvocationBusinessMethodStartEvent;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.InvocationStartEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
import org.apache.servicecomb.core.tracing.TraceIdGenerator;
import org.apache.servicecomb.foundation.common.event.EventManager;
@@ -68,18 +71,26 @@
// 同步模式:避免应答在网络线程中处理解码等等业务级逻辑
private Executor responseExecutor;
- private long startTime;
-
- private long startExecutionTime;
-
private boolean sync = true;
+ private InvocationStageTrace invocationStageTrace = new
InvocationStageTrace(this);
+
private HttpServletRequestEx requestEx;
+ private boolean finished;
+
+ // not extend InvocationType
+ // because isEdge() only affect to apm/metrics output, no need to change so
many logic
+ private boolean edge;
+
public HttpServletRequestEx getRequestEx() {
return requestEx;
}
+ public InvocationStageTrace getInvocationStageTrace() {
+ return invocationStageTrace;
+ }
+
public String getTraceId() {
return getContext(Const.TRACE_ID_NAME);
}
@@ -88,12 +99,14 @@ public String getTraceId(String traceIdName) {
return getContext(traceIdName);
}
+ @Deprecated
public long getStartTime() {
- return startTime;
+ return invocationStageTrace.getStart();
}
+ @Deprecated
public long getStartExecutionTime() {
- return startExecutionTime;
+ return invocationStageTrace.getStartExecution();
}
public Invocation(ReferenceConfig referenceConfig, OperationMeta
operationMeta, Object[] swaggerArguments) {
@@ -242,23 +255,50 @@ protected void initTraceId(TraceIdGenerator
traceIdGenerator) {
addContext(traceIdGenerator.getTraceIdKeyName(),
traceIdGenerator.generate());
}
- public void onStart() {
- this.startTime = System.nanoTime();
+ public void onStart(long start) {
+ invocationStageTrace.start(start);
initTraceId();
EventManager.post(new InvocationStartEvent(this));
}
- public void onStart(HttpServletRequestEx requestEx) {
+ public void onStart(HttpServletRequestEx requestEx, long start) {
this.requestEx = requestEx;
- onStart();
+ onStart(start);
+ }
+
+ public void onExecuteStart() {
+ invocationStageTrace.startExecution();
+ }
+
+ @Override
+ public void onBusinessMethodStart() {
+ invocationStageTrace.startBusinessMethod();
+ EventManager.post(new InvocationBusinessMethodStartEvent(this));
}
- public void onStartExecute() {
- this.startExecutionTime = System.nanoTime();
+ @Override
+ public void onBusinessMethodFinish() {
+ EventManager.post(new InvocationBusinessMethodFinishEvent(this));
+ }
+
+ @Override
+ public void onBusinessFinish() {
+ invocationStageTrace.finishBusiness();
}
public void onFinish(Response response) {
+ if (finished) {
+ // avoid to post repeated event
+ return;
+ }
+
+ invocationStageTrace.finish();
EventManager.post(new InvocationFinishEvent(this, response));
+ finished = true;
+ }
+
+ public boolean isFinished() {
+ return finished;
}
public boolean isSync() {
@@ -272,4 +312,12 @@ public void setSync(boolean sync) {
public boolean isConsumer() {
return InvocationType.CONSUMER.equals(invocationType);
}
+
+ public boolean isEdge() {
+ return edge;
+ }
+
+ public void setEdge(boolean edge) {
+ this.edge = edge;
+ }
}
diff --git a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
index 15b4ee9e1..4be7e7c7b 100644
--- a/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
+++ b/core/src/main/java/org/apache/servicecomb/core/SCBEngine.java
@@ -80,6 +80,10 @@
private volatile SCBStatus status = SCBStatus.DOWN;
+ private EventBus eventBus = EventManager.getEventBus();
+
+ private static final SCBEngine INSTANCE = new SCBEngine();
+
public void setStatus(SCBStatus status) {
this.status = status;
}
@@ -88,10 +92,6 @@ public SCBStatus getStatus() {
return status;
}
- private EventBus eventBus = EventManager.getEventBus();
-
- private static final SCBEngine INSTANCE = new SCBEngine();
-
public static SCBEngine getInstance() {
return INSTANCE;
}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationBaseEvent.java
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBaseEvent.java
new file mode 100644
index 000000000..6914b31f9
--- /dev/null
+++
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBaseEvent.java
@@ -0,0 +1,31 @@
+/*
+ * 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.core.event;
+
+import org.apache.servicecomb.core.Invocation;
+
+public class InvocationBaseEvent {
+ private Invocation invocation;
+
+ public InvocationBaseEvent(Invocation invocation) {
+ this.invocation = invocation;
+ }
+
+ public Invocation getInvocation() {
+ return invocation;
+ }
+}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodFinishEvent.java
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodFinishEvent.java
new file mode 100644
index 000000000..c4419afb8
--- /dev/null
+++
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodFinishEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.core.event;
+
+import org.apache.servicecomb.core.Invocation;
+
+public class InvocationBusinessMethodFinishEvent extends InvocationBaseEvent {
+ public InvocationBusinessMethodFinishEvent(Invocation invocation) {
+ super(invocation);
+ }
+}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodStartEvent.java
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodStartEvent.java
new file mode 100644
index 000000000..0594ae98a
--- /dev/null
+++
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationBusinessMethodStartEvent.java
@@ -0,0 +1,25 @@
+/*
+ * 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.core.event;
+
+import org.apache.servicecomb.core.Invocation;
+
+public class InvocationBusinessMethodStartEvent extends InvocationBaseEvent {
+ public InvocationBusinessMethodStartEvent(Invocation invocation) {
+ super(invocation);
+ }
+}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationFinishEvent.java
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationFinishEvent.java
index d611f7678..7122b9975 100644
---
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationFinishEvent.java
+++
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationFinishEvent.java
@@ -19,16 +19,14 @@
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.swagger.invocation.Response;
-public class InvocationFinishEvent {
+public class InvocationFinishEvent extends InvocationBaseEvent {
private long nanoCurrent;
- private Invocation invocation;
-
private Response response;
public InvocationFinishEvent(Invocation invocation, Response response) {
- this.nanoCurrent = System.nanoTime();
- this.invocation = invocation;
+ super(invocation);
+ this.nanoCurrent = invocation.getInvocationStageTrace().getFinish();
this.response = response;
}
@@ -36,10 +34,6 @@ public long getNanoCurrent() {
return nanoCurrent;
}
- public Invocation getInvocation() {
- return invocation;
- }
-
public Response getResponse() {
return response;
}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
index e83c4470e..2caf8c373 100644
---
a/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
+++
b/core/src/main/java/org/apache/servicecomb/core/event/InvocationStartEvent.java
@@ -18,14 +18,8 @@
import org.apache.servicecomb.core.Invocation;
-public class InvocationStartEvent {
- private Invocation invocation;
-
+public class InvocationStartEvent extends InvocationBaseEvent {
public InvocationStartEvent(Invocation invocation) {
- this.invocation = invocation;
- }
-
- public Invocation getInvocation() {
- return invocation;
+ super(invocation);
}
}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
new file mode 100644
index 000000000..6cf6aa26d
--- /dev/null
+++
b/core/src/main/java/org/apache/servicecomb/core/invocation/InvocationStageTrace.java
@@ -0,0 +1,353 @@
+/*
+ * 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.core.invocation;
+
+import org.apache.servicecomb.core.Invocation;
+
+/**
+ * <pre>
+ * important:
+ * all time point is about invocation stage, not java method
+ * all time is nanoTime
+ * not all stage relate to a event, currently, we only have 4 event:
+ * start/finish/startBusiness/finishBusiness
+ *
+ * for consumer:
+ * start -> startHandlersRequest -> startClientFiltersRequest -> startSend
-> finishGetConnection -> finishWriteToBuffer
+ *
/
+ *
\/
+ * finish <- finishHandlersResponse <- finishClientFiltersResponse <-
startClientFiltersResponse <- finishReceiveResponse
+ *
+ * for producer:
+ * ? ->
+ * start -> startSchedule -> startExecution -> startServerFiltersRequest ->
startHandlersRequest -> startBusinessMethod-----
+ *
|
+ *
\/
+ * finish <- finishWriteToBuffer <- finishServerFiltersResponse <-
finishHandlersResponse <- finishBusiness <- finishBusinessMethod
+ * for edge:
+ * ? ->
+ * start -> startSchedule -> startExecution -> startServerFiltersRequest --
+ * /
+ * ------------------------------------------------------------------
+ * /
+ * ---> startHandlersRequest -> startClientFiltersRequest -> startSend ->
finishGetConnection -> finishWriteToBuffer
+ *
/
+ *
\/
+ * finishHandlersResponse <- finishClientFiltersResponse <-
startClientFiltersResponse <- finishReceiveResponse
+ * |
+ * \/
+ * finish <- finishServerFiltersResponse
+ * </pre>
+ */
+public class InvocationStageTrace {
+ public static final String PREPARE = "prepare";
+
+ public static final String HANDLERS_REQUEST = "handlers request";
+
+ public static final String HANDLERS_RESPONSE = "handlers response";
+
+ public static final String CLIENT_FILTERS_REQUEST = "client filters request";
+
+ public static final String CONSUMER_SEND_REQUEST = "send request";
+
+ public static final String CONSUMER_GET_CONNECTION = "get connection";
+
+ public static final String CONSUMER_WRITE_TO_BUF = "write to buf";
+
+ public static final String CONSUMER_WAIT_RESPONSE = "wait response";
+
+ public static final String CONSUMER_WAKE_CONSUMER = "wake consumer";
+
+ public static final String CLIENT_FILTERS_RESPONSE = "client filters
response";
+
+ public static final String THREAD_POOL_QUEUE = "threadPoolQueue";
+
+ public static final String SERVER_FILTERS_REQUEST = "server filters request";
+
+ public static final String SERVER_FILTERS_RESPONSE = "server filters
response";
+
+ public static final String PRODUCER_SEND_RESPONSE = "send response";
+
+ private Invocation invocation;
+
+ private long start;
+
+ private long startHandlersRequest;
+
+ private long startClientFiltersRequest;
+
+ // only for consumer
+ private long startSend;
+
+ // only for consumer
+ private long finishGetConnection;
+
+ // only for consumer
+ private long finishWriteToBuffer;
+
+ // only for consumer
+ private long finishReceiveResponse;
+
+ private long startClientFiltersResponse;
+
+ private long finishClientFiltersResponse;
+
+ private long finishHandlersResponse;
+
+ private long finish;
+
+ // only for producer: put producer task to thread pool
+ private long startSchedule;
+
+ private long startServerFiltersRequest;
+
+ private long finishServerFiltersResponse;
+
+ // only for producer: start execute in work thread
+ // for reactive mode, work thread is eventloop
+ private long startExecution;
+
+ // only for producer
+ private long startBusinessMethod;
+
+ // only for producer
+ private long finishBusiness;
+
+ public InvocationStageTrace(Invocation invocation) {
+ this.invocation = invocation;
+ }
+
+ public void start(long start) {
+ this.start = start;
+ }
+
+ public long getStart() {
+ return start;
+ }
+
+ public long getStartHandlersRequest() {
+ return startHandlersRequest;
+ }
+
+ public void startHandlersRequest() {
+ this.startHandlersRequest = System.nanoTime();
+ }
+
+ public long getStartClientFiltersRequest() {
+ return startClientFiltersRequest;
+ }
+
+ public void startClientFiltersRequest() {
+ this.startClientFiltersRequest = System.nanoTime();
+ }
+
+ public long getStartSchedule() {
+ return startSchedule;
+ }
+
+ public void startSchedule() {
+ this.startSchedule = System.nanoTime();
+ }
+
+ public long getStartExecution() {
+ return startExecution;
+ }
+
+ public void startExecution() {
+ this.startExecution = System.nanoTime();
+ }
+
+ public long getStartSend() {
+ return startSend;
+ }
+
+ public void startSend() {
+ this.startSend = System.nanoTime();
+ }
+
+ public long getFinishGetConnection() {
+ return finishGetConnection;
+ }
+
+ public void finishGetConnection(long finishGetConnection) {
+ this.finishGetConnection = finishGetConnection;
+ }
+
+ public long getFinishWriteToBuffer() {
+ return finishWriteToBuffer;
+ }
+
+ public void finishWriteToBuffer(long finishWriteToBuffer) {
+ this.finishWriteToBuffer = finishWriteToBuffer;
+ }
+
+ public long getFinishReceiveResponse() {
+ return finishReceiveResponse;
+ }
+
+ public void finishReceiveResponse() {
+ this.finishReceiveResponse = System.nanoTime();
+ }
+
+ public long getStartClientFiltersResponse() {
+ return startClientFiltersResponse;
+ }
+
+ public void startClientFiltersResponse() {
+ this.startClientFiltersResponse = System.nanoTime();
+ }
+
+ public long getFinishClientFiltersResponse() {
+ return finishClientFiltersResponse;
+ }
+
+ public void finishClientFiltersResponse() {
+ this.finishClientFiltersResponse = System.nanoTime();
+ }
+
+ public long getFinishHandlersResponse() {
+ return finishHandlersResponse;
+ }
+
+ public void finishHandlersResponse() {
+ this.finishHandlersResponse = System.nanoTime();
+ }
+
+ public long getStartServerFiltersRequest() {
+ return startServerFiltersRequest;
+ }
+
+ public void startServerFiltersRequest() {
+ this.startServerFiltersRequest = System.nanoTime();
+ }
+
+ public long getFinishServerFiltersResponse() {
+ return finishServerFiltersResponse;
+ }
+
+ public void finishServerFiltersResponse() {
+ this.finishServerFiltersResponse = System.nanoTime();
+ }
+
+ public long getStartBusinessMethod() {
+ return startBusinessMethod;
+ }
+
+ public void startBusinessMethod() {
+ this.startBusinessMethod = System.nanoTime();
+ }
+
+ public long getFinishBusiness() {
+ return finishBusiness;
+ }
+
+ public void finishBusiness() {
+ this.finishBusiness = System.nanoTime();
+ }
+
+ public long getFinish() {
+ return finish;
+ }
+
+ public void finish() {
+ this.finish = System.nanoTime();
+ }
+
+ private double calc(long finish, long start) {
+ if (finish == 0) {
+ return Double.NaN;
+ }
+
+ return finish - start;
+ }
+
+ public double calcTotalTime() {
+ return calc(finish, start);
+ }
+
+ public double calcInvocationPrepareTime() {
+ if (invocation.isConsumer() && !invocation.isEdge()) {
+ return calc(startHandlersRequest, start);
+ }
+
+ return calc(startSchedule, start);
+ }
+
+ public double calcHandlersRequestTime() {
+ if (invocation.isConsumer()) {
+ return calc(startClientFiltersRequest, startHandlersRequest);
+ }
+
+ return calc(startBusinessMethod, startHandlersRequest);
+ }
+
+ public double calcClientFiltersRequestTime() {
+ return calc(startSend, startClientFiltersRequest);
+ }
+
+ public double calcServerFiltersRequestTime() {
+ return calc(startHandlersRequest, startServerFiltersRequest);
+ }
+
+ public double calcSendRequestTime() {
+ return calc(finishWriteToBuffer, startSend);
+ }
+
+ public double calcGetConnectionTime() {
+ return calc(finishGetConnection, startSend);
+ }
+
+ public double calcWriteToBufferTime() {
+ return calc(finishWriteToBuffer, finishGetConnection);
+ }
+
+ public double calcReceiveResponseTime() {
+ return calc(finishReceiveResponse, finishWriteToBuffer);
+ }
+
+ public double calcWakeConsumer() {
+ return calc(startClientFiltersResponse, finishReceiveResponse);
+ }
+
+ public double calcClientFiltersResponseTime() {
+ return calc(finishClientFiltersResponse, startClientFiltersResponse);
+ }
+
+ public double calcServerFiltersResponseTime() {
+ return calc(finishServerFiltersResponse, finishHandlersResponse);
+ }
+
+ public double calcHandlersResponseTime() {
+ if (invocation.isConsumer()) {
+ return calc(finishHandlersResponse, finishClientFiltersResponse);
+ }
+
+ return calc(finishHandlersResponse, finishBusiness);
+ }
+
+ public double calcThreadPoolQueueTime() {
+ return calc(startExecution, startSchedule);
+ }
+
+ public double calcBusinessTime() {
+ return calc(finishBusiness, startBusinessMethod);
+ }
+
+ public double calcSendResponseTime() {
+ return calc(finish, finishServerFiltersResponse);
+ }
+}
diff --git
a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
index 2fef648d3..17ffcb219 100644
---
a/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
+++
b/core/src/main/java/org/apache/servicecomb/core/provider/consumer/InvokerUtils.java
@@ -65,13 +65,15 @@ public static Object syncInvoke(Invocation invocation)
throws InvocationExceptio
*/
public static Response innerSyncInvoke(Invocation invocation) {
try {
- invocation.onStart();
+ invocation.onStart(null, System.nanoTime());
SyncResponseExecutor respExecutor = new SyncResponseExecutor();
invocation.setResponseExecutor(respExecutor);
+ invocation.getInvocationStageTrace().startHandlersRequest();
invocation.next(respExecutor::setResponse);
Response response = respExecutor.waitResponse();
+ invocation.getInvocationStageTrace().finishHandlersResponse();
invocation.onFinish(response);
return response;
} catch (Throwable e) {
@@ -92,15 +94,17 @@ public static Response innerSyncInvoke(Invocation
invocation) {
*/
public static void reactiveInvoke(Invocation invocation, AsyncResponse
asyncResp) {
try {
- invocation.onStart();
+ invocation.onStart(null, System.nanoTime());
invocation.setSync(false);
ReactiveResponseExecutor respExecutor = new ReactiveResponseExecutor();
invocation.setResponseExecutor(respExecutor);
+ invocation.getInvocationStageTrace().startHandlersRequest();
invocation.next(ar -> {
ContextUtils.setInvocationContext(invocation.getParentContext());
try {
+ invocation.getInvocationStageTrace().finishHandlersResponse();
invocation.onFinish(ar);
asyncResp.handle(ar);
} finally {
@@ -108,6 +112,7 @@ public static void reactiveInvoke(Invocation invocation,
AsyncResponse asyncResp
}
});
} catch (Throwable e) {
+ invocation.getInvocationStageTrace().finishHandlersResponse();
//if throw exception,we can use 500 for status code ?
Response response = Response.createConsumerFail(e);
invocation.onFinish(response);
diff --git
a/core/src/main/java/org/apache/servicecomb/core/transport/AbstractTransport.java
b/core/src/main/java/org/apache/servicecomb/core/transport/AbstractTransport.java
index ff5370afd..519fc1d0c 100644
---
a/core/src/main/java/org/apache/servicecomb/core/transport/AbstractTransport.java
+++
b/core/src/main/java/org/apache/servicecomb/core/transport/AbstractTransport.java
@@ -34,7 +34,6 @@
import
org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
import org.apache.servicecomb.foundation.common.net.NetUtils;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
-import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.serviceregistry.RegistryUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,7 +59,9 @@
private static final long DEFAULT_TIMEOUT_MILLIS = 30000;
// 所有transport使用同一个vertx实例,避免创建太多的线程
- protected Vertx transportVertx =
VertxUtils.getOrCreateVertxByName("transport", null);
+ public static TransportVertxFactory transportVertxFactory = new
TransportVertxFactory();
+
+ protected Vertx transportVertx = transportVertxFactory.getTransportVertx();
protected Endpoint endpoint;
diff --git
a/core/src/main/java/org/apache/servicecomb/core/transport/TransportVertxFactory.java
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportVertxFactory.java
new file mode 100644
index 000000000..3aa8ab1bb
--- /dev/null
+++
b/core/src/main/java/org/apache/servicecomb/core/transport/TransportVertxFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.core.transport;
+
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
+import
org.apache.servicecomb.foundation.vertx.metrics.DefaultVertxMetricsFactory;
+import org.apache.servicecomb.foundation.vertx.metrics.MetricsOptionsEx;
+
+import io.vertx.core.Vertx;
+import io.vertx.core.VertxOptions;
+
+public class TransportVertxFactory {
+ private VertxOptions vertxOptions = new VertxOptions();
+
+ private DefaultVertxMetricsFactory metricsFactory = new
DefaultVertxMetricsFactory();
+
+ private MetricsOptionsEx metricsOptionsEx = (MetricsOptionsEx)
metricsFactory.newOptions();
+
+ private Vertx transportVertx;
+
+ public TransportVertxFactory() {
+ vertxOptions.setMetricsOptions(metricsOptionsEx);
+ transportVertx = VertxUtils.getOrCreateVertxByName("transport",
vertxOptions);
+ }
+
+ public DefaultVertxMetricsFactory getMetricsFactory() {
+ return metricsFactory;
+ }
+
+ public Vertx getTransportVertx() {
+ return transportVertx;
+ }
+}
diff --git a/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java
b/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java
index c0e98b749..fb3e00103 100644
--- a/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java
+++ b/core/src/test/java/org/apache/servicecomb/core/TestInvocation.java
@@ -21,6 +21,9 @@
import javax.xml.ws.Holder;
import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.event.InvocationBaseEvent;
+import org.apache.servicecomb.core.event.InvocationBusinessMethodFinishEvent;
+import org.apache.servicecomb.core.event.InvocationBusinessMethodStartEvent;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
import org.apache.servicecomb.core.event.InvocationStartEvent;
import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
@@ -56,7 +59,7 @@
@Mocked
Object[] swaggerArguments;
- static long currentNanoTime = 123;
+ static long nanoTime = 123;
@BeforeClass
public static void classSetup() {
@@ -67,7 +70,7 @@ protected static void mockNonaTime() {
new MockUp<System>() {
@Mock
long nanoTime() {
- return currentNanoTime;
+ return nanoTime;
}
};
}
@@ -91,10 +94,10 @@ public void onStart(InvocationStartEvent event) {
EventManager.register(subscriber);
Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
- invocation.onStart();
+ invocation.onStart(nanoTime);
- Assert.assertEquals(currentNanoTime, result.value.getStartTime());
Assert.assertSame(invocation, result.value);
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStart());
EventManager.unregister(subscriber);
}
@@ -104,13 +107,13 @@ public void onStartExecute() {
mockNonaTime();
Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
- invocation.onStartExecute();
+ invocation.onExecuteStart();
- Assert.assertEquals(currentNanoTime, invocation.getStartExecutionTime());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartExecution());
}
@Test
- public void onFinish(@Mocked Response response) {
+ public void onFinish() {
mockNonaTime();
Holder<InvocationFinishEvent> result = new Holder<>();
@@ -123,11 +126,19 @@ public void onStart(InvocationFinishEvent event) {
EventManager.register(subscriber);
Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
+ Assert.assertFalse(invocation.isFinished());
+ Response response = Response.succResp(null);
invocation.onFinish(response);
- Assert.assertEquals(currentNanoTime, result.value.getNanoCurrent());
+ Assert.assertEquals(nanoTime, result.value.getNanoCurrent());
Assert.assertSame(invocation, result.value.getInvocation());
Assert.assertSame(response, result.value.getResponse());
+ Assert.assertTrue(invocation.isFinished());
+
+ // should not post event again
+ InvocationFinishEvent oldEvent = result.value;
+ invocation.onFinish(null);
+ Assert.assertSame(oldEvent, result.value);
EventManager.unregister(subscriber);
}
@@ -158,7 +169,7 @@ public void traceId_fromContext(@Mocked ReferenceConfig
referenceConfig) {
Invocation invocation = new Invocation(referenceConfig, operationMeta,
swaggerArguments);
invocation.addContext(Const.TRACE_ID_NAME, "abc");
- invocation.onStart();
+ invocation.onStart(0);
Assert.assertEquals("abc", invocation.getTraceId());
Assert.assertEquals("abc", invocation.getTraceId(Const.TRACE_ID_NAME));
@@ -175,7 +186,7 @@ public void traceId_consumerCreateTraceId(@Mocked
ReferenceConfig referenceConfi
};
Invocation invocation = new Invocation(referenceConfig, operationMeta,
swaggerArguments);
- invocation.onStart();
+ invocation.onStart(0);
Assert.assertEquals("abc", invocation.getTraceId());
Assert.assertEquals("abc", invocation.getTraceId(Const.TRACE_ID_NAME));
@@ -191,7 +202,7 @@ public void traceId_fromRequest(@Mocked Endpoint endpoint,
@Mocked HttpServletRe
};
Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
- invocation.onStart(requestEx);
+ invocation.onStart(requestEx, 0);
Assert.assertEquals("abc", invocation.getTraceId());
Assert.assertEquals("abc", invocation.getTraceId(Const.TRACE_ID_NAME));
@@ -208,7 +219,7 @@ public void traceId_producerCreateTraceId(@Mocked Endpoint
endpoint, @Mocked Htt
};
Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
- invocation.onStart(requestEx);
+ invocation.onStart(requestEx, 0);
Assert.assertEquals("abc", invocation.getTraceId());
Assert.assertEquals("abc", invocation.getTraceId(Const.TRACE_ID_NAME));
@@ -238,4 +249,49 @@ public void traceIdGeneratorInit(@Mocked TraceIdGenerator
gen1, @Mocked TraceIdG
Assert.assertThat(Invocation.loadTraceIdGenerators(),
Matchers.contains(gen1, gen3));
}
+
+ InvocationBaseEvent invocationBaseEvent;
+
+ @Test
+ public void onBusinessMethodStart() {
+ Object listener = new Object() {
+ @Subscribe
+ public void onBusinessMethodStart(InvocationBusinessMethodStartEvent
event) {
+ invocationBaseEvent = event;
+ }
+ };
+ EventManager.getEventBus().register(listener);
+ Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
+ mockNonaTime();
+ invocation.onBusinessMethodStart();
+ EventManager.getEventBus().unregister(listener);
+
+ Assert.assertSame(invocation, invocationBaseEvent.getInvocation());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ }
+
+ @Test
+ public void onBusinessMethodFinish() {
+ Object listener = new Object() {
+ @Subscribe
+ public void onBusinessMethodStart(InvocationBusinessMethodFinishEvent
event) {
+ invocationBaseEvent = event;
+ }
+ };
+ EventManager.getEventBus().register(listener);
+ Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
+ invocation.onBusinessMethodFinish();
+ EventManager.getEventBus().unregister(listener);
+
+ Assert.assertSame(invocation, invocationBaseEvent.getInvocation());
+ }
+
+ @Test
+ public void onBusinessFinish() {
+ Invocation invocation = new Invocation(endpoint, operationMeta,
swaggerArguments);
+ mockNonaTime();
+ invocation.onBusinessFinish();
+
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
+ }
}
diff --git a/core/src/test/java/org/apache/servicecomb/core/TestSCBEngine.java
b/core/src/test/java/org/apache/servicecomb/core/TestSCBEngine.java
index 6c1e6052d..7ad7ce489 100644
--- a/core/src/test/java/org/apache/servicecomb/core/TestSCBEngine.java
+++ b/core/src/test/java/org/apache/servicecomb/core/TestSCBEngine.java
@@ -168,7 +168,7 @@ public void bootEvent_refEngine() {
SCBEngine engine = new SCBEngine();
engine.setBootListenerList(Arrays.asList(event -> eventEngine.value =
event.getScbEngine()));
engine.triggerEvent(EventType.AFTER_REGISTRY);
-
+
Assert.assertNotNull(eventEngine.value);
}
}
diff --git
a/core/src/test/java/org/apache/servicecomb/core/definition/schema/TestProducerSchemaFactory.java
b/core/src/test/java/org/apache/servicecomb/core/definition/schema/TestProducerSchemaFactory.java
index 1ab53101d..f33b47d6e 100644
---
a/core/src/test/java/org/apache/servicecomb/core/definition/schema/TestProducerSchemaFactory.java
+++
b/core/src/test/java/org/apache/servicecomb/core/definition/schema/TestProducerSchemaFactory.java
@@ -19,6 +19,7 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
+import javax.ws.rs.core.Response.Status;
import javax.xml.ws.Holder;
import org.apache.servicecomb.core.Const;
@@ -42,6 +43,7 @@
import
org.apache.servicecomb.swagger.invocation.arguments.producer.ProducerArgumentsMapperFactory;
import org.apache.servicecomb.swagger.invocation.converter.ConverterMgr;
import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.hamcrest.Matchers;
import org.junit.AfterClass;
@@ -58,18 +60,35 @@
private static ProducerSchemaFactory producerSchemaFactory = new
ProducerSchemaFactory();
+ static boolean rejectAdd;
+
public static class TestProducerSchemaFactoryImpl {
public int add(int x, int y) {
+ if (rejectAdd) {
+ throw new Error("reject add");
+ }
return x + y;
}
- public CompletableFuture<String> async() {
- return null;
+ public CompletableFuture<String> asyncAdd(int x, int y) {
+ if (rejectAdd) {
+ throw new Error("reject add");
+ }
+ return CompletableFuture.completedFuture(String.valueOf(x + y));
}
}
+ static long nanoTime = 123;
+
@BeforeClass
public static void init() {
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
+
new UnitTestMeta();
ConverterMgr converterMgr = new ConverterMgr();
@@ -128,23 +147,37 @@ public String getInvocationQualifiedName() {
}
};
Holder<Response> holder = new Holder<>();
- producerOperation.invoke(invocation, resp -> {
- holder.value = resp;
- });
+ rejectAdd = false;
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
Assert.assertEquals(3, (int) holder.value.getResult());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
- invocation.setSwaggerArguments(new Object[] {1, 2});
- producerOperation.invoke(invocation, resp -> {
- holder.value = resp;
- });
+ nanoTime++;
+ rejectAdd = true;
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
Assert.assertEquals(true, holder.value.isFailed());
- InvocationException exception = (InvocationException)
holder.value.getResult();
+ InvocationException exception = holder.value.getResult();
CommonExceptionData data = (CommonExceptionData) exception.getErrorData();
+ Assert.assertEquals(ExceptionFactory.PRODUCER_INNER_STATUS_CODE,
exception.getStatusCode());
Assert.assertEquals("Cse Internal Server Error", data.getMessage());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
+
+ nanoTime++;
+ invocation.setSwaggerArguments(new Object[] {1, 2});
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
+ Assert.assertEquals(true, holder.value.isFailed());
+ exception = holder.value.getResult();
+ data = (CommonExceptionData) exception.getErrorData();
+ Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(),
exception.getStatusCode());
+ Assert.assertEquals("Parameters not valid or types not match.",
data.getMessage());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
}
@Test
- public void testGetOrCreateProducerWithPrefix() throws Exception {
+ public void testGetOrCreateProducerWithPrefix() {
ArchaiusUtils.setProperty(org.apache.servicecomb.serviceregistry.api.Const.REGISTER_URL_PREFIX,
"true");
System.setProperty(org.apache.servicecomb.serviceregistry.api.Const.URL_PREFIX,
"/pojo/test");
SchemaMeta schemaMeta =
producerSchemaFactory.getOrCreateProducerSchema("schema2",
@@ -160,11 +193,51 @@ public void testGetOrCreateProducerWithPrefix() throws
Exception {
}
@Test
- public void testCompletableFuture() {
- SchemaMeta schemaMeta =
producerSchemaFactory.getOrCreateProducerSchema("schema3",
+ public void testCompletableFuture() throws ClassNotFoundException,
IllegalAccessException, InstantiationException {
+ SchemaMeta schemaMeta =
producerSchemaFactory.getOrCreateProducerSchema("schema",
TestProducerSchemaFactoryImpl.class,
new TestProducerSchemaFactoryImpl());
- OperationMeta operationMeta = schemaMeta.ensureFindOperation("async");
+ OperationMeta operationMeta = schemaMeta.ensureFindOperation("asyncAdd");
Assert.assertThat(operationMeta.getExecutor(),
Matchers.instanceOf(ReactiveExecutor.class));
+
+ SwaggerProducerOperation producerOperation =
operationMeta.getExtData(Const.PRODUCER_OPERATION);
+ //we can not set microserviceName any more,use the default name
+ Object addBody =
Class.forName("cse.gen.app.perfClient.schema.asyncAddBody").newInstance();
+ ReflectUtils.setField(addBody, "x", 1);
+ ReflectUtils.setField(addBody, "y", 2);
+ Invocation invocation = new Invocation((Endpoint) null, operationMeta, new
Object[] {addBody}) {
+ @Override
+ public String getInvocationQualifiedName() {
+ return "";
+ }
+ };
+ Holder<Response> holder = new Holder<>();
+ rejectAdd = false;
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
+ Assert.assertEquals("3", holder.value.getResult());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
+
+ nanoTime++;
+ rejectAdd = true;
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
+ Assert.assertEquals(true, holder.value.isFailed());
+ InvocationException exception = holder.value.getResult();
+ CommonExceptionData data = (CommonExceptionData) exception.getErrorData();
+ Assert.assertEquals(ExceptionFactory.PRODUCER_INNER_STATUS_CODE,
exception.getStatusCode());
+ Assert.assertEquals("Cse Internal Server Error", data.getMessage());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
+
+ nanoTime++;
+ invocation.setSwaggerArguments(new Object[] {1, 2});
+ producerOperation.invoke(invocation, resp -> holder.value = resp);
+ Assert.assertEquals(true, holder.value.isFailed());
+ exception = holder.value.getResult();
+ data = (CommonExceptionData) exception.getErrorData();
+ Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(),
exception.getStatusCode());
+ Assert.assertEquals("Parameters not valid or types not match.",
data.getMessage());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartBusinessMethod());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishBusiness());
}
}
diff --git
a/core/src/test/java/org/apache/servicecomb/core/event/TestInvocationFinishEvent.java
b/core/src/test/java/org/apache/servicecomb/core/event/TestInvocationFinishEvent.java
index 5fe6b83d2..daae2d635 100644
---
a/core/src/test/java/org/apache/servicecomb/core/event/TestInvocationFinishEvent.java
+++
b/core/src/test/java/org/apache/servicecomb/core/event/TestInvocationFinishEvent.java
@@ -17,10 +17,12 @@
package org.apache.servicecomb.core.event;
import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.swagger.invocation.Response;
import org.junit.Assert;
import org.junit.Test;
+import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
@@ -30,6 +32,7 @@
@Test
public void construct(@Mocked Invocation invocation, @Mocked Response
response) {
+ InvocationStageTrace stageTrace = new InvocationStageTrace(invocation);
long time = 123;
new MockUp<System>() {
@Mock
@@ -37,6 +40,13 @@ long nanoTime() {
return time;
}
};
+ new Expectations() {
+ {
+ invocation.getInvocationStageTrace();
+ result = stageTrace;
+ }
+ };
+ stageTrace.finish();
event = new InvocationFinishEvent(invocation, response);
diff --git
a/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
new file mode 100644
index 000000000..64c468d50
--- /dev/null
+++
b/core/src/test/java/org/apache/servicecomb/core/invocation/TestInvocationStageTrace.java
@@ -0,0 +1,224 @@
+/*
+ * 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.core.invocation;
+
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.provider.consumer.ReferenceConfig;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestInvocationStageTrace {
+ Invocation invocation;
+
+ InvocationStageTrace stageTrace;
+
+ @Mocked
+ Endpoint endpoint;
+
+ @Mocked
+ ReferenceConfig referenceConfig;
+
+ @Mocked
+ OperationMeta operationMeta;
+
+ Object[] args = new Object[] {};
+
+ static long nanoTime = 0;
+
+ @BeforeClass
+ public static void classSetup() {
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
+ }
+
+ @Test
+ public void consumer() {
+ invocation = new Invocation(referenceConfig, operationMeta, args);
+ stageTrace = new InvocationStageTrace(invocation);
+
+ stageTrace.start(1);
+ nanoTime = 2;
+ stageTrace.startHandlersRequest();
+ nanoTime = 3;
+ stageTrace.startClientFiltersRequest();
+ nanoTime = 4;
+ stageTrace.startSend();
+ stageTrace.finishGetConnection(5);
+ stageTrace.finishWriteToBuffer(6);
+ nanoTime = 7;
+ stageTrace.finishReceiveResponse();
+ nanoTime = 8;
+ stageTrace.startClientFiltersResponse();
+ nanoTime = 9;
+ stageTrace.finishClientFiltersResponse();
+ nanoTime = 10;
+ stageTrace.finishHandlersResponse();
+ nanoTime = 11;
+ stageTrace.finish();
+
+ Assert.assertEquals(1, stageTrace.getStart());
+ Assert.assertEquals(2, stageTrace.getStartHandlersRequest());
+ Assert.assertEquals(3, stageTrace.getStartClientFiltersRequest());
+ Assert.assertEquals(4, stageTrace.getStartSend());
+ Assert.assertEquals(5, stageTrace.getFinishGetConnection());
+ Assert.assertEquals(6, stageTrace.getFinishWriteToBuffer());
+ Assert.assertEquals(7, stageTrace.getFinishReceiveResponse());
+ Assert.assertEquals(8, stageTrace.getStartClientFiltersResponse());
+ Assert.assertEquals(9, stageTrace.getFinishClientFiltersResponse());
+ Assert.assertEquals(10, stageTrace.getFinishHandlersResponse());
+ Assert.assertEquals(11, stageTrace.getFinish());
+
+ Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcClientFiltersRequestTime(), 0.1f);
+ Assert.assertEquals(2f, stageTrace.calcSendRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcGetConnectionTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcWriteToBufferTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcReceiveResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcWakeConsumer(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcClientFiltersResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+ Assert.assertEquals(10f, stageTrace.calcTotalTime(), 0.1f);
+ }
+
+ @Test
+ public void producer() {
+ invocation = new Invocation(endpoint, operationMeta, args);
+ stageTrace = new InvocationStageTrace(invocation);
+
+ stageTrace.start(1);
+ nanoTime = 2;
+ stageTrace.startSchedule();
+ nanoTime = 3;
+ stageTrace.startExecution();
+ nanoTime = 4;
+ stageTrace.startServerFiltersRequest();
+ nanoTime = 5;
+ stageTrace.startHandlersRequest();
+ nanoTime = 6;
+ stageTrace.startBusinessMethod();
+ nanoTime = 7;
+ stageTrace.finishBusiness();
+ nanoTime = 8;
+ stageTrace.finishHandlersResponse();
+ nanoTime = 9;
+ stageTrace.finishServerFiltersResponse();
+ nanoTime = 10;
+ stageTrace.finish();
+
+ Assert.assertEquals(1, stageTrace.getStart());
+ Assert.assertEquals(2, stageTrace.getStartSchedule());
+ Assert.assertEquals(3, stageTrace.getStartExecution());
+ Assert.assertEquals(4, stageTrace.getStartServerFiltersRequest());
+ Assert.assertEquals(5, stageTrace.getStartHandlersRequest());
+ Assert.assertEquals(6, stageTrace.getStartBusinessMethod());
+ Assert.assertEquals(7, stageTrace.getFinishBusiness());
+ Assert.assertEquals(8, stageTrace.getFinishHandlersResponse());
+ Assert.assertEquals(9, stageTrace.getFinishServerFiltersResponse());
+ Assert.assertEquals(10, stageTrace.getFinish());
+
+ Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcThreadPoolQueueTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcServerFiltersRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcBusinessTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcServerFiltersResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcSendResponseTime(), 0.1f);
+ Assert.assertEquals(9f, stageTrace.calcTotalTime(), 0.1f);
+ }
+
+ @Test
+ public void edge() {
+ invocation = new Invocation(referenceConfig, operationMeta, args);
+ stageTrace = new InvocationStageTrace(invocation);
+ invocation.setEdge(true);
+
+ stageTrace.start(1);
+ nanoTime = 2;
+ stageTrace.startSchedule();
+ nanoTime = 3;
+ stageTrace.startExecution();
+ nanoTime = 4;
+ stageTrace.startServerFiltersRequest();
+ nanoTime = 5;
+ stageTrace.startHandlersRequest();
+ nanoTime = 6;
+ stageTrace.startClientFiltersRequest();
+ nanoTime = 7;
+ stageTrace.startSend();
+ stageTrace.finishGetConnection(8);
+ stageTrace.finishWriteToBuffer(9);
+ nanoTime = 10;
+ stageTrace.finishReceiveResponse();
+ nanoTime = 11;
+ stageTrace.startClientFiltersResponse();
+ nanoTime = 12;
+ stageTrace.finishClientFiltersResponse();
+ nanoTime = 13;
+ stageTrace.finishHandlersResponse();
+ nanoTime = 14;
+ stageTrace.finishServerFiltersResponse();
+ nanoTime = 15;
+ stageTrace.finish();
+
+ Assert.assertEquals(1, stageTrace.getStart());
+ Assert.assertEquals(2, stageTrace.getStartSchedule());
+ Assert.assertEquals(3, stageTrace.getStartExecution());
+ Assert.assertEquals(4, stageTrace.getStartServerFiltersRequest());
+ Assert.assertEquals(5, stageTrace.getStartHandlersRequest());
+ Assert.assertEquals(6, stageTrace.getStartClientFiltersRequest());
+ Assert.assertEquals(7, stageTrace.getStartSend());
+ Assert.assertEquals(8, stageTrace.getFinishGetConnection());
+ Assert.assertEquals(9, stageTrace.getFinishWriteToBuffer());
+ Assert.assertEquals(10, stageTrace.getFinishReceiveResponse());
+ Assert.assertEquals(11, stageTrace.getStartClientFiltersResponse());
+ Assert.assertEquals(12, stageTrace.getFinishClientFiltersResponse());
+ Assert.assertEquals(13, stageTrace.getFinishHandlersResponse());
+ Assert.assertEquals(14, stageTrace.getFinishServerFiltersResponse());
+ Assert.assertEquals(15, stageTrace.getFinish());
+
+ Assert.assertEquals(1f, stageTrace.calcInvocationPrepareTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcThreadPoolQueueTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcServerFiltersRequestTime(), 0.1f);
+
+ Assert.assertEquals(1f, stageTrace.calcHandlersRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcClientFiltersRequestTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcGetConnectionTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcWriteToBufferTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcReceiveResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcWakeConsumer(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcClientFiltersResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcHandlersResponseTime(), 0.1f);
+
+ Assert.assertEquals(1f, stageTrace.calcServerFiltersResponseTime(), 0.1f);
+ Assert.assertEquals(1f, stageTrace.calcSendResponseTime(), 0.1f);
+
+ Assert.assertEquals(14f, stageTrace.calcTotalTime(), 0.1f);
+ }
+}
diff --git
a/core/src/test/java/org/apache/servicecomb/core/provider/consumer/TestInvokerUtils.java
b/core/src/test/java/org/apache/servicecomb/core/provider/consumer/TestInvokerUtils.java
index 04e32b20c..3ac309cdd 100644
---
a/core/src/test/java/org/apache/servicecomb/core/provider/consumer/TestInvokerUtils.java
+++
b/core/src/test/java/org/apache/servicecomb/core/provider/consumer/TestInvokerUtils.java
@@ -17,15 +17,19 @@
package org.apache.servicecomb.core.provider.consumer;
+import java.util.Arrays;
+
import javax.xml.ws.Holder;
import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.core.Handler;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.SCBEngine;
import org.apache.servicecomb.core.SCBStatus;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.definition.SchemaMeta;
import org.apache.servicecomb.core.invocation.InvocationFactory;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.context.ContextUtils;
@@ -34,6 +38,7 @@
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -49,8 +54,33 @@
@Rule
public ExpectedException expectedException = ExpectedException.none();
+ @Mocked
+ ReferenceConfig referenceConfig;
+
+ @Mocked
+ SchemaMeta schemaMeta;
+
+ @Mocked
+ OperationMeta operationMeta;
+
+ Invocation invocation;
+
+ static Object invokeResult;
+
SCBEngine scbEngine = new SCBEngine();
+ static long nanoTime = 1;
+
+ @BeforeClass
+ public static void classSetup() {
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
+ }
+
@Before
public void setup() {
new MockUp<SCBEngine>() {
@@ -60,34 +90,56 @@ SCBEngine getInstance() {
}
};
scbEngine.setStatus(SCBStatus.UP);
+
+ new Expectations() {
+ {
+ operationMeta.getSchemaMeta();
+ result = schemaMeta;
+ schemaMeta.getConsumerHandlerChain();
+ result = Arrays.asList((Handler) (i, ar) -> {
+ System.out.println(invokeResult);
+ ar.success(invokeResult);
+ });
+ }
+ };
+ invocation = new Invocation(referenceConfig, operationMeta, new Object[]
{});
}
@Test
public void testSyncInvokeInvocationWithException() {
Invocation invocation = Mockito.mock(Invocation.class);
+ InvocationStageTrace stageTrace = new InvocationStageTrace(invocation);
+ Mockito.when(invocation.getInvocationStageTrace()).thenReturn(stageTrace);
Response response = Mockito.mock(Response.class);
new MockUp<SyncResponseExecutor>() {
@Mock
public Response waitResponse() {
- return Mockito.mock(Response.class);
+ return response;
}
};
- Mockito.when(response.isSuccessed()).thenReturn(true);
+ Mockito.when(response.isSuccessed()).thenReturn(false);
OperationMeta operationMeta = Mockito.mock(OperationMeta.class);
Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
Mockito.when(operationMeta.getMicroserviceQualifiedName()).thenReturn("test");
- try {
- InvokerUtils.syncInvoke(invocation);
- } catch (InvocationException e) {
- Assert.assertEquals(490, e.getStatusCode());
- }
+ expectedException.expect(InvocationException.class);
+ expectedException.expect(Matchers.hasProperty("statusCode",
Matchers.is(490)));
+ InvokerUtils.syncInvoke(invocation);
+ }
+
+ @Test
+ public void testSyncInvokeNormal() {
+ invokeResult = 1;
+ Assert.assertEquals(1, (int) InvokerUtils.syncInvoke(invocation));
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getStart());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getFinishHandlersResponse());
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getFinish());
}
@Test
- public void testReactiveInvoke(@Mocked Invocation invocation, @Mocked
InvocationContext parentContext,
- @Mocked Response response) {
+ public void testReactiveInvoke(@Mocked InvocationContext parentContext,
@Mocked Response response) {
new MockUp<Invocation>(invocation) {
@Mock
InvocationContext getParentContext() {
@@ -105,6 +157,29 @@ void next(AsyncResponse asyncResp) {
Assert.assertNull(ContextUtils.getInvocationContext());
Assert.assertSame(parentContext, holder.value);
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getStart());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getFinishHandlersResponse());
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getFinish());
+ }
+
+ @Test
+ public void reactiveInvokeException() {
+ new MockUp<Invocation>(invocation) {
+ @Mock
+ void next(AsyncResponse asyncResp) {
+ throw new Error();
+ }
+ };
+
+ Holder<Response> holder = new Holder<>();
+ InvokerUtils.reactiveInvoke(invocation, ar -> holder.value = ar);
+
+ Assert.assertFalse(holder.value.isSuccessed());
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getStart());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(1,
invocation.getInvocationStageTrace().getFinishHandlersResponse());
+ Assert.assertEquals(1, invocation.getInvocationStageTrace().getFinish());
}
@SuppressWarnings("deprecation")
diff --git
a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
index e0aacfb5f..7490caa99 100644
---
a/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
+++
b/core/src/test/java/org/apache/servicecomb/core/transport/TestAbstractTransport.java
@@ -26,10 +26,12 @@
import org.apache.servicecomb.core.Invocation;
import
org.apache.servicecomb.foundation.common.exceptions.ServiceCombException;
import org.apache.servicecomb.foundation.common.net.IpPort;
+import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.serviceregistry.RegistryUtils;
import org.apache.servicecomb.serviceregistry.registry.AbstractServiceRegistry;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -81,6 +83,11 @@ public void teardown() {
RegistryUtils.setServiceRegistry(null);
}
+ @AfterClass
+ public static void classTeardown() {
+ VertxUtils.closeVertxByName("transport");
+ }
+
@Test
public void testSetListenAddressWithoutSchemaChineseSpaceNewSC() throws
UnsupportedEncodingException {
new Expectations() {
diff --git
a/core/src/test/java/org/apache/servicecomb/core/transport/TestTransportVertxFactory.java
b/core/src/test/java/org/apache/servicecomb/core/transport/TestTransportVertxFactory.java
new file mode 100644
index 000000000..aec2492b2
--- /dev/null
+++
b/core/src/test/java/org/apache/servicecomb/core/transport/TestTransportVertxFactory.java
@@ -0,0 +1,33 @@
+/*
+ * 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.core.transport;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestTransportVertxFactory {
+ @Test
+ public void getTransportVertx() {
+ TransportVertxFactory vertxFactory = new TransportVertxFactory();
+
+ Assert.assertNotNull(vertxFactory.getTransportVertx());
+ Assert.assertSame(vertxFactory.getTransportVertx(),
vertxFactory.getTransportVertx());
+ Assert.assertSame(vertxFactory.getTransportVertx(),
vertxFactory.getMetricsFactory().getVertxMetrics().getVertx());
+
+ vertxFactory.getTransportVertx().close();
+ }
+}
diff --git a/demo/perf/pom.xml b/demo/perf/pom.xml
index faf3d447d..92efc6dc4 100644
--- a/demo/perf/pom.xml
+++ b/demo/perf/pom.xml
@@ -52,7 +52,7 @@
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-redis-client</artifactId>
- <version>3.5.0</version>
+ <version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>org.apache.servicecomb</groupId>
diff --git
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
index 742762a46..fb885a5da 100644
---
a/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
+++
b/edge/edge-core/src/main/java/org/apache/servicecomb/edge/core/EdgeInvocation.java
@@ -127,6 +127,7 @@ protected void createInvocation() {
restOperationMeta.getOperationMeta(),
null);
this.invocation.setSync(false);
+ this.invocation.setEdge(true);
this.invocation.getHandlerContext().put(EDGE_INVOCATION_CONTEXT,
Vertx.currentContext());
this.invocation.setResponseExecutor(new ReactiveResponseExecutor());
this.routingContext.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
diff --git
a/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestEdgeInvocation.java
b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestEdgeInvocation.java
index 67a59d23d..538e97900 100644
---
a/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestEdgeInvocation.java
+++
b/edge/edge-core/src/test/java/org/apache/servicecomb/edge/core/TestEdgeInvocation.java
@@ -235,6 +235,7 @@ public void createInvocation(@Mocked
MicroserviceVersionMeta microserviceVersion
Invocation invocation = Deencapsulation.getField(edgeInvocation,
"invocation");
Assert.assertThat(invocation.getResponseExecutor(),
Matchers.instanceOf(ReactiveResponseExecutor.class));
Assert.assertFalse(invocation.isSync());
+ Assert.assertTrue(invocation.isEdge());
Assert.assertSame(context,
invocation.getHandlerContext().get(EdgeInvocation.EDGE_INVOCATION_CONTEXT));
}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java
index 4824f2aba..d979f1fd6 100644
---
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/AbstractTcpClientPackage.java
@@ -27,11 +27,21 @@ public static long getAndIncRequestId() {
return reqId.getAndIncrement();
}
+ private long finishWriteToBuffer;
+
protected long msgId = getAndIncRequestId();
public long getMsgId() {
return msgId;
}
+ public long getFinishWriteToBuffer() {
+ return finishWriteToBuffer;
+ }
+
+ public void finishWriteToBuffer() {
+ this.finishWriteToBuffer = System.nanoTime();
+ }
+
public abstract TcpOutputStream createStream();
}
diff --git
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java
index 95611f74e..4efb8eb91 100644
---
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java
+++
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/client/tcp/TcpClientConnection.java
@@ -132,6 +132,7 @@ private boolean writeToBufferQueue(AbstractTcpClientPackage
tcpClientPackage) {
// encode in sender thread
try (TcpOutputStream os = tcpClientPackage.createStream()) {
write(os.getByteBuf());
+ tcpClientPackage.finishWriteToBuffer();
}
return true;
}
@@ -156,6 +157,7 @@ private void writePackageInContext() {
try (TcpOutputStream os = pkg.createStream()) {
Buffer buf = os.getBuffer();
netSocket.write(buf);
+ pkg.finishWriteToBuffer();
}
}
}
diff --git
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java
index 550db4f75..d3c1edde9 100644
---
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java
+++
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/TestVertxUtils.java
@@ -48,7 +48,7 @@ public void testGetOrCreateVertx() throws
InterruptedException {
latch.await();
Assert.assertEquals(name.value, "ut-vert.x-eventloop-thread-0");
- vertx.close();
+ VertxUtils.closeVertxByName("ut");
}
@Test
diff --git
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
index 851fb916e..da606e067 100644
---
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
+++
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/AbortFaultTest.java
@@ -32,6 +32,7 @@
import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -67,6 +68,11 @@ public void after() {
ArchaiusUtils.resetConfig();
}
+ @AfterClass
+ public static void classTeardown() {
+ VertxUtils.closeVertxByName("faultinjectionTest");
+ }
+
@Test
public void injectFaultError() {
ArchaiusUtils
diff --git
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
index 71c17825b..7b5452d29 100644
---
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
+++
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/DelayFaultTest.java
@@ -33,6 +33,7 @@
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -68,6 +69,11 @@ public void after() {
ArchaiusUtils.resetConfig();
}
+ @AfterClass
+ public static void classTeardown() {
+ VertxUtils.closeVertxByName("faultinjectionTest");
+ }
+
@Test
public void injectFaultVertxDelay() throws InterruptedException {
ArchaiusUtils
diff --git
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
index d71f2ac57..bc5585c7c 100644
---
a/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
+++
b/handlers/handler-fault-injection/src/test/java/org/apache/servicecomb/faultinjection/TestFaultInjectHandler.java
@@ -34,6 +34,7 @@
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -97,6 +98,11 @@ public void tearDown() {
ArchaiusUtils.resetConfig();
}
+ @AfterClass
+ public static void classTeardown() {
+ VertxUtils.closeVertxByName("faultinjectionTest");
+ }
+
/**
* Tests the fault injection handler functionality with default values for
* highway transport.
diff --git
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
index d681525c8..c0ca9a082 100644
---
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
+++
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/junit/ITJUnitUtils.java
@@ -118,15 +118,15 @@ public static void run(Class<?>... classes) {
}
}
- public static void runWithHighwayAndRest(Class<?> classes) {
+ public static void runWithHighwayAndRest(Class<?>... classes) {
runWithTransports(Arrays.asList(Const.HIGHWAY, Const.RESTFUL), classes);
}
- public static void runWithRest(Class<?> classes) {
+ public static void runWithRest(Class<?>... classes) {
runWithTransports(Arrays.asList(Const.RESTFUL), classes);
}
- public static void runWithTransports(List<String> transports, Class<?>
classes) {
+ public static void runWithTransports(List<String> transports, Class<?>...
classes) {
for (String transport : transports) {
ITJUnitUtils.pushTransport(transport);
diff --git
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
index d2ae51043..b05200f94 100644
---
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
+++
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/AbstractInvocationMeter.java
@@ -34,6 +34,7 @@ public AbstractInvocationMeter(Registry registry, Id id,
Invocation invocation,
}
public void onInvocationFinish(InvocationFinishEvent event) {
- totalTimer.record(event.getNanoCurrent() -
event.getInvocation().getStartTime(), TimeUnit.NANOSECONDS);
+ totalTimer.record(event.getNanoCurrent() -
event.getInvocation().getInvocationStageTrace().getStart(),
+ TimeUnit.NANOSECONDS);
}
}
diff --git
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
index 11062659c..a8835c758 100644
---
a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
+++
b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/meter/invocation/ProducerInvocationMeter.java
@@ -45,7 +45,10 @@ public void onInvocationFinish(InvocationFinishEvent event) {
super.onInvocationFinish(event);
Invocation invocation = event.getInvocation();
- executorQueueTimer.record(invocation.getStartExecutionTime() -
invocation.getStartTime(), TimeUnit.NANOSECONDS);
- executionTimer.record(event.getNanoCurrent() -
invocation.getStartExecutionTime(), TimeUnit.NANOSECONDS);
+ executorQueueTimer.record(
+ invocation.getInvocationStageTrace().getStartExecution() -
invocation.getInvocationStageTrace().getStart(),
+ TimeUnit.NANOSECONDS);
+ executionTimer.record(event.getNanoCurrent() -
invocation.getInvocationStageTrace().getStartExecution(),
+ TimeUnit.NANOSECONDS);
}
}
diff --git
a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
index e990e9cd1..bc6f8771c 100644
---
a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
+++
b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/TestInvocationMetersInitializer.java
@@ -79,7 +79,7 @@ public void consumerInvocation(@Mocked InvocationFinishEvent
event) {
result = Const.RESTFUL;
invocation.getMicroserviceQualifiedName();
result = "m.s.o";
- invocation.getStartTime();
+ invocation.getInvocationStageTrace().getStart();
result = 1;
event.getInvocation();
result = invocation;
@@ -111,9 +111,9 @@ public void producerInvocation(@Mocked
InvocationFinishEvent event) {
result = Const.RESTFUL;
invocation.getMicroserviceQualifiedName();
result = "m.s.o";
- invocation.getStartTime();
+ invocation.getInvocationStageTrace().getStart();
result = 1;
- invocation.getStartExecutionTime();
+ invocation.getInvocationStageTrace().getStartExecution();
result = 3;
event.getNanoCurrent();
result = 10;
diff --git
a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
index 5a79c7243..1b0d14a58 100644
---
a/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
+++
b/metrics/metrics-core/src/test/java/org/apache/servicecomb/metrics/core/publish/TestInvocationPublishModelFactory.java
@@ -19,6 +19,7 @@
import org.apache.servicecomb.core.Const;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.event.InvocationFinishEvent;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.foundation.common.utils.JsonUtils;
import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.foundation.metrics.MetricsInitializer;
@@ -37,6 +38,7 @@
import com.netflix.spectator.api.ManualClock;
import com.netflix.spectator.api.Registry;
+import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
@@ -55,6 +57,8 @@
@Mocked
Invocation invocation;
+ InvocationStageTrace invocationStageTrace = new
InvocationStageTrace(invocation);
+
@Mocked
Response response;
@@ -85,12 +89,9 @@ public void createDefaultPublishModel() throws
JsonProcessingException {
}
protected void prepareInvocation() {
- new MockUp<System>() {
- @Mock
- long nanoTime() {
- return 10;
- }
- };
+ Deencapsulation.setField(invocationStageTrace, "start", 0L);
+ Deencapsulation.setField(invocationStageTrace, "finish", 10L);
+ Deencapsulation.setField(invocationStageTrace, "startExecution", 5L);
invocationType = InvocationType.CONSUMER;
new MockUp<Invocation>() {
@@ -115,8 +116,8 @@ String getMicroserviceQualifiedName() {
}
@Mock
- long getStartExecutionTime() {
- return 5;
+ InvocationStageTrace getInvocationStageTrace() {
+ return invocationStageTrace;
}
};
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
index c7d3a1ba4..cca21c5da 100644
---
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerProducerOperation.java
@@ -128,13 +128,18 @@ public void completableFutureInvoke(SwaggerInvocation
invocation, AsyncResponse
@SuppressWarnings("unchecked")
public void doCompletableFutureInvoke(SwaggerInvocation invocation,
AsyncResponse asyncResp) {
try {
+ invocation.onBusinessMethodStart();
+
Object[] args = argumentsMapper.toProducerArgs(invocation);
for (ProducerInvokeExtension producerInvokeExtension :
producerInvokeExtenstionList) {
producerInvokeExtension.beforeMethodInvoke(invocation, this, args);
}
+
Object result = producerMethod.invoke(producerInstance, args);
+ invocation.onBusinessMethodFinish();
((CompletableFuture<Object>) result).whenComplete((realResult, ex) -> {
+ invocation.onBusinessFinish();
if (ex == null) {
asyncResp.handle(responseMapper.mapResponse(invocation.getStatus(),
realResult));
return;
@@ -142,7 +147,15 @@ public void doCompletableFutureInvoke(SwaggerInvocation
invocation, AsyncRespons
asyncResp.handle(processException(invocation, ex));
});
+ } catch (IllegalArgumentException ae) {
+ invocation.onBusinessMethodFinish();
+ invocation.onBusinessFinish();
+ asyncResp.handle(processException(invocation,
+ new InvocationException(Status.BAD_REQUEST.getStatusCode(), "",
+ new CommonExceptionData("Parameters not valid or types not
match."), ae)));
} catch (Throwable e) {
+ invocation.onBusinessMethodFinish();
+ invocation.onBusinessFinish();
asyncResp.handle(processException(invocation, e));
}
}
@@ -157,18 +170,28 @@ public void syncInvoke(SwaggerInvocation invocation,
AsyncResponse asyncResp) {
public Response doInvoke(SwaggerInvocation invocation) {
Response response = null;
try {
+ invocation.onBusinessMethodStart();
+
Object[] args = argumentsMapper.toProducerArgs(invocation);
for (ProducerInvokeExtension producerInvokeExtension :
producerInvokeExtenstionList) {
producerInvokeExtension.beforeMethodInvoke(invocation, this, args);
}
+
Object result = producerMethod.invoke(producerInstance, args);
response = responseMapper.mapResponse(invocation.getStatus(), result);
+
+ invocation.onBusinessMethodFinish();
+ invocation.onBusinessFinish();
} catch (IllegalArgumentException ae) {
+ invocation.onBusinessMethodFinish();
+ invocation.onBusinessFinish();
// ae.getMessage() is always null. Give a custom error message.
response = processException(invocation,
new InvocationException(Status.BAD_REQUEST.getStatusCode(), "",
new CommonExceptionData("Parameters not valid or types not
match."), ae));
} catch (Throwable e) {
+ invocation.onBusinessMethodFinish();
+ invocation.onBusinessFinish();
response = processException(invocation, e);
}
return response;
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
index 98f0ad8b0..e4c4cb6f4 100644
---
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/SwaggerInvocation.java
@@ -64,4 +64,13 @@ public void setSwaggerArgument(int idx, Object
swaggerArgument) {
public String getInvocationQualifiedName() {
return invocationType.name();
}
+
+ public void onBusinessMethodStart() {
+ }
+
+ public void onBusinessMethodFinish() {
+ }
+
+ public void onBusinessFinish() {
+ }
}
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerArgumentToProducerBodyField.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerArgumentToProducerBodyField.java
index 519e9bd52..d1541a3fc 100644
---
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerArgumentToProducerBodyField.java
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/SwaggerArgumentToProducerBodyField.java
@@ -50,6 +50,8 @@ public void mapArgument(SwaggerInvocation invocation,
Object[] producerArguments
Object producerParam = info.getConverter().convert(fieldValue);
producerArguments[entry.getKey()] = producerParam;
}
+ } catch (IllegalArgumentException e) {
+ throw e;
} catch (Throwable e) {
throw new Error(e);
}
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 5106f555c..8cfd0ccb7 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
@@ -77,6 +77,9 @@ private TcpClientConfig createTcpClientConfig() {
}
public void send(Invocation invocation, AsyncResponse asyncResp) throws
Exception {
+ invocation.getInvocationStageTrace().startClientFiltersRequest();
+ invocation.getInvocationStageTrace().startSend();
+
HighwayClientConnectionPool tcpClientPool =
clientMgr.findClientPool(invocation.isSync());
OperationMeta operationMeta = invocation.getOperationMeta();
@@ -85,6 +88,8 @@ public void send(Invocation invocation, AsyncResponse
asyncResp) throws Exceptio
HighwayClientConnection tcpClient =
tcpClientPool.findOrCreateClient(invocation.getEndpoint().getEndpoint());
+
invocation.getInvocationStageTrace().finishGetConnection(System.nanoTime());
+
//set the timeout based on priority. the priority is follows.
//high priotiry: 1) operational level 2)schema level 3) service level 4)
global level : low priotiry.
TcpClientConfig tcpClientConfig = tcpClient.getClientConfig();
@@ -97,10 +102,14 @@ public void send(Invocation invocation, AsyncResponse
asyncResp) throws Exceptio
invocation.getMicroserviceQualifiedName(),
invocation.getEndpoint().getEndpoint());
tcpClient.send(clientPackage, ar -> {
+
invocation.getInvocationStageTrace().finishWriteToBuffer(clientPackage.getFinishWriteToBuffer());
+ invocation.getInvocationStageTrace().finishReceiveResponse();
// 此时是在网络线程中,转换线程
invocation.getResponseExecutor().execute(() -> {
+ invocation.getInvocationStageTrace().startClientFiltersResponse();
if (ar.failed()) {
// 只会是本地异常
+ invocation.getInvocationStageTrace().finishClientFiltersResponse();
asyncResp.consumerFail(ar.cause());
return;
}
@@ -112,8 +121,10 @@ public void send(Invocation invocation, AsyncResponse
asyncResp) throws Exceptio
operationProtobuf,
ar.result(),
tcpClient.getProtobufFeature());
+ invocation.getInvocationStageTrace().finishClientFiltersResponse();
asyncResp.complete(response);
} catch (Throwable e) {
+ invocation.getInvocationStageTrace().finishClientFiltersResponse();
asyncResp.consumerFail(e);
}
});
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 eee779885..290b75bf3 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
@@ -64,11 +64,14 @@
Invocation invocation;
+ protected long start;
+
public HighwayServerInvoke() {
this(null, null);
}
public HighwayServerInvoke(Endpoint endpoint, ProtobufFeature
protobufFeature) {
+ this.start = System.nanoTime();
this.endpoint = endpoint;
this.protobufFeature = protobufFeature;
}
@@ -123,22 +126,26 @@ private void runInExecutor() {
}
private boolean isInQueueTimeout() {
- return System.nanoTime() - invocation.getStartTime() >
+ return System.nanoTime() - invocation.getInvocationStageTrace().getStart()
>
HighwayConfig.getRequestWaitInPoolTimeout() * 1_000_000;
}
private void doRunInExecutor() throws Exception {
- invocation.onStartExecute();
+ invocation.onExecuteStart();
+ invocation.getInvocationStageTrace().startServerFiltersRequest();
HighwayCodec.decodeRequest(invocation, header, operationProtobuf,
bodyBuffer, protobufFeature);
invocation.getHandlerContext().put(Const.REMOTE_ADDRESS,
this.connection.getNetSocket().remoteAddress());
+ invocation.getInvocationStageTrace().startHandlersRequest();
invocation.next(response -> {
sendResponse(invocation.getContext(), response);
});
}
private void sendResponse(Map<String, String> context, Response response) {
+ invocation.getInvocationStageTrace().finishHandlersResponse();
+
ResponseHeader header = new ResponseHeader();
header.setStatusCode(response.getStatusCode());
header.setReasonPhrase(response.getReasonPhrase());
@@ -153,6 +160,7 @@ private void sendResponse(Map<String, String> context,
Response response) {
try {
Buffer respBuffer = HighwayCodec.encodeResponse(msgId, header,
bodySchema, body, protobufFeature);
+ invocation.getInvocationStageTrace().finishServerFiltersResponse();
connection.write(respBuffer.getByteBuf());
} catch (Exception e) {
// 没招了,直接打日志
@@ -175,7 +183,8 @@ public void execute() {
invocation = InvocationFactory.forProvider(endpoint,
operationProtobuf.getOperationMeta(),
null);
- invocation.onStart();
+ invocation.onStart(null, start);
+ invocation.getInvocationStageTrace().startSchedule();
operationMeta.getExecutor().execute(() -> runInExecutor());
} catch (IllegalStateException e) {
sendResponse(header.getContext(), Response.providerFailResp(e));
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 0b88ba528..447af3587 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
@@ -29,6 +29,7 @@
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.executor.ReactiveExecutor;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.core.transport.AbstractTransport;
import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;
@@ -68,18 +69,29 @@
Invocation invocation = Mockito.mock(Invocation.class);
+ InvocationStageTrace invocationStageTrace = new
InvocationStageTrace(invocation);
+
OperationProtobuf operationProtobuf = Mockito.mock(OperationProtobuf.class);
OperationMeta operationMeta = Mockito.mock(OperationMeta.class);
Endpoint endpoint = Mockito.mock(Endpoint.class);
+ static long nanoTime = 123;
+
@BeforeClass
public static void beforeCls() {
ConfigUtil.installDynamicConfig();
AbstractConfiguration configuration =
(AbstractConfiguration)
DynamicPropertyFactory.getBackingConfigurationSource();
configuration.addProperty(REQUEST_TIMEOUT_KEY, 2000);
+
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
}
@Test
@@ -160,6 +172,7 @@ Response decodeResponse(Invocation invocation,
OperationProtobuf operationProtob
Mockito.when(invocation.getEndpoint()).thenReturn(endpoint);
Mockito.when(invocation.getEndpoint().getEndpoint()).thenReturn("endpoint");
Mockito.when(invocation.getResponseExecutor()).thenReturn(new
ReactiveExecutor());
+
Mockito.when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);
Holder<Object> result = new Holder<>();
client.send(invocation, ar -> {
@@ -178,10 +191,23 @@ void send(AbstractTcpClientPackage tcpClientPackage,
TcpResponseCallback callbac
callback.success(null);
}
};
-
+ new MockUp<HighwayClientPackage>() {
+ @Mock
+ public long getFinishWriteToBuffer() {
+ return nanoTime;
+ }
+ };
Object result = doTestSend(vertx, pool, tcpClient, Response.ok("ok"));
Assert.assertEquals("ok", result);
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishClientFiltersResponse());
+
+ Assert.assertEquals(nanoTime, invocationStageTrace.getStartSend());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishGetConnection());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishWriteToBuffer());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishReceiveResponse());
}
@Test
@@ -197,6 +223,9 @@ void send(AbstractTcpClientPackage tcpClientPackage,
TcpResponseCallback callbac
Object result = doTestSend(vertx, pool, tcpClient, new
InvocationException(Status.BAD_REQUEST, (Object) "failed"));
Assert.assertEquals("failed", ((InvocationException)
result).getErrorData());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishClientFiltersResponse());
}
@Test
@@ -215,6 +244,9 @@ void send(AbstractTcpClientPackage tcpClientPackage,
TcpResponseCallback callbac
null);
Assert.assertEquals("failed", ((InvocationException)
result).getErrorData());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getStartClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocationStageTrace.getFinishClientFiltersResponse());
}
@Test
diff --git
a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayServerInvoke.java
b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayServerInvoke.java
index 6a7d1327f..7381dee3e 100644
---
a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayServerInvoke.java
+++
b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayServerInvoke.java
@@ -64,10 +64,19 @@ public int add(int x, int y) {
private SocketAddress socketAddress;
+ static long nanoTime = 1;
+
@BeforeClass
public static void classSetup() {
EventManager.eventBus = new EventBus();
SCBEngine.getInstance().setStatus(SCBStatus.UP);
+
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
}
@AfterClass
@@ -154,6 +163,12 @@ public void onFinish(InvocationFinishEvent event) {
Assert.assertEquals(true,
Buffer.buffer(netSocketBuffer).toString().startsWith("CSE.TCP"));
Assert.assertSame(highwayServerInvoke.invocation,
startHolder.value.getInvocation());
Assert.assertSame(highwayServerInvoke.invocation,
finishHolder.value.getInvocation());
- Assert.assertTrue(highwayServerInvoke.invocation.getStartExecutionTime()
!= 0);
+
Assert.assertTrue(highwayServerInvoke.invocation.getInvocationStageTrace().getStartExecution()
!= 0);
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getStart());
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getFinishHandlersResponse());
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getStartSchedule());
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getStartHandlersRequest());
+ Assert.assertEquals(1,
highwayServerInvoke.invocation.getInvocationStageTrace().getFinishHandlersResponse());
}
}
diff --git
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
index 73b89feb8..a7b422df9 100644
---
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
+++
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
@@ -27,6 +27,7 @@
import org.apache.servicecomb.common.rest.filter.HttpClientFilter;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.core.transport.AbstractTransport;
import org.apache.servicecomb.foundation.common.http.HttpStatus;
import org.apache.servicecomb.foundation.common.net.IpPort;
@@ -38,6 +39,7 @@
import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;
import
org.apache.servicecomb.foundation.vertx.http.VertxClientRequestToHttpServletRequest;
import
org.apache.servicecomb.foundation.vertx.http.VertxClientResponseToHttpServletResponse;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
import org.apache.servicecomb.serviceregistry.api.Const;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
@@ -50,6 +52,7 @@
import io.vertx.core.http.HttpClientResponse;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.RequestOptions;
+import io.vertx.core.net.impl.ConnectionBase;
public class RestClientInvocation {
private static final Logger LOGGER =
LoggerFactory.getLogger(RestClientInvocation.class);
@@ -89,13 +92,14 @@ public void invoke(Invocation invocation, AsyncResponse
asyncResp) throws Except
Buffer requestBodyBuffer = restClientRequest.getBodyBuffer();
HttpServletRequestEx requestEx = new
VertxClientRequestToHttpServletRequest(clientRequest, requestBodyBuffer);
+ invocation.getInvocationStageTrace().startClientFiltersRequest();
for (HttpClientFilter filter : httpClientFilters) {
filter.beforeSendRequest(invocation, requestEx);
}
clientRequest.exceptionHandler(e -> {
LOGGER.error("Failed to send request to {}.", ipPort.getSocketAddress(),
e);
- asyncResp.fail(invocation.getInvocationType(), e);
+ fail(e);
});
clientRequest.connectionHandler(connection -> {
LOGGER.debug("http connection connected, local:{}, remote:{}.",
@@ -113,7 +117,9 @@ public void invoke(Invocation invocation, AsyncResponse
asyncResp) throws Except
e);
});
});
+
// 从业务线程转移到网络线程中去发送
+ invocation.getInvocationStageTrace().startSend();
httpClientWithContext.runOnContext(httpClient -> {
this.setCseContext();
//set the timeout based on priority. the priority is follows.
@@ -125,7 +131,7 @@ public void invoke(Invocation invocation, AsyncResponse
asyncResp) throws Except
restClientRequest.end();
} catch (Throwable e) {
LOGGER.error("send http request failed,", e);
- asyncResp.fail(invocation.getInvocationType(), e);
+ fail(e);
}
});
}
@@ -167,7 +173,7 @@ protected void handleResponse(HttpClientResponse
httpClientResponse) {
httpClientResponse.exceptionHandler(e -> {
LOGGER.error("Failed to receive response from {}.",
httpClientResponse.netSocket().remoteAddress(), e);
- asyncResp.fail(invocation.getInvocationType(), e);
+ fail(e);
});
clientResponse.bodyHandler(responseBuf -> {
@@ -175,24 +181,55 @@ protected void handleResponse(HttpClientResponse
httpClientResponse) {
});
}
+ /**
+ *
+ * @param responseBuf response body buffer, when download, responseBuf is
null, because download data by ReadStreamPart
+ */
protected void processResponseBody(Buffer responseBuf) {
+ invocation.getInvocationStageTrace().finishReceiveResponse();
invocation.getResponseExecutor().execute(() -> {
try {
+ invocation.getInvocationStageTrace().startClientFiltersResponse();
HttpServletResponseEx responseEx =
new VertxClientResponseToHttpServletResponse(clientResponse,
responseBuf);
for (HttpClientFilter filter : httpClientFilters) {
Response response = filter.afterReceiveResponse(invocation,
responseEx);
if (response != null) {
- asyncResp.complete(response);
+ complete(response);
return;
}
}
} catch (Throwable e) {
- asyncResp.fail(invocation.getInvocationType(), e);
+ fail(e);
}
});
}
+ protected void complete(Response response) {
+ DefaultHttpSocketMetric httpSocketMetric = (DefaultHttpSocketMetric)
((ConnectionBase) clientRequest.connection())
+ .metric();
+
invocation.getInvocationStageTrace().finishGetConnection(httpSocketMetric.getRequestBeginTime());
+
invocation.getInvocationStageTrace().finishWriteToBuffer(httpSocketMetric.getRequestEndTime());
+
+ invocation.getInvocationStageTrace().finishClientFiltersResponse();
+ asyncResp.complete(response);
+ }
+
+ protected void fail(Throwable e) {
+ if (invocation.isFinished()) {
+ return;
+ }
+
+ InvocationStageTrace stageTrace = invocation.getInvocationStageTrace();
+ DefaultHttpSocketMetric httpSocketMetric = (DefaultHttpSocketMetric)
((ConnectionBase) clientRequest.connection())
+ .metric();
+ stageTrace.finishGetConnection(httpSocketMetric.getRequestBeginTime());
+ stageTrace.finishWriteToBuffer(httpSocketMetric.getRequestEndTime());
+
+ stageTrace.finishClientFiltersResponse();
+ asyncResp.fail(invocation.getInvocationType(), e);
+ }
+
protected void setCseContext() {
try {
String cseContext =
JsonUtils.writeValueAsString(invocation.getContext());
diff --git
a/transports/transport-rest/transport-rest-client/src/test/java/io/vertx/core/http/impl/VertxImplTestUtils.java
b/transports/transport-rest/transport-rest-client/src/test/java/io/vertx/core/http/impl/VertxImplTestUtils.java
new file mode 100644
index 000000000..cb2631fbd
--- /dev/null
+++
b/transports/transport-rest/transport-rest-client/src/test/java/io/vertx/core/http/impl/VertxImplTestUtils.java
@@ -0,0 +1,25 @@
+/*
+ * 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 io.vertx.core.http.impl;
+
+import org.mockito.Mockito;
+
+public class VertxImplTestUtils {
+ public static ClientConnection mockClientConnection() {
+ return Mockito.mock(ClientConnection.class);
+ }
+}
diff --git
a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestRestClientInvocation.java
b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestRestClientInvocation.java
index 76a6eabf6..e1f115372 100644
---
a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestRestClientInvocation.java
+++
b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestRestClientInvocation.java
@@ -40,11 +40,14 @@
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.core.executor.ReactiveExecutor;
+import org.apache.servicecomb.core.invocation.InvocationStageTrace;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;
import
org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultEndpointMetric;
+import
org.apache.servicecomb.foundation.vertx.metrics.metric.DefaultHttpSocketMetric;
import org.apache.servicecomb.serviceregistry.api.Const;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
import org.apache.servicecomb.swagger.invocation.Response;
@@ -52,6 +55,7 @@
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mockito;
@@ -61,10 +65,13 @@
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpConnection;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.RequestOptions;
+import io.vertx.core.http.impl.VertxImplTestUtils;
import io.vertx.core.net.NetSocket;
import io.vertx.core.net.SocketAddress;
+import io.vertx.core.net.impl.ConnectionBase;
import mockit.Deencapsulation;
import mockit.Mock;
import mockit.MockUp;
@@ -87,6 +94,8 @@
Invocation invocation = mock(Invocation.class);
+ InvocationStageTrace invocationStageTrace = new
InvocationStageTrace(invocation);
+
Response response;
AsyncResponse asyncResp = resp -> {
@@ -109,6 +118,18 @@
Map<String, Object> handlerContext = new HashMap<>();
+ static long nanoTime = 123;
+
+ @BeforeClass
+ public static void classSetup() {
+ new MockUp<System>() {
+ @Mock
+ long nanoTime() {
+ return nanoTime;
+ }
+ };
+ }
+
@SuppressWarnings("unchecked")
@Before
public void setup() {
@@ -123,8 +144,19 @@ public void setup() {
when(invocation.getEndpoint()).thenReturn(endpoint);
when(endpoint.getAddress()).thenReturn(address);
when(invocation.getHandlerContext()).then(answer -> handlerContext);
+
when(invocation.getInvocationStageTrace()).thenReturn(invocationStageTrace);
when(httpClient.request((HttpMethod) Mockito.any(), (RequestOptions)
Mockito.any(), Mockito.any()))
.thenReturn(request);
+
+ ConnectionBase connectionBase = VertxImplTestUtils.mockClientConnection();
+
when(connectionBase.metric()).thenReturn(Mockito.mock(DefaultHttpSocketMetric.class));
+ when(request.connection()).thenReturn((HttpConnection) connectionBase);
+
+ DefaultHttpSocketMetric httpSocketMetric = new
DefaultHttpSocketMetric(Mockito.mock(DefaultEndpointMetric.class));
+ httpSocketMetric.requestBegin();
+ httpSocketMetric.requestEnd();
+ when(connectionBase.metric()).thenReturn(httpSocketMetric);
+
doAnswer(a -> {
exceptionHandler = (Handler<Throwable>) a.getArguments()[0];
return request;
@@ -148,6 +180,8 @@ public void invoke(@Mocked Response resp) throws Exception {
restClientInvocation.invoke(invocation, asyncResp);
Assert.assertSame(resp, response);
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartSend());
}
@Test
@@ -156,6 +190,8 @@ public void invoke_endThrow() throws Exception {
restClientInvocation.invoke(invocation, asyncResp);
Assert.assertThat(((InvocationException) response.getResult()).getCause(),
Matchers.instanceOf(Error.class));
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishClientFiltersResponse());
}
@Test
@@ -169,6 +205,8 @@ public void invoke_requestThrow() throws Exception {
restClientInvocation.invoke(invocation, asyncResp);
Assert.assertThat(((InvocationException) response.getResult()).getCause(),
Matchers.sameInstance(t));
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartClientFiltersRequest());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishClientFiltersResponse());
}
@Test
@@ -281,6 +319,11 @@ public void processResponseBody() {
restClientInvocation.processResponseBody(null);
Assert.assertSame(resp, response);
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishReceiveResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishGetConnection());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishWriteToBuffer());
}
@SuppressWarnings("unchecked")
@@ -300,6 +343,11 @@ public void processResponseBody_throw() {
restClientInvocation.processResponseBody(null);
Assert.assertThat(((InvocationException) response.getResult()).getCause(),
Matchers.instanceOf(Error.class));
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getStartClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishClientFiltersResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishReceiveResponse());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishGetConnection());
+ Assert.assertEquals(nanoTime,
invocation.getInvocationStageTrace().getFinishWriteToBuffer());
}
@Test
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> add more invocation stage measurement
> -------------------------------------
>
> Key: SCB-881
> URL: https://issues.apache.org/jira/browse/SCB-881
> Project: Apache ServiceComb
> Issue Type: Sub-task
> Components: Java-Chassis
> Reporter: wujimin
> Assignee: wujimin
> Priority: Major
> Fix For: java-chassis-1.1.0
>
>
> prepare/handler/filter/net and so on
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)