This is an automated email from the ASF dual-hosted git repository. amccright pushed a commit to branch 3.2.x-fixes in repository https://gitbox.apache.org/repos/asf/cxf.git
commit b14c73fde58d8e300ab043381e24c9caa2cb4732 Author: Andy McCright <j.andrew.mccri...@gmail.com> AuthorDate: Thu Jul 5 17:24:07 2018 -0500 [CXF-7673] MP Rest Client 1.1 Impl (continued) Various changes to account for change to use CompletionStage and to pass the 1.1 TCK: * Remove changes for InvocationCallback - spec voted against it * Changed Future to CompletionStage * Ensure ResponseImpl.getLocation() returns a non-null URI * Using CompletableFuture in JaxrsClientCallback * Updates to pom.xml files to use public MP Rest Client API and TCK * Throw IllegalArgumentException if executorService is null * Show preference to baseURI config in CDI * Modify MP Rest Client tests to expect latest version of spec changes --- .../org/apache/cxf/jaxrs/impl/ResponseImpl.java | 3 + .../apache/cxf/jaxrs/client/ClientProxyImpl.java | 1 - .../cxf/jaxrs/client/JaxrsClientCallback.java | 5 +- rt/rs/microprofile-client/pom.xml | 4 +- .../client/CxfTypeSafeClientBuilder.java | 3 + .../apache/cxf/microprofile/client/Validator.java | 16 +- .../microprofile/client/cdi/RestClientBean.java | 36 ++-- .../client/proxy/MicroProfileClientProxyImpl.java | 55 ++---- systests/microprofile/client/async/pom.xml | 4 +- .../microprofile/rest/client/AsyncMethodTest.java | 195 ++------------------- ...re.java => AsyncClientWithCompletionStage.java} | 6 +- .../mock/AsyncClientWithInvocationCallback.java | 31 ---- systests/microprofile/pom.xml | 2 +- 13 files changed, 69 insertions(+), 292 deletions(-) diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java index 617e8ee..0dfeec0 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ResponseImpl.java @@ -238,6 +238,9 @@ public final class ResponseImpl extends Response { public URI getLocation() { Object header = metadata.getFirst(HttpHeaders.LOCATION); + if (header == null) { + header = outMessage.get(Message.REQUEST_URI); + } return header == null || header instanceof URI ? (URI)header : URI.create(header.toString()); } diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java index ac0cace..cc5dfea 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/ClientProxyImpl.java @@ -824,7 +824,6 @@ public class ClientProxyImpl extends AbstractClient implements } } return null; - } private InvocationCallback<Object> doCheckAsyncCallback(OperationResourceInfo ori, diff --git a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JaxrsClientCallback.java b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JaxrsClientCallback.java index 98443c5..227242f 100644 --- a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JaxrsClientCallback.java +++ b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/JaxrsClientCallback.java @@ -22,6 +22,7 @@ package org.apache.cxf.jaxrs.client; import java.lang.reflect.Type; import java.util.Map; import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -64,7 +65,7 @@ public class JaxrsClientCallback<T> extends ClientCallback { return result; } - public Future<T> createFuture() { + public CompletableFuture<T> createFuture() { return new JaxrsResponseFuture<T>(this); } @@ -96,7 +97,7 @@ public class JaxrsClientCallback<T> extends ClientCallback { - static class JaxrsResponseFuture<T> implements Future<T> { + static class JaxrsResponseFuture<T> extends CompletableFuture<T> implements Future<T> { JaxrsClientCallback<T> callback; JaxrsResponseFuture(JaxrsClientCallback<T> cb) { callback = cb; diff --git a/rt/rs/microprofile-client/pom.xml b/rt/rs/microprofile-client/pom.xml index 965da32..60a83ff 100644 --- a/rt/rs/microprofile-client/pom.xml +++ b/rt/rs/microprofile-client/pom.xml @@ -104,7 +104,7 @@ <dependency> <groupId>org.eclipse.microprofile.rest.client</groupId> <artifactId>microprofile-rest-client-api</artifactId> - <version>1.1.0.20180323</version> + <version>1.1</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> @@ -119,7 +119,7 @@ <dependency> <groupId>org.eclipse.microprofile.rest.client</groupId> <artifactId>microprofile-rest-client-tck</artifactId> - <version>1.1.0.20180323</version> + <version>1.1</version> <exclusions> <exclusion> <groupId>org.testng</groupId> diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java index 4ddf6a8..ed77152 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilder.java @@ -50,6 +50,9 @@ public class CxfTypeSafeClientBuilder implements RestClientBuilder, Configurable @Override public RestClientBuilder executorService(ExecutorService executor) { + if (null == executor) { + throw new IllegalArgumentException("executor must not be null"); + } this.executorService = executor; return this; } diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/Validator.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/Validator.java index 88de84c..3155164 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/Validator.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/Validator.java @@ -22,7 +22,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -34,7 +33,6 @@ import java.util.Set; import javax.ws.rs.HttpMethod; import javax.ws.rs.Path; import javax.ws.rs.PathParam; -import javax.ws.rs.client.InvocationCallback; import org.apache.cxf.common.i18n.BundleUtils; import org.apache.cxf.common.i18n.Message; @@ -47,6 +45,7 @@ final class Validator { private Validator() { } + public static void checkValid(Class<?> userType) throws RestClientDefinitionException { if (!userType.isInterface()) { throwException("VALIDATION_NOT_AN_INTERFACE", userType); @@ -54,7 +53,6 @@ final class Validator { Method[] methods = userType.getMethods(); checkMethodsForMultipleHTTPMethodAnnotations(methods); checkMethodsForInvalidURITemplates(userType, methods); - checkAsyncMethods(userType, methods); } private static void checkMethodsForMultipleHTTPMethodAnnotations(Method[] clientMethods) @@ -131,18 +129,6 @@ final class Validator { } } - private static void checkAsyncMethods(Class<?> userType, Method[] clientMethods) { - for (Method method : clientMethods) { - boolean containsInvocationCallbackParm = Arrays.asList(method.getParameterTypes()) - .contains(InvocationCallback.class); - Class<?> returnType = method.getReturnType(); - if (containsInvocationCallbackParm && returnType != void.class) { - throwException("VALIDATION_ASYNC_METHOD_RETURNS_UNEXPECTED_TYPE", userType.getName(), - method.getName(), returnType.getName()); - } - } - } - private static void throwException(String msgKey, Object...msgParams) throws RestClientDefinitionException { Message msg = new Message(msgKey, BUNDLE, msgParams); throw new RestClientDefinitionException(msg.toString()); diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java index 23868f6..d9f47e9 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/cdi/RestClientBean.java @@ -20,13 +20,13 @@ package org.apache.cxf.microprofile.client.cdi; import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import java.net.MalformedURLException; -import java.net.URL; +import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.Set; import javax.enterprise.context.Dependent; @@ -45,6 +45,7 @@ import org.eclipse.microprofile.rest.client.inject.RestClient; public class RestClientBean implements Bean<Object>, PassivationCapable { public static final String REST_URL_FORMAT = "%s/mp-rest/url"; + public static final String REST_URI_FORMAT = "%s/mp-rest/uri"; public static final String REST_SCOPE_FORMAT = "%s/mp-rest/scope"; private static final Default DEFAULT_LITERAL = new DefaultLiteral(); private final Class<?> clientInterface; @@ -79,12 +80,8 @@ public class RestClientBean implements Bean<Object>, PassivationCapable { @Override public Object create(CreationalContext<Object> creationalContext) { CxfTypeSafeClientBuilder builder = new CxfTypeSafeClientBuilder(); - String baseUrl = getBaseUrl(); - try { - return builder.baseUrl(new URL(baseUrl)).build(clientInterface); - } catch (MalformedURLException e) { - throw new IllegalArgumentException("The value of URL was invalid " + baseUrl); - } + String baseUri = getBaseUri(); + return builder.baseUri(URI.create(baseUri)).build(clientInterface); } @Override @@ -122,13 +119,24 @@ public class RestClientBean implements Bean<Object>, PassivationCapable { return false; } - private String getBaseUrl() { - String property = String.format(REST_URL_FORMAT, clientInterface.getName()); - String baseURL = ConfigFacade.getValue(property, String.class); - if (baseURL == null) { - throw new IllegalStateException("Unable to determine base URL from configuration"); + private String getBaseUri() { + String interfaceName = clientInterface.getName(); + String property = String.format(REST_URI_FORMAT, interfaceName); + String baseURI = null; + try { + baseURI = ConfigFacade.getValue(property, String.class); + } catch (NoSuchElementException ex) { + // no-op - will revert to baseURL config value (as opposed to baseURI) + } + if (baseURI == null) { + // revert to baseUrl + property = String.format(REST_URL_FORMAT, interfaceName); + baseURI = ConfigFacade.getValue(property, String.class); + if (baseURI == null) { + throw new IllegalStateException("Unable to determine base URI from configuration"); + } } - return baseURL; + return baseURI; } private Class<? extends Annotation> readScope() { diff --git a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java index 89dd84c..384b188 100644 --- a/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java +++ b/rt/rs/microprofile-client/src/main/java/org/apache/cxf/microprofile/client/proxy/MicroProfileClientProxyImpl.java @@ -23,8 +23,8 @@ import java.lang.reflect.Type; import java.net.URI; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; import javax.ws.rs.client.InvocationCallback; import javax.ws.rs.core.Response; @@ -35,25 +35,19 @@ import org.apache.cxf.jaxrs.client.JaxrsClientCallback; import org.apache.cxf.jaxrs.client.LocalClientState; import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; -import org.apache.cxf.jaxrs.model.Parameter; -import org.apache.cxf.jaxrs.model.ParameterType; import org.apache.cxf.jaxrs.utils.InjectionUtils; import org.apache.cxf.message.Message; import org.apache.cxf.microprofile.client.MicroProfileClientProviderFactory; import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; public class MicroProfileClientProxyImpl extends ClientProxyImpl { - private static final InvocationCallback<Object> MARKER_CALLBACK = new InvocationCallback<Object>() { + private static final InvocationCallback<Object> NO_OP_CALLBACK = new InvocationCallback<Object>() { @Override - public void completed(Object paramRESPONSE) { - // no-op - } + public void failed(Throwable t) { } @Override - public void failed(Throwable paramThrowable) { - // no-op - } + public void completed(Object o) { } }; private final MPAsyncInvocationInterceptorImpl aiiImpl = new MPAsyncInvocationInterceptorImpl(); @@ -79,12 +73,19 @@ public class MicroProfileClientProxyImpl extends ClientProxyImpl { protected InvocationCallback<Object> checkAsyncCallback(OperationResourceInfo ori, Map<String, Object> reqContext, Message outMessage) { - if (Future.class.equals(ori.getMethodToInvoke().getReturnType())) { - return MARKER_CALLBACK; + InvocationCallback<Object> callback = outMessage.getContent(InvocationCallback.class); + if (callback == null && CompletionStage.class.equals(ori.getMethodToInvoke().getReturnType())) { + callback = NO_OP_CALLBACK; + outMessage.setContent(InvocationCallback.class, callback); } - return outMessage.getContent(InvocationCallback.class); + return callback; } + protected boolean checkAsyncReturnType(OperationResourceInfo ori, + Map<String, Object> reqContext, + Message outMessage) { + return CompletionStage.class.equals(ori.getMethodToInvoke().getReturnType()); + } @Override protected Object doInvokeAsync(OperationResourceInfo ori, Message outMessage, @@ -94,12 +95,8 @@ public class MicroProfileClientProxyImpl extends ClientProxyImpl { super.doInvokeAsync(ori, outMessage, asyncCallback); - Future<?> future = null; - if (asyncCallback == MARKER_CALLBACK) { - JaxrsClientCallback<?> cb = outMessage.getExchange().get(JaxrsClientCallback.class); - future = cb.createFuture(); - } - return future; + JaxrsClientCallback<?> cb = outMessage.getExchange().get(JaxrsClientCallback.class); + return cb.createFuture(); } @Override @@ -127,29 +124,11 @@ public class MicroProfileClientProxyImpl extends ClientProxyImpl { @Override protected Class<?> getReturnType(Method method, Message outMessage) { - if (!outMessage.getExchange().isSynchronous()) { - InvocationCallback<?> callback = outMessage.getContent(InvocationCallback.class); - if (callback != null) { - Type t = getCallbackType(callback); - if (t instanceof Class) { - return (Class<?>) t; - } - } - } Class<?> returnType = super.getReturnType(method, outMessage); - if (Future.class.isAssignableFrom(returnType)) { + if (CompletionStage.class.isAssignableFrom(returnType)) { Type t = method.getGenericReturnType(); returnType = InjectionUtils.getActualType(t); } return returnType; } - - @Override - protected boolean isIgnorableParameter(Method m, Parameter p) { - if (p.getType() == ParameterType.CONTEXT) { - return true; - } - return p.getType() == ParameterType.REQUEST_BODY - && m.getParameterTypes()[p.getIndex()] == InvocationCallback.class; - } } diff --git a/systests/microprofile/client/async/pom.xml b/systests/microprofile/client/async/pom.xml index b4e9167..1c854b4 100644 --- a/systests/microprofile/client/async/pom.xml +++ b/systests/microprofile/client/async/pom.xml @@ -21,7 +21,7 @@ <parent> <artifactId>cxf-microprofile-tck</artifactId> <groupId>org.apache.cxf.systests</groupId> - <version>3.2.5-SNAPSHOT</version> + <version>3.3.0-SNAPSHOT</version> <relativePath>../../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> @@ -32,7 +32,7 @@ <url>http://cxf.apache.org</url> <properties> <cxf.geronimo.config.version>1.0</cxf.geronimo.config.version> - <cxf.microprofile.rest.client.version>1.1.0.20180323</cxf.microprofile.rest.client.version> + <cxf.microprofile.rest.client.version>1.1</cxf.microprofile.rest.client.version> <cxf.wiremock.params>--port=8765</cxf.wiremock.params> <cxf.weld.se.version>2.4.5.Final</cxf.weld.se.version> <cxf.arquillian.weld.container.version>2.0.0.Final</cxf.arquillian.weld.container.version> diff --git a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/AsyncMethodTest.java b/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/AsyncMethodTest.java index a25e865..19efc46 100644 --- a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/AsyncMethodTest.java +++ b/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/AsyncMethodTest.java @@ -19,24 +19,18 @@ package org.apache.cxf.systest.microprofile.rest.client; import java.net.URI; -import java.net.URL; -import java.util.ArrayList; import java.util.List; -import java.util.concurrent.CountDownLatch; +import java.util.concurrent.CompletionStage; import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.client.InvocationCallback; import javax.ws.rs.core.Response; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.junit.WireMockRule; -import org.apache.cxf.systest.microprofile.rest.client.mock.AsyncClientWithFuture; -import org.apache.cxf.systest.microprofile.rest.client.mock.AsyncClientWithInvocationCallback; +import org.apache.cxf.systest.microprofile.rest.client.mock.AsyncClientWithCompletionStage; import org.apache.cxf.systest.microprofile.rest.client.mock.AsyncInvocationInterceptorFactoryTestImpl; import org.apache.cxf.systest.microprofile.rest.client.mock.AsyncInvocationInterceptorFactoryTestImpl2; import org.apache.cxf.systest.microprofile.rest.client.mock.ThreadLocalClientFilter; @@ -62,181 +56,16 @@ public class AsyncMethodTest extends Assert { @Rule public WireMockRule wireMockRule = new WireMockRule(WireMockConfiguration.options().dynamicPort()); - private static class StringInvocationCallback implements InvocationCallback<String> { - private final List<Object> results; - private final CountDownLatch latch; - - StringInvocationCallback(List<Object> results, CountDownLatch latch) { - this.results = results; - this.latch = latch; - } - - /** {@inheritDoc}*/ - @Override - public void completed(String response) { - results.add(response); - results.add(Thread.currentThread().getId()); - latch.countDown(); - } - - /** {@inheritDoc}*/ - @Override - public void failed(Throwable th) { - results.add(th); - results.add(Thread.currentThread().getId()); - latch.countDown(); - } - } - - private static class ResponseInvocationCallback implements InvocationCallback<Response> { - final List<String> inboundList = new ArrayList<>(); - Throwable throwable; - private final CountDownLatch latch; - - - ResponseInvocationCallback(CountDownLatch latch) { - this.latch = latch; - } - - /** {@inheritDoc}*/ - @Override - public void completed(Response response) { - inboundList.addAll(response.getStringHeaders().get("CXFTestResponse")); - latch.countDown(); - } - - /** {@inheritDoc}*/ - @Override - public void failed(Throwable th) { - throwable = th; - latch.countDown(); - } - } - - @Test - public void testInvokesPostOperationWithRegisteredProvidersAsyncInvocationCallback() throws Exception { - wireMockRule.stubFor(put(urlEqualTo("/echo/test")) - .willReturn(aResponse() - .withBody("this is the replaced writer input body will be removed"))); - long mainThreadId = Thread.currentThread().getId(); - String inputBody = "input body will be removed"; - String expectedResponseBody = TestMessageBodyReader.REPLACED_BODY; - - AsyncClientWithInvocationCallback api = RestClientBuilder.newBuilder() - .register(TestClientRequestFilter.class) - .register(TestClientResponseFilter.class) - .register(TestMessageBodyReader.class, 3) - .register(TestMessageBodyWriter.class) - .register(TestParamConverterProvider.class) - .register(TestReaderInterceptor.class) - .register(TestWriterInterceptor.class) - .baseUri(getBaseUri()) - .build(AsyncClientWithInvocationCallback.class); - - final List<Object> responseBodyList = new ArrayList<>(); - final CountDownLatch latch = new CountDownLatch(1); - - api.put(new StringInvocationCallback(responseBodyList, latch), inputBody); - - latch.await(20, TimeUnit.SECONDS); // should need <1 second, but 20s timeout in case something goes wrong - assertEquals(2, responseBodyList.size()); - - assertEquals(expectedResponseBody, responseBodyList.get(0)); - assertNotEquals(mainThreadId, responseBodyList.get(1)); - - assertEquals(TestClientResponseFilter.getAndResetValue(), 1); - assertEquals(TestClientRequestFilter.getAndResetValue(), 1); - assertEquals(TestReaderInterceptor.getAndResetValue(), 1); - } - - @Test - public void testInvokesPostOperationWithRegisteredProvidersAsyncInvocationCallbackWithExecutor() throws Exception { - final String inputBody = "input body will be ignored"; - wireMockRule.stubFor(put(urlEqualTo("/echo/test")) - .willReturn(aResponse() - .withBody(inputBody))); - AsyncInvocationInterceptorFactoryTestImpl.INBOUND.remove(); - AsyncInvocationInterceptorFactoryTestImpl.OUTBOUND.remove(); - try { - final String asyncThreadName = "CXF-MPRestClientThread-1"; - - AsyncClientWithInvocationCallback api = RestClientBuilder.newBuilder() - .register(AsyncInvocationInterceptorFactoryTestImpl.class) - .register(AsyncInvocationInterceptorFactoryTestImpl2.class) - .register(ThreadLocalClientFilter.class) - .baseUri(getBaseUri()) - .executorService(Executors.newSingleThreadExecutor(new ThreadFactory() { - - @Override - public Thread newThread(Runnable r) { - return new Thread(r, asyncThreadName); - } - })) - .build(AsyncClientWithInvocationCallback.class); - - final CountDownLatch latch = new CountDownLatch(1); - - ResponseInvocationCallback callback = new ResponseInvocationCallback(latch); - api.put(callback, inputBody); - List<String> outboundList = AsyncInvocationInterceptorFactoryTestImpl.OUTBOUND.get(); - assertEquals(4, outboundList.size()); - - // ensure filters and asyncInvocationInterceptors are executed in the correct order and the correct thread - // outbound: - assertEquals(ThreadLocalClientFilter.class.getSimpleName(), outboundList.get(0)); - assertEquals(AsyncInvocationInterceptorFactoryTestImpl.class.getSimpleName(), outboundList.get(1)); - assertEquals(AsyncInvocationInterceptorFactoryTestImpl2.class.getSimpleName(), outboundList.get(2)); - assertEquals(Thread.currentThread().getName(), outboundList.get(3)); - - // inbound: - latch.await(20, TimeUnit.SECONDS); // should need <1 second, but 20s timeout in case something goes wrong - assertNull(callback.throwable); - List<String> responseList = callback.inboundList; - assertEquals(4, responseList.size()); - - assertEquals(asyncThreadName, responseList.get(0)); - assertEquals(AsyncInvocationInterceptorFactoryTestImpl2.class.getSimpleName(), responseList.get(1)); - assertEquals(AsyncInvocationInterceptorFactoryTestImpl.class.getSimpleName(), responseList.get(2)); - assertEquals(ThreadLocalClientFilter.class.getSimpleName(), responseList.get(3)); - } finally { - AsyncInvocationInterceptorFactoryTestImpl.INBOUND.remove(); - AsyncInvocationInterceptorFactoryTestImpl.OUTBOUND.remove(); - } - } - - @Test - public void testInvokesPostOperationWithRegisteredProvidersAsyncInvocationCallbackWithException() throws Exception { - wireMockRule.stubFor(put(urlEqualTo("/Missing/test")) - .willReturn(status(404))); - long mainThreadId = Thread.currentThread().getId(); - String inputBody = "input body will be removed"; - - AsyncClientWithInvocationCallback api = RestClientBuilder.newBuilder() - .baseUrl(new URL("http://localhost:" + wireMockRule.port() + "/Missing")) - .build(AsyncClientWithInvocationCallback.class); - - final List<Object> responseBodyList = new ArrayList<>(); - final CountDownLatch latch = new CountDownLatch(1); - - api.put(new StringInvocationCallback(responseBodyList, latch), inputBody); - - latch.await(20, TimeUnit.SECONDS); // should need <1 second, but 20s timeout in case something goes wrong - assertEquals(2, responseBodyList.size()); - Object body = responseBodyList.get(0); - - assertTrue(body instanceof WebApplicationException); - assertNotEquals(mainThreadId, responseBodyList.get(1)); - } @Test - public void testInvokesPostOperationWithRegisteredProvidersAsyncFuture() throws Exception { + public void testInvokesPostOperationWithRegisteredProvidersAsyncCompletionStage() throws Exception { wireMockRule.stubFor(put(urlEqualTo("/echo/test")) .willReturn(aResponse() .withBody("this is the replaced writer input body will be removed"))); String inputBody = "input body will be removed"; String expectedResponseBody = TestMessageBodyReader.REPLACED_BODY; - AsyncClientWithFuture api = RestClientBuilder.newBuilder() + AsyncClientWithCompletionStage api = RestClientBuilder.newBuilder() .register(TestClientRequestFilter.class) .register(TestClientResponseFilter.class) .register(TestMessageBodyReader.class, 3) @@ -245,12 +74,12 @@ public class AsyncMethodTest extends Assert { .register(TestReaderInterceptor.class) .register(TestWriterInterceptor.class) .baseUri(getBaseUri()) - .build(AsyncClientWithFuture.class); + .build(AsyncClientWithCompletionStage.class); - Future<Response> future = api.put(inputBody); + CompletionStage<Response> cs = api.put(inputBody); // should need <1 second, but 20s timeout in case something goes wrong - Response response = future.get(20, TimeUnit.SECONDS); + Response response = cs.toCompletableFuture().get(20, TimeUnit.SECONDS); String actualResponseBody = response.readEntity(String.class); assertEquals(expectedResponseBody, actualResponseBody); @@ -261,7 +90,7 @@ public class AsyncMethodTest extends Assert { } @Test - public void testInvokesPostOperationWithRegisteredProvidersAsyncFutureWithExecutor() throws Exception { + public void testInvokesPostOperationWithRegisteredProvidersAsyncCompletionStageWithExecutor() throws Exception { final String inputBody = "input body will be ignored"; wireMockRule.stubFor(put(urlEqualTo("/echo/test")) .willReturn(aResponse() @@ -271,7 +100,7 @@ public class AsyncMethodTest extends Assert { try { final String asyncThreadName = "CXF-MPRestClientThread-2"; - AsyncClientWithFuture api = RestClientBuilder.newBuilder() + AsyncClientWithCompletionStage api = RestClientBuilder.newBuilder() .register(AsyncInvocationInterceptorFactoryTestImpl.class) .register(AsyncInvocationInterceptorFactoryTestImpl2.class) .register(ThreadLocalClientFilter.class) @@ -283,9 +112,9 @@ public class AsyncMethodTest extends Assert { return new Thread(r, asyncThreadName); } })) - .build(AsyncClientWithFuture.class); + .build(AsyncClientWithCompletionStage.class); - Future<Response> future = api.put(inputBody); + CompletionStage<Response> cs = api.put(inputBody); List<String> outboundList = AsyncInvocationInterceptorFactoryTestImpl.OUTBOUND.get(); assertEquals(4, outboundList.size()); @@ -298,7 +127,7 @@ public class AsyncMethodTest extends Assert { // inbound: // should need <1 second, but 20s timeout in case something goes wrong - Response response = future.get(20, TimeUnit.SECONDS); + Response response = cs.toCompletableFuture().get(20, TimeUnit.SECONDS); List<String> responseList = response.getStringHeaders().get("CXFTestResponse"); assertEquals(4, responseList.size()); diff --git a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithFuture.java b/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithCompletionStage.java similarity index 87% rename from systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithFuture.java rename to systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithCompletionStage.java index b2408d1..d30a2d0 100644 --- a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithFuture.java +++ b/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithCompletionStage.java @@ -19,15 +19,15 @@ package org.apache.cxf.systest.microprofile.rest.client.mock; -import java.util.concurrent.Future; +import java.util.concurrent.CompletionStage; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.core.Response; -public interface AsyncClientWithFuture { +public interface AsyncClientWithCompletionStage { @PUT @Path("/test") - Future<Response> put(String text); + CompletionStage<Response> put(String text); } diff --git a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithInvocationCallback.java b/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithInvocationCallback.java deleted file mode 100644 index df0b352..0000000 --- a/systests/microprofile/client/async/src/test/java/org/apache/cxf/systest/microprofile/rest/client/mock/AsyncClientWithInvocationCallback.java +++ /dev/null @@ -1,31 +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.cxf.systest.microprofile.rest.client.mock; - -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.client.InvocationCallback; - -public interface AsyncClientWithInvocationCallback { - - @PUT - @Path("/test") - void put(InvocationCallback<?> callback, String text); -} diff --git a/systests/microprofile/pom.xml b/systests/microprofile/pom.xml index 90cc036..a2524c9 100644 --- a/systests/microprofile/pom.xml +++ b/systests/microprofile/pom.xml @@ -33,7 +33,7 @@ <url>http://cxf.apache.org</url> <properties> <cxf.geronimo.config.version>1.0</cxf.geronimo.config.version> - <cxf.microprofile.rest.client.version>1.1.0.20180323</cxf.microprofile.rest.client.version> + <cxf.microprofile.rest.client.version>1.1</cxf.microprofile.rest.client.version> <cxf.wiremock.params>--port=8765</cxf.wiremock.params> <cxf.weld.se.version>2.4.5.Final</cxf.weld.se.version> <cxf.arquillian.weld.container.version>2.0.0.Final</cxf.arquillian.weld.container.version>