You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/04/22 08:32:29 UTC
[incubator-servicecomb-java-chassis] 02/09: [SCB-486] refactoring
VertxHttpMethod to RestClientInvocation: move method parameters to be
fields, not change any logic
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 15b85a5d0b0ae0457be40b5f93bc894b4d440bd5
Author: wujimin <wu...@huawei.com>
AuthorDate: Sat Apr 21 21:17:29 2018 +0800
[SCB-486] refactoring VertxHttpMethod to RestClientInvocation: move method parameters to be fields, not change any logic
---
.../test/scaffolding/log/LogCollector.java | 6 +
.../transport-rest/transport-rest-client/pom.xml | 66 ++---
.../transport/rest/client/RestTransportClient.java | 16 +-
...txHttpMethod.java => RestClientInvocation.java} | 97 ++++---
.../rest/client/http/TestRestClientInvocation.java | 302 +++++++++++++++++++++
.../rest/client/http/TestVertxHttpMethod.java | 302 ---------------------
6 files changed, 407 insertions(+), 382 deletions(-)
diff --git a/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java b/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java
index 33e5808..53359e3 100644
--- a/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java
+++ b/foundations/foundation-test-scaffolding/src/main/java/org/apache/servicecomb/foundation/test/scaffolding/log/LogCollector.java
@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
@@ -48,6 +49,11 @@ public class LogCollector {
Logger.getRootLogger().addAppender(appender);
}
+ public LogCollector setLogLevel(String logName, Level level) {
+ Logger.getLogger(logName).setLevel(level);
+ return this;
+ }
+
public List<LoggingEvent> getEvents() {
return events;
}
diff --git a/transports/transport-rest/transport-rest-client/pom.xml b/transports/transport-rest/transport-rest-client/pom.xml
index d7e2996..d7f0363 100644
--- a/transports/transport-rest/transport-rest-client/pom.xml
+++ b/transports/transport-rest/transport-rest-client/pom.xml
@@ -16,36 +16,40 @@
~ limitations under the License.
-->
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.servicecomb</groupId>
- <artifactId>transport-rest</artifactId>
- <version>1.0.0-m2-SNAPSHOT</version>
- </parent>
- <artifactId>transport-rest-client</artifactId>
- <name>Java Chassis::Transports::Rest::Client</name>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>transport-rest</artifactId>
+ <version>1.0.0-m2-SNAPSHOT</version>
+ </parent>
+ <artifactId>transport-rest-client</artifactId>
+ <name>Java Chassis::Transports::Rest::Client</name>
- <dependencies>
- <dependency>
- <groupId>org.apache.servicecomb</groupId>
- <artifactId>foundation-vertx</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.servicecomb</groupId>
- <artifactId>common-rest</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>foundation-vertx</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>common-rest</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.servicecomb</groupId>
+ <artifactId>foundation-test-scaffolding</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
</project>
diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestTransportClient.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestTransportClient.java
index 1fed065..937097a 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestTransportClient.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestTransportClient.java
@@ -17,7 +17,11 @@
package org.apache.servicecomb.transport.rest.client;
+import java.util.List;
+
+import org.apache.servicecomb.common.rest.filter.HttpClientFilter;
import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.foundation.vertx.VertxTLSBuilder;
import org.apache.servicecomb.foundation.vertx.VertxUtils;
import org.apache.servicecomb.foundation.vertx.client.ClientPoolManager;
@@ -25,7 +29,7 @@ import org.apache.servicecomb.foundation.vertx.client.ClientVerticle;
import org.apache.servicecomb.foundation.vertx.client.http.HttpClientPoolFactory;
import org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
import org.apache.servicecomb.swagger.invocation.AsyncResponse;
-import org.apache.servicecomb.transport.rest.client.http.VertxHttpMethod;
+import org.apache.servicecomb.transport.rest.client.http.RestClientInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,8 +44,11 @@ public final class RestTransportClient {
private ClientPoolManager<HttpClientWithContext> clientMgr;
+ private List<HttpClientFilter> httpClientFilters;
public void init(Vertx vertx) throws Exception {
+ httpClientFilters = SPIServiceUtils.getSortedService(HttpClientFilter.class);
+
HttpClientOptions httpClientOptions = createHttpClientOptions();
clientMgr = new ClientPoolManager<>(vertx, new HttpClientPoolFactory(httpClientOptions));
@@ -61,11 +68,12 @@ public final class RestTransportClient {
return httpClientOptions;
}
- public void send(Invocation invocation, AsyncResponse asyncResp) throws Exception {
+ public void send(Invocation invocation, AsyncResponse asyncResp) {
HttpClientWithContext httpClientWithContext = clientMgr.findClientPool(invocation.isSync());
+ RestClientInvocation restClientInvocation = new RestClientInvocation(httpClientWithContext, httpClientFilters);
try {
- VertxHttpMethod.INSTANCE.doMethod(httpClientWithContext, invocation, asyncResp);
- } catch (Exception e) {
+ restClientInvocation.invoke(invocation, asyncResp);
+ } catch (Throwable e) {
asyncResp.fail(invocation.getInvocationType(), e);
LOGGER.error("vertx rest transport send error.", e);
}
diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/VertxHttpMethod.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
similarity index 69%
rename from transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/VertxHttpMethod.java
rename to transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
index d4f2aa1..58789a6 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/VertxHttpMethod.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/RestClientInvocation.java
@@ -29,7 +29,6 @@ import org.apache.servicecomb.core.transport.AbstractTransport;
import org.apache.servicecomb.foundation.common.net.IpPort;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
@@ -43,33 +42,42 @@ import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import io.vertx.core.buffer.Buffer;
-import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpClientRequest;
import io.vertx.core.http.HttpClientResponse;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.RequestOptions;
-public class VertxHttpMethod {
- private static final Logger LOGGER = LoggerFactory.getLogger(VertxHttpMethod.class);
+public class RestClientInvocation {
+ private static final Logger LOGGER = LoggerFactory.getLogger(RestClientInvocation.class);
- public static final VertxHttpMethod INSTANCE = new VertxHttpMethod();
+ private HttpClientWithContext httpClientWithContext;
- static List<HttpClientFilter> httpClientFilters = SPIServiceUtils.getSortedService(HttpClientFilter.class);
+ private Invocation invocation;
+
+ private AsyncResponse asyncResp;
+
+ private List<HttpClientFilter> httpClientFilters;
+
+ private HttpClientRequest clientRequest;
+
+ private HttpClientResponse clientResponse;
+
+ public RestClientInvocation(HttpClientWithContext httpClientWithContext, List<HttpClientFilter> httpClientFilters) {
+ this.httpClientWithContext = httpClientWithContext;
+ this.httpClientFilters = httpClientFilters;
+ }
+
+ public void invoke(Invocation invocation, AsyncResponse asyncResp) throws Exception {
+ this.invocation = invocation;
+ this.asyncResp = asyncResp;
- public void doMethod(HttpClientWithContext httpClientWithContext, Invocation invocation,
- AsyncResponse asyncResp) throws Exception {
OperationMeta operationMeta = invocation.getOperationMeta();
RestOperationMeta swaggerRestOperation = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
- String path = this.createRequestPath(invocation, swaggerRestOperation);
+ String path = this.createRequestPath(swaggerRestOperation);
IpPort ipPort = (IpPort) invocation.getEndpoint().getAddress();
- HttpClientRequest clientRequest =
- this.createRequest(httpClientWithContext.getHttpClient(),
- invocation,
- ipPort,
- path,
- asyncResp);
+ createRequest(ipPort, path);
clientRequest.putHeader(org.apache.servicecomb.core.Const.TARGET_MICROSERVICE, invocation.getMicroserviceName());
RestClientRequestImpl restClientRequest =
new RestClientRequestImpl(clientRequest, httpClientWithContext.context().owner(), asyncResp);
@@ -88,7 +96,7 @@ public class VertxHttpMethod {
// 从业务线程转移到网络线程中去发送
httpClientWithContext.runOnContext(httpClient -> {
- this.setCseContext(invocation, clientRequest);
+ this.setCseContext();
clientRequest.setTimeout(AbstractTransport.getRequestTimeoutProperty().get());
try {
restClientRequest.end();
@@ -99,15 +107,14 @@ public class VertxHttpMethod {
});
}
- private HttpMethod getMethod(Invocation invocation) {
+ private HttpMethod getMethod() {
OperationMeta operationMeta = invocation.getOperationMeta();
RestOperationMeta swaggerRestOperation = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
String method = swaggerRestOperation.getHttpMethod();
return HttpMethod.valueOf(method);
}
- HttpClientRequest createRequest(HttpClient client, Invocation invocation, IpPort ipPort, String path,
- AsyncResponse asyncResp) {
+ void createRequest(IpPort ipPort, String path) {
URIEndpointObject endpoint = (URIEndpointObject) invocation.getEndpoint().getAddress();
RequestOptions requestOptions = new RequestOptions();
requestOptions.setHost(ipPort.getHostOrIp())
@@ -115,51 +122,51 @@ public class VertxHttpMethod {
.setSsl(endpoint.isSslEnabled())
.setURI(path);
- HttpMethod method = getMethod(invocation);
+ HttpMethod method = getMethod();
LOGGER.debug("Sending request by rest, method={}, qualifiedName={}, path={}, endpoint={}.",
method,
invocation.getMicroserviceQualifiedName(),
path,
invocation.getEndpoint().getEndpoint());
- HttpClientRequest request = client.request(method, requestOptions, response -> {
- handleResponse(invocation, response, asyncResp);
- });
- return request;
+ clientRequest = httpClientWithContext.getHttpClient().request(method, requestOptions, this::handleResponse);
}
- void handleResponse(Invocation invocation, HttpClientResponse clientResponse,
- AsyncResponse asyncResp) {
+ protected void handleResponse(HttpClientResponse httpClientResponse) {
+ this.clientResponse = httpClientResponse;
+
clientResponse.bodyHandler(responseBuf -> {
- // 此时是在网络线程中,不应该就地处理,通过dispatcher转移线程
- invocation.getResponseExecutor().execute(() -> {
- try {
- HttpServletResponseEx responseEx =
- new VertxClientResponseToHttpServletResponse(clientResponse, responseBuf);
- for (HttpClientFilter filter : httpClientFilters) {
- Response response = filter.afterReceiveResponse(invocation, responseEx);
- if (response != null) {
- asyncResp.complete(response);
- return;
- }
+ processResponseBody(responseBuf);
+ });
+ }
+
+ protected void processResponseBody(Buffer responseBuf) {
+ invocation.getResponseExecutor().execute(() -> {
+ try {
+ HttpServletResponseEx responseEx =
+ new VertxClientResponseToHttpServletResponse(clientResponse, responseBuf);
+ for (HttpClientFilter filter : httpClientFilters) {
+ Response response = filter.afterReceiveResponse(invocation, responseEx);
+ if (response != null) {
+ asyncResp.complete(response);
+ return;
}
- } catch (Throwable e) {
- asyncResp.fail(invocation.getInvocationType(), e);
}
- });
+ } catch (Throwable e) {
+ asyncResp.fail(invocation.getInvocationType(), e);
+ }
});
}
- protected void setCseContext(Invocation invocation, HttpClientRequest request) {
+ protected void setCseContext() {
try {
String cseContext = JsonUtils.writeValueAsString(invocation.getContext());
- request.putHeader(org.apache.servicecomb.core.Const.CSE_CONTEXT, cseContext);
+ clientRequest.putHeader(org.apache.servicecomb.core.Const.CSE_CONTEXT, cseContext);
} catch (Exception e) {
- LOGGER.debug(e.toString());
+ LOGGER.debug("Failed to encode and set cseContext.", e);
}
}
- protected String createRequestPath(Invocation invocation,
- RestOperationMeta swaggerRestOperation) throws Exception {
+ protected String createRequestPath(RestOperationMeta swaggerRestOperation) throws Exception {
URIEndpointObject address = (URIEndpointObject) invocation.getEndpoint().getAddress();
String urlPrefix = address.getFirst(Const.URL_PREFIX);
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
new file mode 100644
index 0000000..5b5f4a1
--- /dev/null
+++ b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestRestClientInvocation.java
@@ -0,0 +1,302 @@
+/*
+ * 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.transport.rest.client.http;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Level;
+import org.apache.servicecomb.common.rest.RestConst;
+import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
+import org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;
+import org.apache.servicecomb.common.rest.filter.HttpClientFilter;
+import org.apache.servicecomb.core.Endpoint;
+import org.apache.servicecomb.core.Invocation;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.core.executor.ReactiveExecutor;
+import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
+import org.apache.servicecomb.foundation.test.scaffolding.log.LogCollector;
+import org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
+import org.apache.servicecomb.serviceregistry.api.Const;
+import org.apache.servicecomb.swagger.invocation.AsyncResponse;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import io.vertx.core.Context;
+import io.vertx.core.Handler;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpClient;
+import io.vertx.core.http.HttpClientRequest;
+import io.vertx.core.http.HttpClientResponse;
+import io.vertx.core.http.HttpMethod;
+import io.vertx.core.http.RequestOptions;
+import mockit.Deencapsulation;
+import mockit.Mock;
+import mockit.MockUp;
+import mockit.Mocked;
+
+public class TestRestClientInvocation {
+ Handler<Throwable> exceptionHandler;
+
+ Handler<Buffer> bodyHandler;
+
+ Map<String, String> headers = new HashMap<>();
+
+ HttpClientRequest request = mock(HttpClientRequest.class);
+
+ HttpClient httpClient = mock(HttpClient.class);
+
+ Context context = mock(Context.class);
+
+ HttpClientWithContext httpClientWithContext = new HttpClientWithContext(httpClient, context);
+
+ Invocation invocation = mock(Invocation.class);
+
+ Response response;
+
+ AsyncResponse asyncResp = resp -> {
+ response = resp;
+ };
+
+ OperationMeta operationMeta = mock(OperationMeta.class);
+
+ Endpoint endpoint = mock(Endpoint.class);
+
+ RestOperationMeta swaggerRestOperation = mock(RestOperationMeta.class);
+
+ URLPathBuilder urlPathBuilder = mock(URLPathBuilder.class);
+
+ URIEndpointObject address = mock(URIEndpointObject.class);
+
+ List<HttpClientFilter> httpClientFilters = new ArrayList<>();
+
+ RestClientInvocation restClientInvocation = new RestClientInvocation(httpClientWithContext, httpClientFilters);
+
+ Map<String, Object> handlerContext = new HashMap<>();
+
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setup() {
+ Deencapsulation.setField(restClientInvocation, "clientRequest", request);
+ Deencapsulation.setField(restClientInvocation, "invocation", invocation);
+ Deencapsulation.setField(restClientInvocation, "asyncResp", asyncResp);
+
+ when(invocation.getOperationMeta()).thenReturn(operationMeta);
+ when(swaggerRestOperation.getPathBuilder()).thenReturn(urlPathBuilder);
+ when(swaggerRestOperation.getHttpMethod()).thenReturn("GET");
+ when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerRestOperation);
+ when(invocation.getEndpoint()).thenReturn(endpoint);
+ when(endpoint.getAddress()).thenReturn(address);
+ when(invocation.getHandlerContext()).then(answer -> handlerContext);
+ when(httpClient.request((HttpMethod) Mockito.any(), (RequestOptions) Mockito.any(), Mockito.any()))
+ .thenReturn(request);
+ doAnswer(a -> {
+ exceptionHandler = (Handler<Throwable>) a.getArguments()[0];
+ return request;
+ }).when(request).exceptionHandler(any());
+ doAnswer(a -> {
+ headers.put(a.getArgumentAt(0, String.class), a.getArgumentAt(1, String.class));
+ return request;
+ }).when(request).putHeader((String) any(), (String) any());
+ doAnswer(a -> {
+ ((Handler<Void>) a.getArguments()[0]).handle(null);
+ return null;
+ }).when(context).runOnContext(any());
+ }
+
+ @Test
+ public void invoke(@Mocked Response resp) throws Exception {
+ doAnswer(a -> {
+ asyncResp.complete(resp);
+ return null;
+ }).when(request).end();
+ restClientInvocation.invoke(invocation, asyncResp);
+
+ Assert.assertSame(resp, response);
+ }
+
+ @Test
+ public void invoke_endThrow() throws Exception {
+ Mockito.doThrow(Error.class).when(request).end();
+ restClientInvocation.invoke(invocation, asyncResp);
+
+ Assert.assertThat(((InvocationException) response.getResult()).getCause(), Matchers.instanceOf(Error.class));
+ }
+
+ @Test
+ public void invoke_requestThrow() throws Exception {
+ Throwable t = new Error();
+ doAnswer(a -> {
+ exceptionHandler.handle(t);
+ return null;
+ }).when(request).end();
+ restClientInvocation.invoke(invocation, asyncResp);
+ restClientInvocation.invoke(invocation, asyncResp);
+
+ Assert.assertThat(((InvocationException) response.getResult()).getCause(), Matchers.sameInstance(t));
+ }
+
+ @Test
+ public void testSetCseContext() {
+ Map<String, String> contextMap = Collections.singletonMap("k", "v");
+ when(invocation.getContext()).thenReturn(contextMap);
+
+ restClientInvocation.setCseContext();
+
+ Assert.assertEquals("{x-cse-context={\"k\":\"v\"}}", headers.toString());
+ }
+
+ @Test
+ public void testSetCseContext_failed() {
+ LogCollector logCollector = new LogCollector();
+ logCollector.setLogLevel(RestClientInvocation.class.getName(), Level.DEBUG);
+ Deencapsulation.setField(restClientInvocation, "invocation", null);
+
+ restClientInvocation.setCseContext();
+
+ Assert.assertEquals("Failed to encode and set cseContext.", logCollector.getEvents().get(0).getMessage());
+ logCollector.teardown();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void handleResponse() {
+ HttpClientResponse httpClientResponse = mock(HttpClientResponse.class);
+ doAnswer(a -> {
+ bodyHandler = (Handler<Buffer>) a.getArguments()[0];
+ return httpClientResponse;
+ }).when(httpClientResponse).bodyHandler(any());
+
+ Buffer buf = Buffer.buffer();
+ new MockUp<RestClientInvocation>(restClientInvocation) {
+ @Mock
+ void processResponseBody(Buffer responseBuf) {
+ asyncResp.success(buf);
+ }
+ };
+
+ restClientInvocation.handleResponse(httpClientResponse);
+ bodyHandler.handle(buf);
+
+ Assert.assertSame(buf, response.getResult());
+ }
+
+ @Test
+ public void processResponseBody() {
+ Response resp = Response.ok(null);
+
+ HttpClientResponse httpClientResponse = mock(HttpClientResponse.class);
+ Deencapsulation.setField(restClientInvocation, "clientResponse", httpClientResponse);
+
+ {
+ HttpClientFilter filter = mock(HttpClientFilter.class);
+ when(filter.afterReceiveResponse(any(), any())).thenReturn(null);
+ httpClientFilters.add(filter);
+ }
+ {
+ HttpClientFilter filter = mock(HttpClientFilter.class);
+ when(filter.afterReceiveResponse(any(), any())).thenReturn(resp);
+ httpClientFilters.add(filter);
+ }
+
+ when(invocation.getResponseExecutor()).thenReturn(new ReactiveExecutor());
+
+ restClientInvocation.processResponseBody(null);
+
+ Assert.assertSame(resp, response);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void processResponseBody_throw() {
+ HttpClientResponse httpClientResponse = mock(HttpClientResponse.class);
+ Deencapsulation.setField(restClientInvocation, "clientResponse", httpClientResponse);
+
+ {
+ HttpClientFilter filter = mock(HttpClientFilter.class);
+ when(filter.afterReceiveResponse(any(), any())).thenThrow(Error.class);
+ httpClientFilters.add(filter);
+ }
+
+ when(invocation.getResponseExecutor()).thenReturn(new ReactiveExecutor());
+
+ restClientInvocation.processResponseBody(null);
+
+ Assert.assertThat(((InvocationException) response.getResult()).getCause(), Matchers.instanceOf(Error.class));
+ }
+
+ @Test
+ public void createRequestPath_NoUrlPrefixNoPath() throws Exception {
+ when(address.getFirst(Const.URL_PREFIX)).thenReturn(null);
+
+ when(urlPathBuilder.createRequestPath(any())).thenReturn("/path");
+
+ String path = restClientInvocation.createRequestPath(swaggerRestOperation);
+ Assert.assertEquals("/path", path);
+ }
+
+ @Test
+ public void createRequestPath_noUrlPrefixHavePath() throws Exception {
+ handlerContext.put(RestConst.REST_CLIENT_REQUEST_PATH, "/client/path");
+ when(address.getFirst(Const.URL_PREFIX)).thenReturn(null);
+
+ String path = restClientInvocation.createRequestPath(swaggerRestOperation);
+ Assert.assertEquals("/client/path", path);
+ }
+
+ @Test
+ public void createRequestPath_haveUrlPrefixNoPath() throws Exception {
+ when(address.getFirst(Const.URL_PREFIX)).thenReturn("/prefix");
+
+ when(urlPathBuilder.createRequestPath(any())).thenReturn("/path");
+
+ String path = restClientInvocation.createRequestPath(swaggerRestOperation);
+ Assert.assertEquals("/prefix/path", path);
+ }
+
+ @Test
+ public void createRequestPath_haveUrlPrefixHavePath() throws Exception {
+ when(address.getFirst(Const.URL_PREFIX)).thenReturn("/prefix");
+ handlerContext.put(RestConst.REST_CLIENT_REQUEST_PATH, "/client/path");
+
+ String path = restClientInvocation.createRequestPath(swaggerRestOperation);
+ Assert.assertEquals("/prefix/client/path", path);
+ }
+
+ @Test
+ public void createRequestPath_haveUrlPrefixHavePathAndStartWith() throws Exception {
+ when(address.getFirst(Const.URL_PREFIX)).thenReturn("/prefix");
+ handlerContext.put(RestConst.REST_CLIENT_REQUEST_PATH, "/prefix/client/path");
+
+ String path = restClientInvocation.createRequestPath(swaggerRestOperation);
+ Assert.assertEquals("/prefix/client/path", path);
+ }
+}
diff --git a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestVertxHttpMethod.java b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestVertxHttpMethod.java
deleted file mode 100644
index 1c9dcfe..0000000
--- a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestVertxHttpMethod.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.transport.rest.client.http;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.common.rest.RestConst;
-import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
-import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
-import org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;
-import org.apache.servicecomb.core.Endpoint;
-import org.apache.servicecomb.core.Invocation;
-import org.apache.servicecomb.core.definition.OperationMeta;
-import org.apache.servicecomb.foundation.common.net.IpPort;
-import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
-import org.apache.servicecomb.foundation.vertx.client.http.HttpClientWithContext;
-import org.apache.servicecomb.serviceregistry.api.Const;
-import org.apache.servicecomb.swagger.invocation.AsyncResponse;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import io.vertx.core.Context;
-import io.vertx.core.Handler;
-import io.vertx.core.http.HttpClient;
-import io.vertx.core.http.HttpClientRequest;
-import io.vertx.core.http.HttpClientResponse;
-import io.vertx.core.http.HttpMethod;
-import mockit.Expectations;
-import mockit.Injectable;
-import mockit.Mock;
-import mockit.MockUp;
-import mockit.Mocked;
-
-public class TestVertxHttpMethod extends VertxHttpMethod {
-
- HttpClientRequest request;
-
- @Before
- public void setup() {
- request = mock(HttpClientRequest.class);
- }
-
- @Test
- public void testDoMethodNullPointerException(@Mocked HttpClient httpClient) throws Exception {
- Context context = new MockUp<Context>() {
- @Mock
- public void runOnContext(Handler<Void> action) {
- action.handle(null);
- }
- }.getMockInstance();
- HttpClientWithContext httpClientWithContext = new HttpClientWithContext(httpClient, context);
-
- Invocation invocation = mock(Invocation.class);
- AsyncResponse asyncResp = mock(AsyncResponse.class);
-
- try {
- this.doMethod(httpClientWithContext, invocation, asyncResp);
- fail("Expect to throw NullPointerException, but got none");
- } catch (NullPointerException e) {
- }
- }
-
- @Test
- public void testDoMethod(@Mocked HttpClient httpClient, @Injectable URIEndpointObject address) throws Exception {
- Context context = new MockUp<Context>() {
- @Mock
- public void runOnContext(Handler<Void> action) {
- action.handle(null);
- }
- }.getMockInstance();
- HttpClientWithContext httpClientWithContext = new HttpClientWithContext(httpClient, context);
-
- Invocation invocation = mock(Invocation.class);
- AsyncResponse asyncResp = mock(AsyncResponse.class);
- OperationMeta operationMeta = mock(OperationMeta.class);
- RestOperationMeta swaggerRestOperation = mock(RestOperationMeta.class);
-
- Endpoint endpoint = mock(Endpoint.class);
- when(invocation.getOperationMeta()).thenReturn(operationMeta);
- URLPathBuilder urlPathBuilder = mock(URLPathBuilder.class);
- when(swaggerRestOperation.getPathBuilder()).thenReturn(urlPathBuilder);
- operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
- when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerRestOperation);
- when(invocation.getEndpoint()).thenReturn(endpoint);
- when(endpoint.getAddress()).thenReturn(address);
-
- when(request.exceptionHandler(Mockito.any())).then(answer -> null);
- Map<String, Object> map = new HashMap<>();
- when(invocation.getHandlerContext()).then(answer -> map);;
-
- this.doMethod(httpClientWithContext, invocation, asyncResp);
- Assert.assertTrue(true);
- }
-
- @Test
- public void testCreateRequest() {
- HttpClient client = mock(HttpClient.class);
- Invocation invocation = mock(Invocation.class);
- OperationMeta operationMeta = mock(OperationMeta.class);
- Endpoint endpoint = mock(Endpoint.class);
- URIEndpointObject address = mock(URIEndpointObject.class);
- when(invocation.getEndpoint()).thenReturn(endpoint);
- when(endpoint.getAddress()).thenReturn(address);
- when(address.isSslEnabled()).thenReturn(false);
- when(invocation.getOperationMeta()).thenReturn(operationMeta);
- RestOperationMeta swaggerRestOperation = mock(RestOperationMeta.class);
- when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerRestOperation);
- IpPort ipPort = mock(IpPort.class);
- when(ipPort.getPort()).thenReturn(10);
- when(ipPort.getHostOrIp()).thenReturn("ever");
- AsyncResponse asyncResp = mock(AsyncResponse.class);
- List<HttpMethod> methods = new ArrayList<>(
- Arrays.asList(HttpMethod.GET, HttpMethod.PUT, HttpMethod.POST, HttpMethod.DELETE, HttpMethod.PATCH));
- for (HttpMethod method : methods) {
- when(swaggerRestOperation.getHttpMethod()).thenReturn(method.toString());
- HttpClientRequest obj =
- VertxHttpMethod.INSTANCE.createRequest(client, invocation, ipPort, "good", asyncResp);
- Assert.assertNull(obj);
- }
- }
-
- @Test
- public void testSetCseContext() {
- boolean status = false;
- try {
- Invocation invocation = mock(Invocation.class);
- HttpClientResponse httpResponse = mock(HttpClientResponse.class);
- OperationMeta operationMeta = mock(OperationMeta.class);
- RestOperationMeta swaggerRestOperation = mock(RestOperationMeta.class);
- HttpClientRequest request = mock(HttpClientRequest.class);
-
- Endpoint endpoint = mock(Endpoint.class);
- when(invocation.getOperationMeta()).thenReturn(operationMeta);
- URLPathBuilder urlPathBuilder = mock(URLPathBuilder.class);
- when(swaggerRestOperation.getPathBuilder()).thenReturn(urlPathBuilder);
- operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
- when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerRestOperation);
- when(invocation.getEndpoint()).thenReturn(endpoint);
- String contentType = httpResponse.getHeader("Content-Type");
- ProduceProcessor produceProcessor = mock(ProduceProcessor.class);
- when(swaggerRestOperation.findProduceProcessor(contentType)).thenReturn(produceProcessor);
- this.setCseContext(invocation, request);
- } catch (Exception ex) {
- status = true;
- }
- Assert.assertFalse(status);
- }
-
- @Test
- public void testHandleResponse() {
- boolean status = false;
- try {
- Invocation invocation = mock(Invocation.class);
- AsyncResponse asyncResp = mock(AsyncResponse.class);
- HttpClientResponse httpResponse = mock(HttpClientResponse.class);
- OperationMeta operationMeta = mock(OperationMeta.class);
- RestOperationMeta swaggerRestOperation = mock(RestOperationMeta.class);
-
- Endpoint endpoint = mock(Endpoint.class);
- when(invocation.getOperationMeta()).thenReturn(operationMeta);
- URLPathBuilder urlPathBuilder = mock(URLPathBuilder.class);
- when(swaggerRestOperation.getPathBuilder()).thenReturn(urlPathBuilder);
- operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
- when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(swaggerRestOperation);
- when(invocation.getEndpoint()).thenReturn(endpoint);
-
- String contentType = httpResponse.getHeader("Content-Type");
- ProduceProcessor produceProcessor = mock(ProduceProcessor.class);
- when(swaggerRestOperation.findProduceProcessor(contentType)).thenReturn(produceProcessor);
- this.handleResponse(invocation, httpResponse, asyncResp);
- } catch (Exception ex) {
- status = true;
- }
- Assert.assertFalse(status);
- }
-
- @Override
- protected HttpClientRequest createRequest(HttpClient client, Invocation invocation, IpPort ipPort, String path,
- AsyncResponse asyncResp) {
- return request;
- }
-
- @Test
- public void testCreateRequestPathNoUrlPrefixNoPath(@Injectable Invocation invocation,
- @Injectable RestOperationMeta swaggerRestOperation, @Injectable Endpoint endpoint,
- @Injectable URIEndpointObject address, @Injectable URLPathBuilder builder) throws Exception {
- new Expectations() {
- {
- endpoint.getAddress();
- result = address;
- builder.createRequestPath((Object[]) any);
- result = "/path";
- }
- };
- String path = this.createRequestPath(invocation, swaggerRestOperation);
- Assert.assertEquals("/path", path);
- }
-
- @Test
- public void testCreateRequestPathNoUrlPrefixHavePath(@Injectable Invocation invocation,
- @Injectable RestOperationMeta swaggerRestOperation, @Injectable Endpoint endpoint,
- @Injectable URIEndpointObject address, @Injectable URLPathBuilder builder) throws Exception {
- Map<String, Object> contextMap = new HashMap<>();
- contextMap.put(RestConst.REST_CLIENT_REQUEST_PATH, "/client/path");
-
- new Expectations() {
- {
- endpoint.getAddress();
- result = address;
- invocation.getHandlerContext();
- result = contextMap;
- }
- };
- String path = this.createRequestPath(invocation, swaggerRestOperation);
- Assert.assertEquals("/client/path", path);
- }
-
- @Test
- public void testCreateRequestPathHaveUrlPrefixNoPath(@Injectable Invocation invocation,
- @Injectable RestOperationMeta swaggerRestOperation, @Injectable Endpoint endpoint,
- @Injectable URIEndpointObject address, @Injectable URLPathBuilder builder) throws Exception {
- new Expectations() {
- {
- endpoint.getAddress();
- result = address;
- address.getFirst(Const.URL_PREFIX);
- result = "/root";
- builder.createRequestPath((Object[]) any);
- result = "/path";
- }
- };
- String path = this.createRequestPath(invocation, swaggerRestOperation);
- Assert.assertEquals("/root/path", path);
- }
-
- @Test
- public void testCreateRequestPathHaveUrlPrefixHavePath(@Injectable Invocation invocation,
- @Injectable RestOperationMeta swaggerRestOperation, @Injectable Endpoint endpoint,
- @Injectable URIEndpointObject address, @Injectable URLPathBuilder builder) throws Exception {
- Map<String, Object> contextMap = new HashMap<>();
- contextMap.put(RestConst.REST_CLIENT_REQUEST_PATH, "/client/path");
-
- new Expectations() {
- {
- endpoint.getAddress();
- result = address;
- address.getFirst(Const.URL_PREFIX);
- result = "/root";
- invocation.getHandlerContext();
- result = contextMap;
- }
- };
- String path = this.createRequestPath(invocation, swaggerRestOperation);
- Assert.assertEquals("/root/client/path", path);
- }
-
- @Test
- public void testCreateRequestPathHaveUrlPrefixHavePathAndStartWith(@Injectable Invocation invocation,
- @Injectable RestOperationMeta swaggerRestOperation, @Injectable Endpoint endpoint,
- @Injectable URIEndpointObject address, @Injectable URLPathBuilder builder) throws Exception {
- Map<String, Object> contextMap = new HashMap<>();
- contextMap.put(RestConst.REST_CLIENT_REQUEST_PATH, "/client/path");
-
- new Expectations() {
- {
- endpoint.getAddress();
- result = address;
- address.getFirst(Const.URL_PREFIX);
- result = "/client";
- invocation.getHandlerContext();
- result = contextMap;
- }
- };
- String path = this.createRequestPath(invocation, swaggerRestOperation);
- Assert.assertEquals("/client/path", path);
- }
-}
--
To stop receiving notification emails like this one, please contact
liubao@apache.org.