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 2d31ae8b701..a567f83a04f 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 @@ -725,6 +725,18 @@ protected void handleCookies(Method m, }); }); } + + protected Message createMessage(Object body, + OperationResourceInfo ori, + MultivaluedMap headers, + URI currentURI, + Exchange exchange, + Map invocationContext, + boolean isProxy) { + return createMessage(body, ori.getHttpMethod(), headers, currentURI, + exchange, invocationContext, isProxy); + } + //CHECKSTYLE:OFF protected Object doChainedInvocation(URI uri, MultivaluedMap headers, @@ -743,8 +755,7 @@ protected Object doChainedInvocation(URI uri, if (loader != null) { origLoader = ClassLoaderUtils.setThreadContextClassloader(loader); } - Message outMessage = createMessage(body, ori.getHttpMethod(), headers, uri, - exchange, invocationContext, true); + Message outMessage = createMessage(body, ori, headers, uri, exchange, invocationContext, true); if (bodyIndex != -1) { outMessage.put(Type.class, ori.getMethodToInvoke().getGenericParameterTypes()[bodyIndex]); } 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 9038f2bc013..33c57ca48bd 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 @@ -21,12 +21,14 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.net.URI; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutorService; import javax.ws.rs.client.InvocationCallback; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import org.apache.cxf.jaxrs.client.ClientProxyImpl; @@ -36,6 +38,7 @@ import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.jaxrs.utils.InjectionUtils; +import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; import org.apache.cxf.microprofile.client.MPRestClientCallback; import org.apache.cxf.microprofile.client.MicroProfileClientProviderFactory; @@ -139,4 +142,20 @@ protected Class getReturnType(Method method, Message outMessage) { } return returnType; } + + @Override + protected Message createMessage(Object body, + OperationResourceInfo ori, + MultivaluedMap headers, + URI currentURI, + Exchange exchange, + Map invocationContext, + boolean proxy) { + Method m = ori.getMethodToInvoke(); + Map filterProps = new HashMap<>(); + filterProps.put("org.eclipse.microprofile.rest.client.invokedMethod", m); + Message msg = super.createMessage(body, ori, headers, currentURI, exchange, invocationContext, proxy); + msg.getExchange().put("jaxrs.filter.properties", filterProps); + return msg; + } } diff --git a/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java index 5aa7c619880..5274acd92e2 100644 --- a/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java +++ b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/CxfTypeSafeClientBuilderTest.java @@ -18,8 +18,10 @@ */ package org.apache.cxf.microprofile.client; +import java.net.URI; import java.net.URL; +import javax.ws.rs.PathParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -27,6 +29,7 @@ import org.apache.cxf.microprofile.client.mock.ExceptionMappingClient; import org.apache.cxf.microprofile.client.mock.HighPriorityClientReqFilter; import org.apache.cxf.microprofile.client.mock.HighPriorityMBW; +import org.apache.cxf.microprofile.client.mock.InvokedMethodClientRequestFilter; import org.apache.cxf.microprofile.client.mock.LowPriorityClientReqFilter; import org.apache.cxf.microprofile.client.mock.MyClient; import org.apache.cxf.microprofile.client.mock.NoSuchEntityException; @@ -131,6 +134,23 @@ public void testDefaultResponseExceptionMapper() throws Exception { fail(r, "Did not throw expected mapped exception: WebApplicationException"); } + @Test + public void testClientRequestFilterCanAccessInvokedMethod() throws Exception { + InterfaceWithoutProvidersDefined client = RestClientBuilder.newBuilder() + .register(InvokedMethodClientRequestFilter.class) + .baseUri(new URI("http://localhost:8080/neverUsed")) + .build(InterfaceWithoutProvidersDefined.class); + + Response response = client.executePut("foo", "bar"); + assertEquals(200, response.getStatus()); + assertEquals(Response.class.getName(), response.getHeaderString("ReturnType")); + assertEquals("PUT", response.getHeaderString("PUT")); + assertEquals("/{id}", response.getHeaderString("Path")); + assertEquals(String.class.getName(), response.getHeaderString("Parm1")); + assertEquals(PathParam.class.getName(), response.getHeaderString("Parm1Annotation")); + assertEquals(String.class.getName(), response.getHeaderString("Parm2")); + } + private void fail(Response r, String failureMessage) { System.out.println(r.getStatus()); fail(failureMessage); diff --git a/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/mock/InvokedMethodClientRequestFilter.java b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/mock/InvokedMethodClientRequestFilter.java new file mode 100644 index 00000000000..21abc70d880 --- /dev/null +++ b/rt/rs/microprofile-client/src/test/java/org/apache/cxf/microprofile/client/mock/InvokedMethodClientRequestFilter.java @@ -0,0 +1,53 @@ +/** + * 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.microprofile.client.mock; + +import java.io.IOException; +import java.lang.reflect.Method; + +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.core.Response; + +public class InvokedMethodClientRequestFilter implements ClientRequestFilter { + + @Override + public void filter(ClientRequestContext ctx) throws IOException { + try { + Method m = (Method) ctx.getProperty("org.eclipse.microprofile.rest.client.invokedMethod"); + + Path path = m.getAnnotation(Path.class); + ctx.abortWith(Response.ok("OK") + .header("ReturnType", m.getReturnType().getName()) + .header("PUT", m.getAnnotation(PUT.class) == null ? "null" : "PUT") + .header("Path", path == null ? "null" : path.value()) + .header("Parm1", m.getParameters()[0].getType().getName()) + .header("Parm1Annotation", + m.getParameters()[0].getAnnotations()[0].annotationType().getName()) + .header("Parm2", m.getParameters()[1].getType().getName()) + .build()); + } catch (Throwable t) { + t.printStackTrace(); + ctx.abortWith(Response.serverError().build()); + } + } + +}