Repository: tomee Updated Branches: refs/heads/develop 2d4b68005 -> de9cd659e
supporting all dispatching types for cxf filter Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/ece75c8c Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/ece75c8c Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/ece75c8c Branch: refs/heads/develop Commit: ece75c8c2f4d790bbdf382003f14bffb8634bfe2 Parents: 2d4b680 Author: Romain Manni-Bucau <[email protected]> Authored: Tue Feb 10 12:14:06 2015 +0100 Committer: Romain Manni-Bucau <[email protected]> Committed: Tue Feb 10 12:17:42 2015 +0100 ---------------------------------------------------------------------- .../tests/jaxrs/suspended/Endpoint.java | 78 ++++++++++++++++++ .../tests/jaxrs/suspended/SuspendedTest.java | 66 +++++++++++++++ .../openejb/server/cxf/rs/SuspendedTest.java | 87 ++++++++++++++++++++ .../openejb/server/httpd/HttpRequestImpl.java | 6 +- .../server/httpd/OpenEJBAsyncContext.java | 34 +++++++- .../server/httpd/OpenEJBHttpRegistry.java | 2 +- .../tomee/webservices/TomcatRsRegistry.java | 4 + 7 files changed, 272 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/Endpoint.java ---------------------------------------------------------------------- diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/Endpoint.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/Endpoint.java new file mode 100644 index 0000000..46a2284 --- /dev/null +++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/Endpoint.java @@ -0,0 +1,78 @@ +/* + * 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.openejb.arquillian.tests.jaxrs.suspended; + +import javax.annotation.PreDestroy; +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; + +@Path("touch") +@ApplicationScoped +public class Endpoint { + private volatile AsyncResponse current; + + private volatile Thread thread; + + @GET + public void async(@Suspended final AsyncResponse response) { + if (current == null) { + current = response; + } else { + throw new IllegalStateException("we shouldnt go here back"); + } + } + + @GET + @Path("check") + public boolean set() { + return current != null; + } + + @POST + @Path("answer") + public void async(final String response) { + thread = new RunThread(response, current); + thread.setDaemon(true); + thread.start(); + } + + @PreDestroy + public void end() { + if (thread != null && thread.isAlive()) { + thread.interrupt(); + } + } + + public static class RunThread extends Thread { + private final String content; + private final AsyncResponse response; + + public RunThread(final String response, final AsyncResponse current) { + this.response = current; + this.content = response; + } + + @Override + public void run() { + response.resume(content); + } + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/SuspendedTest.java ---------------------------------------------------------------------- diff --git a/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/SuspendedTest.java b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/SuspendedTest.java new file mode 100644 index 0000000..61554ac --- /dev/null +++ b/arquillian/arquillian-tomee-tests/arquillian-tomee-jaxrs-tests/src/test/java/org/apache/openejb/arquillian/tests/jaxrs/suspended/SuspendedTest.java @@ -0,0 +1,66 @@ +/* + * 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.openejb.arquillian.tests.jaxrs.suspended; + +import org.apache.cxf.jaxrs.client.WebClient; +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.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; +import javax.ws.rs.core.Response; + +import static java.lang.Thread.sleep; +import static org.junit.Assert.assertEquals; + +@RunWith(Arquillian.class) +public class SuspendedTest { + @Deployment + public static Archive<?> war() { + return ShrinkWrap.create(WebArchive.class, "suspended.war").addClasses(Endpoint.class, Endpoint.RunThread.class); + } + + @ArquillianResource + private URL url; + + @Test + public void run() throws InterruptedException { + final AtomicReference<Response> response = new AtomicReference<>(); + final CountDownLatch end = new CountDownLatch(1); + new Thread() { + @Override + public void run() { + response.set(WebClient.create(url.toExternalForm() + "touch").get()); + end.countDown(); + } + }.start(); + final WebClient client = WebClient.create(url.toExternalForm() + "touch"); + while (!client.reset().path("check").get(Boolean.class)) { + sleep(1000); + } + client.reset().path("answer").post("hello"); + end.await(); + assertEquals("hello", response.get().readEntity(String.class)); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SuspendedTest.java ---------------------------------------------------------------------- diff --git a/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SuspendedTest.java b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SuspendedTest.java new file mode 100644 index 0000000..ca5d212 --- /dev/null +++ b/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SuspendedTest.java @@ -0,0 +1,87 @@ +/* + * 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.openejb.server.cxf.rs; + +import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.EnableServices; +import org.apache.openejb.testing.RandomPort; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.URL; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicReference; +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.container.AsyncResponse; +import javax.ws.rs.container.Suspended; +import javax.ws.rs.core.Response; + +import static org.junit.Assert.assertEquals; + +@EnableServices("jaxrs") +@Classes(cdi = true, innerClassesAsBean = true) +@RunWith(ApplicationComposer.class) +public class SuspendedTest { + @Path("touch") + @ApplicationScoped + public static class Endpoint { + private static final CountDownLatch LATCH = new CountDownLatch(1); + private volatile AsyncResponse current; + + @GET + public String async(@Suspended final AsyncResponse response) { + if (current == null) { + current = response; + LATCH.countDown(); + return "ignored"; + } else { + throw new IllegalStateException("we shouldnt go here back since"); + } + } + + @POST + @Path("answer") + public void async(final String response) { + current.resume(response); + } + } + + @RandomPort("http") + private URL url; + + @Test + public void run() throws InterruptedException { + final AtomicReference<Response> response = new AtomicReference<>(); + final CountDownLatch end = new CountDownLatch(1); + new Thread() { + @Override + public void run() { + response.set(WebClient.create(url.toExternalForm() + "openejb/touch").get()); + end.countDown(); + } + }.start(); + Endpoint.LATCH.await(); + WebClient.create(url.toExternalForm() + "openejb/touch").path("answer").post("hello"); + end.await(); + assertEquals("hello", response.get().readEntity(String.class)); + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java index 4cd69ec..9d4c0c4 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java @@ -198,6 +198,10 @@ public class HttpRequestImpl implements HttpRequest { this.socketURI = socketURI; } + public void setUri(final URI uri) { + this.uri = uri; + } + /** * Gets a header based the header name passed in. * @@ -1154,7 +1158,7 @@ public class HttpRequestImpl implements HttpRequest { @Override public boolean isAsyncSupported() { - return false; + return true; } @Override http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java index eb6d660..06c85e2 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBAsyncContext.java @@ -28,6 +28,7 @@ import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; import javax.servlet.ServletContext; import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -226,21 +227,48 @@ public class OpenEJBAsyncContext implements AsyncContext { try { final String contextPath = this.context.getContextRoot().startsWith("/") ? this.context.getContextRoot() : ('/' + this.context.getContextRoot()); final HttpRequestImpl req = new HttpRequestImpl(new URI(request.getRequestURI())) { + private String thisPath = path; + private String thisContextPath = contextPath; + @Override public String getContextPath() { - return contextPath; + return thisContextPath; } @Override public String getServletPath() { - return path; + return thisPath; + } + + @Override + public void initServletPath(final String servlet) { + thisPath = servlet; } @Override - public String getRequestURI() { + public void initPathFromContext(final String context) { + super.initPathFromContext(context); + thisContextPath = super.getContextPath(); + } + + @Override + public String getRequestURI() { // not thisContextPath + thisPath since it would break JAXRS return contextPath + path; } + + @Override + public ServletInputStream getInputStream() throws IOException { + return request.getInputStream(); + } + + @Override + public String getMethod() { + return request.getMethod(); + } }; + if (HttpRequestImpl.class.isInstance(request)) { // needed for some advanced cases like async + req.setUri(HttpRequestImpl.class.cast(request).getURI()); + } registry.onMessage(req, HttpResponse.class.isInstance(response) ? HttpResponse.class.cast(response) : new ServletResponseAdapter(HttpServletResponse.class.cast(response))); complete(); } catch (final Exception e) { http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java ---------------------------------------------------------------------- diff --git a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java index 8030f02..1903e45 100644 --- a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java +++ b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/OpenEJBHttpRegistry.java @@ -110,7 +110,7 @@ public class OpenEJBHttpRegistry { try { if (request instanceof HttpRequestImpl) { final HttpRequestImpl httpRequest = HttpRequestImpl.class.cast(request); - final WebContext web = findWebContext(request.getURI().getPath()); + final WebContext web = findWebContext(request.getURI() == null ? request.getContextPath() : request.getURI().getPath()); if (web != null) { if (web.getClassLoader() != null) { thread.setContextClassLoader(web.getClassLoader()); http://git-wip-us.apache.org/repos/asf/tomee/blob/ece75c8c/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java index 7754adf..2f3d549 100644 --- a/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java +++ b/tomee/tomee-jaxrs/src/main/java/org/apache/tomee/webservices/TomcatRsRegistry.java @@ -42,6 +42,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; import java.util.TreeMap; +import javax.servlet.DispatcherType; public class TomcatRsRegistry implements RsRegistry { private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_STARTUP, TomcatRsRegistry.class); @@ -127,6 +128,9 @@ public class TomcatRsRegistry implements RsRegistry { final FilterMap filterMap = new FilterMap(); filterMap.addURLPattern(urlPattern); + for (final DispatcherType type : DispatcherType.values()) { + filterMap.setDispatcher(type.name()); + } filterMap.setFilterName(filterDef.getFilterName()); context.addFilterMap(filterMap);
