You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jg...@apache.org on 2021/06/03 12:32:21 UTC
[tomee] branch master updated: TOMEE-3752 Fix issue injecting
WebServiceContext into field when usign CDI interceptor
This is an automated email from the ASF dual-hosted git repository.
jgallimore pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/master by this push:
new dfbdedb TOMEE-3752 Fix issue injecting WebServiceContext into field when usign CDI interceptor
new 8abe5fd Merge pull request #799 from jgallimore/TOMEE-3752
dfbdedb is described below
commit dfbdedbcebf71cab294c4b01ee43651de369ced3
Author: Jonathan Gallimore <jo...@jrg.me.uk>
AuthorDate: Wed May 26 11:18:30 2021 +0100
TOMEE-3752 Fix issue injecting WebServiceContext into field when usign CDI interceptor
---
.../tests/jaxws/WebServiceContextTest.java | 137 +++++++++++++++++++++
.../openejb/server/cxf/transport/util/CxfUtil.java | 32 +++++
2 files changed, 169 insertions(+)
diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextTest.java
new file mode 100644
index 0000000..9ba9bd7
--- /dev/null
+++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxws-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxws/WebServiceContextTest.java
@@ -0,0 +1,137 @@
+package org.apache.openejb.arquillian.tests.jaxws;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.descriptor.api.Descriptors;
+import org.jboss.shrinkwrap.descriptor.api.beans11.BeansDescriptor;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Priority;
+import javax.annotation.Resource;
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InterceptorBinding;
+import javax.interceptor.InvocationContext;
+import javax.jws.WebService;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.net.URL;
+import java.util.logging.Logger;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Arquillian.class)
+public class WebServiceContextTest {
+
+ @ArquillianResource
+ private URL url;
+
+ @Deployment(testable = false)
+ public static WebArchive createDeployment() {
+ final String beansXml = Descriptors.create(BeansDescriptor.class)
+ .getOrCreateInterceptors()
+ .clazz(LogInterceptor.class.getName())
+ .up().exportAsString();
+
+ return ShrinkWrap.create(WebArchive.class, "ROOT.war")
+ .addClasses(Echo.class, EchoWS.class, SimpleRequestContext.class, Log.class, LogInterceptor.class)
+ .addAsWebInfResource(new StringAsset(beansXml), "beans.xml");
+ }
+
+ @Test
+ public void invoke() throws Exception {
+ final Service service = Service.create(new URL(url.toExternalForm() + "/EchoWSService?wsdl"), new QName("http://jaxws.tests.arquillian.openejb.apache.org/", "EchoWSService"));
+ final Echo echo = service.getPort(Echo.class);
+ assertEquals("foo", echo.echo("foo"));
+ final String remote = echo.remote();
+ System.out.println(remote);
+ assertEquals("127.0.0.1", remote);
+ }
+
+ @WebService(portName = "EchoWSPort")
+ public static interface Echo {
+ public String echo(final String input);
+ public String remote();
+ }
+
+ @WebService
+ public static class EchoWS implements Echo {
+ @Resource
+ private WebServiceContext wsc;
+
+ @Inject
+ private SimpleRequestContext ctx;
+
+ @Override
+ @Log
+ public String remote() {
+ final HttpServletRequest request = (HttpServletRequest) wsc.getMessageContext().get(MessageContext.SERVLET_REQUEST);
+ return request.getRemoteAddr();
+ }
+
+ @Override
+ @Log
+ public String echo(String input) {
+ return input;
+ }
+ }
+
+ @RequestScoped
+ public static class SimpleRequestContext {
+ private String status;
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+ }
+
+ @InterceptorBinding
+ @Priority(4020)
+ @Target({TYPE, METHOD})
+ @Retention(RUNTIME)
+ public @interface Log {
+ }
+
+ @Interceptor
+ @Log
+ public static class LogInterceptor {
+
+ private static final Logger LOGGER = Logger.getLogger(LogInterceptor.class.getName());
+
+ @AroundInvoke
+ protected Object businessMethodInterceptor(final InvocationContext ic) throws Throwable {
+ final Object result;
+ try {
+ LOGGER.info("Entering " + ic.getMethod().toString());
+ result = ic.proceed();
+ } catch (Throwable t) {
+ throw t;
+ } finally {
+ LOGGER.info("Exiting " + ic.getMethod().toString());
+ }
+
+ return result;
+ }
+ }
+
+}
diff --git a/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java b/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java
index 24ee6d4..3d58bb0 100644
--- a/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java
+++ b/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java
@@ -49,8 +49,13 @@ import org.apache.openejb.server.cxf.transport.OpenEJBHttpDestinationFactory;
import org.apache.openejb.server.cxf.transport.event.BusCreated;
import org.apache.openejb.util.PropertiesHelper;
import org.apache.openejb.util.reflection.Reflections;
+import org.apache.webbeans.intercept.DefaultInterceptorHandler;
+import org.apache.webbeans.proxy.InterceptorHandler;
+import org.apache.webbeans.proxy.OwbInterceptorProxy;
+import org.apache.webbeans.util.ExceptionUtil;
import javax.management.MBeanServer;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -62,6 +67,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
+import static org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory.FIELD_INTERCEPTOR_HANDLER;
+
public final class CxfUtil {
public static final String ENDPOINT_PROPERTIES = "properties";
public static final String FEATURES = "features";
@@ -129,8 +136,33 @@ public final class CxfUtil {
@Override
public Object getRealObject(Object o) {
+ // special case for OWB proxies - ie, a webservice endpoint with a CDI interceptor
+ // we'll want to unwrap this and set the field on the proxied instance, rather than set the field
+ // straight on the proxy
+ if (o instanceof OwbInterceptorProxy) {
+ return getProxiedInstance(o);
+ }
+
return o;
}
+
+ private Object getProxiedInstance(Object o) {
+ try {
+ final Field field = o.getClass().getDeclaredField(FIELD_INTERCEPTOR_HANDLER);
+ field.setAccessible(true);
+
+ final Object fieldValue = field.get(o);
+
+ if (fieldValue instanceof DefaultInterceptorHandler) {
+ final DefaultInterceptorHandler handler = (DefaultInterceptorHandler) fieldValue;
+ return handler.getTarget();
+ } else {
+ throw new IllegalStateException("Expected OwbInterceptorProxy handler to be an instance of Default Interceptor Handler.");
+ }
+ } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
});
SystemInstance.get().addObserver(new LifecycleManager());