From 8b6a2629f84333e657a49476a53d52de51beef07 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Fri, 30 Jan 2015 10:19:29 -0700 Subject: [PATCH] 453834 - CDI Support for WebSocket --- jetty-cdi/pom.xml | 29 +++ jetty-cdi/src/main/config/modules/cdi.mod | 4 +- .../jetty/cdi/JettyWeldInitializer.java | 72 ++++++ .../jetty/cdi/WeldDeploymentBinding.java | 36 +-- .../cdi/embedded/EmbeddedCdiHandler.java | 132 +++++++++++ .../jetty/cdi/weld/WebSocketBoundRequest.java | 40 ++++ .../cdi/weld/WeldConversationContext.java | 41 ++++ .../jetty/cdi/weld/WeldRequestContext.java | 41 ++++ .../jetty/cdi/weld/WeldScopeInitializer.java | 77 +++++++ .../jetty/cdi/weld/WeldSessionContext.java | 44 ++++ .../jetty/cdi/EventDebugExtension.java | 72 ++++++ .../eclipse/jetty/cdi/weld/CheckSocket.java | 99 ++++++++ .../cdi/weld/WeldScopeInitializerTest.java | 216 ++++++++++++++++++ .../jetty/cdi/weld/basicapp/EchoSocket.java | 57 +++++ .../jetty/cdi/weld/cdiapp/CdiInfoSocket.java | 91 ++++++++ .../eclipse/jetty/cdi/weld/cdiapp/Dumper.java | 27 +++ .../cdi/weld/cdiapp/IsoTimeFormatter.java | 39 ++++ .../cdi/weld/cdiapp/LocaleTimeFormatter.java | 38 +++ .../jetty/cdi/weld/cdiapp/NamedLiteral.java | 45 ++++ .../cdi/weld/cdiapp/RequestInfoServlet.java | 67 ++++++ .../cdi/weld/cdiapp/RequestParamsDumper.java | 71 ++++++ .../jetty/cdi/weld/cdiapp/TimeFormatter.java | 26 +++ .../jetty/cdi/weld/cdiapp/TimeServlet.java | 57 +++++ .../jetty/util/log/JettyLogHandler.java | 198 ++++++++++++++++ .../src/test/resources/META-INF/beans.xml | 6 + .../javax.enterprise.inject.spi.Extension | 1 + .../test/resources/jetty-logging.properties | 10 + .../src/test/resources/logging.properties | 2 + .../jetty/util/DecoratedObjectFactory.java | 1 + .../common/scopes/WebSocketSessionScope.java | 6 + .../server/WebSocketServerFactory.java | 3 +- 31 files changed, 1617 insertions(+), 31 deletions(-) create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/JettyWeldInitializer.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/embedded/EmbeddedCdiHandler.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WebSocketBoundRequest.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldConversationContext.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldRequestContext.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializer.java create mode 100644 jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldSessionContext.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/EventDebugExtension.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/CheckSocket.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializerTest.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/basicapp/EchoSocket.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/CdiInfoSocket.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/Dumper.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/IsoTimeFormatter.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/LocaleTimeFormatter.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/NamedLiteral.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestInfoServlet.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestParamsDumper.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeFormatter.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeServlet.java create mode 100644 jetty-cdi/src/test/java/org/eclipse/jetty/util/log/JettyLogHandler.java create mode 100644 jetty-cdi/src/test/resources/META-INF/beans.xml create mode 100644 jetty-cdi/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension create mode 100644 jetty-cdi/src/test/resources/jetty-logging.properties create mode 100644 jetty-cdi/src/test/resources/logging.properties diff --git a/jetty-cdi/pom.xml b/jetty-cdi/pom.xml index a24d75fdccd..154cf43322b 100644 --- a/jetty-cdi/pom.xml +++ b/jetty-cdi/pom.xml @@ -11,6 +11,7 @@ jar ${project.groupId}.${project.artifactId} + 2.2.9.Final @@ -45,5 +46,33 @@ jetty-deploy ${project.version} + + org.eclipse.jetty.websocket + websocket-server + ${project.version} + + + org.jboss.weld.servlet + weld-servlet + ${weld.version} + + + + org.eclipse.jetty.websocket + javax-websocket-server-impl + ${project.version} + test + + + org.eclipse.jetty + apache-jsp + ${project.version} + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + diff --git a/jetty-cdi/src/main/config/modules/cdi.mod b/jetty-cdi/src/main/config/modules/cdi.mod index cde3090e0cd..37bca3c5508 100644 --- a/jetty-cdi/src/main/config/modules/cdi.mod +++ b/jetty-cdi/src/main/config/modules/cdi.mod @@ -11,10 +11,10 @@ jsp [files] lib/weld/ -maven://org.jboss.weld.servlet/weld-servlet/2.2.5.Final|lib/weld/weld-servlet-2.2.5.Final.jar +maven://org.jboss.weld.servlet/weld-servlet/2.2.9.Final|lib/weld/weld-servlet-2.2.9.Final.jar [lib] -lib/weld/weld-servlet-2.2.5.Final.jar +lib/weld/weld-servlet-2.2.9.Final.jar lib/jetty-cdi-${jetty.version}.jar [xml] diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/JettyWeldInitializer.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/JettyWeldInitializer.java new file mode 100644 index 00000000000..3aea5bf8e6f --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/JettyWeldInitializer.java @@ -0,0 +1,72 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi; + +import javax.naming.NamingException; +import javax.naming.Reference; + +import org.eclipse.jetty.plus.jndi.Resource; +import org.eclipse.jetty.server.handler.ContextHandler; +import org.eclipse.jetty.webapp.WebAppContext; + +/** + * Utility class suitable for initializing CDI/Weld on Embedded Jetty + */ +public class JettyWeldInitializer +{ + /** + * Initialize WebAppContext to support CDI/Weld. + *

+ * Initializes Context, then sets up WebAppContext system and server classes to allow Weld to operate from Server + * level. + *

+ * Includes {@link #initContext(ContextHandler)} behavior as well. + */ + public static void initWebApp(WebAppContext webapp) throws NamingException + { + initContext(webapp); + + // webapp cannot change / replace weld classes + webapp.addSystemClass("org.jboss.weld."); + webapp.addSystemClass("org.jboss.classfilewriter."); + webapp.addSystemClass("org.jboss.logging."); + webapp.addSystemClass("com.google.common."); + + // don't hide weld classes from webapps (allow webapp to use ones from system classloader) + webapp.addServerClass("-org.jboss.weld."); + webapp.addServerClass("-org.jboss.classfilewriter."); + webapp.addServerClass("-org.jboss.logging."); + webapp.addServerClass("-com.google.common."); + } + + public static void initContext(ContextHandler handler) throws NamingException + { + // Add context specific weld container reference. + // See https://issues.jboss.org/browse/WELD-1710 + // and https://github.com/weld/core/blob/2.2.5.Final/environments/servlet/core/src/main/java/org/jboss/weld/environment/servlet/WeldServletLifecycle.java#L244-L253 + handler.setInitParameter("org.jboss.weld.environment.container.class","org.jboss.weld.environment.jetty.JettyContainer"); + + // Setup Weld BeanManager reference + Reference ref = new Reference("javax.enterprise.inject.spi.BeanManager","org.jboss.weld.resources.ManagerObjectFactory",null); + new Resource(handler,"BeanManager",ref); + + // Add just in time listeners for WebSocketServerFactory + handler.setAttribute("org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope.Listener","org.eclipse.jetty.cdi.weld.WeldScopeInitializer"); + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/WeldDeploymentBinding.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/WeldDeploymentBinding.java index 0ce37ec532e..a2388c080fb 100644 --- a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/WeldDeploymentBinding.java +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/WeldDeploymentBinding.java @@ -18,12 +18,9 @@ package org.eclipse.jetty.cdi; -import javax.naming.Reference; - import org.eclipse.jetty.deploy.App; import org.eclipse.jetty.deploy.AppLifeCycle; import org.eclipse.jetty.deploy.graph.Node; -import org.eclipse.jetty.plus.jndi.Resource; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.webapp.WebAppContext; @@ -34,8 +31,7 @@ public class WeldDeploymentBinding implements AppLifeCycle.Binding { public String[] getBindingTargets() { - return new String[] - { "deploying" }; + return new String[] { "deploying" }; } public void processBinding(Node node, App app) throws Exception @@ -48,30 +44,14 @@ public class WeldDeploymentBinding implements AppLifeCycle.Binding if (handler instanceof WebAppContext) { + // Do webapp specific init WebAppContext webapp = (WebAppContext)handler; - - // Add context specific weld container reference. - // See https://issues.jboss.org/browse/WELD-1710 - // and https://github.com/weld/core/blob/2.2.5.Final/environments/servlet/core/src/main/java/org/jboss/weld/environment/servlet/WeldServletLifecycle.java#L244-L253 - webapp.setInitParameter("org.jboss.weld.environment.container.class", - "org.jboss.weld.environment.jetty.JettyContainer"); - - // Setup Weld BeanManager reference - Reference ref = new Reference("javax.enterprise.inject.spi.BeanManager", - "org.jboss.weld.resources.ManagerObjectFactory", null); - new Resource(webapp,"BeanManager",ref); - - // webapp cannot change / replace weld classes - webapp.addSystemClass("org.jboss.weld."); - webapp.addSystemClass("org.jboss.classfilewriter."); - webapp.addSystemClass("org.jboss.logging."); - webapp.addSystemClass("com.google.common."); - - // don't hide weld classes from webapps (allow webapp to use ones from system classloader) - webapp.addServerClass("-org.jboss.weld."); - webapp.addServerClass("-org.jboss.classfilewriter."); - webapp.addServerClass("-org.jboss.logging."); - webapp.addServerClass("-com.google.common."); + JettyWeldInitializer.initWebApp(webapp); + } + else + { + // Do general init + JettyWeldInitializer.initContext(handler); } } } diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/embedded/EmbeddedCdiHandler.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/embedded/EmbeddedCdiHandler.java new file mode 100644 index 00000000000..9133f889317 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/embedded/EmbeddedCdiHandler.java @@ -0,0 +1,132 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.embedded; + +import java.io.IOException; +import java.util.Collections; +import java.util.Set; + +import javax.servlet.ServletContext; + +import org.eclipse.jetty.cdi.JettyWeldInitializer; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.Resource; +import org.jboss.weld.environment.servlet.EnhancedListener; + +/** + * Handy {@link ServletContextHandler} implementation that hooks up + * all of the various CDI related components and listeners from Weld. + */ +public class EmbeddedCdiHandler extends ServletContextHandler +{ + private static final Logger LOG = Log.getLogger(EmbeddedCdiHandler.class); + + private static final String[] REQUIRED_BEANS_XML_PATHS = new String[] { + "/WEB-INF/beans.xml", + "/META-INF/beans.xml", + "/WEB-INF/classes/META-INF/beans.xml" + }; + + public EmbeddedCdiHandler() + { + super(); + } + + public EmbeddedCdiHandler(int options) + { + super(options); + } + + @Override + protected void doStart() throws Exception + { + // Required of CDI + Resource baseResource = getBaseResource(); + if (baseResource == null) + { + throw new NullPointerException("baseResource must be set (to so it can find the beans.xml)"); + } + + boolean foundBeansXml = false; + + // Verify that beans.xml is present, otherwise weld will fail silently. + for(String beansXmlPath: REQUIRED_BEANS_XML_PATHS) { + Resource res = baseResource.addPath(beansXmlPath); + if (res == null) + { + // not found, skip it + continue; + } + + if (res.exists()) + { + foundBeansXml = true; + } + + if (res.isDirectory()) + { + throw new IOException("Directory conflicts with expected file: " + res.getURI().toASCIIString()); + } + } + + if (!foundBeansXml) + { + StringBuilder err = new StringBuilder(); + err.append("Unable to find required beans.xml from the baseResource: "); + err.append(baseResource.getURI().toASCIIString()).append(System.lineSeparator()); + err.append("Searched for: "); + for (String beansXmlPath : REQUIRED_BEANS_XML_PATHS) + { + err.append(System.lineSeparator()); + err.append(" ").append(beansXmlPath); + } + LOG.warn("ERROR: {}",err.toString()); + throw new IOException(err.toString()); + } + + // Initialize Weld + JettyWeldInitializer.initContext(this); + + // Wire up Weld (what's usually done via the ServletContainerInitializer) + ServletContext ctx = getServletContext(); + + // Fake the call to ServletContainerInitializer + ClassLoader orig = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(ctx.getClassLoader()); + + EnhancedListener weldListener = new EnhancedListener(); + Set> classes = Collections.emptySet(); + weldListener.onStartup(classes,ctx); + + // add the rest of the Weld Listeners + ctx.addListener(weldListener); + } + finally + { + Thread.currentThread().setContextClassLoader(orig); + } + + // Let normal ServletContextHandler startup continue its merry way + super.doStart(); + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WebSocketBoundRequest.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WebSocketBoundRequest.java new file mode 100644 index 00000000000..b6e83bf8402 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WebSocketBoundRequest.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import java.util.Map; + +import org.jboss.weld.context.bound.BoundRequest; + +public class WebSocketBoundRequest implements BoundRequest +{ + @Override + public Map getRequestMap() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public Map getSessionMap(boolean create) + { + // TODO Auto-generated method stub + return null; + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldConversationContext.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldConversationContext.java new file mode 100644 index 00000000000..2e6331fa1da --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldConversationContext.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import org.jboss.weld.context.bound.BoundConversationContext; + +public class WeldConversationContext +{ + public static void activate(BoundConversationContext boundConversationContext) + { + // TODO Auto-generated method stub + } + + public static void deactivate() + { + // TODO Auto-generated method stub + + } + + public static void invalidate() + { + // TODO Auto-generated method stub + + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldRequestContext.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldRequestContext.java new file mode 100644 index 00000000000..0c365990763 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldRequestContext.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import org.jboss.weld.context.bound.BoundRequestContext; + +public class WeldRequestContext +{ + public static void activate(BoundRequestContext boundRequestContext) + { + // TODO Auto-generated method stub + } + + public static void deactivate() + { + // TODO Auto-generated method stub + + } + + public static void invalidate() + { + // TODO Auto-generated method stub + + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializer.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializer.java new file mode 100644 index 00000000000..3207a57e47d --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializer.java @@ -0,0 +1,77 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import javax.inject.Inject; +import javax.servlet.ServletContext; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; +import org.jboss.weld.context.bound.BoundConversationContext; +import org.jboss.weld.context.bound.BoundRequestContext; +import org.jboss.weld.manager.BeanManagerImpl; + +/** + * CDI/Weld scopes initialization of WebSocket specific Weld Contexts. + */ +public class WeldScopeInitializer +{ + private static final Logger LOG = Log.getLogger(WeldScopeInitializer.class); + + @Inject + private ServletContext servletContext; + + @Inject + private BoundRequestContext boundRequestContext; + + @Inject + private BoundConversationContext boundConversationContext; + + @Inject + private BeanManagerImpl beanManager; + + private WeldConversationContext conversationContext; + private WeldRequestContext requestContext; + private WeldSessionContext sessionCOntext; + + public void activate(WebSocketContainerScope scope) + { + LOG.info("activate(WebSocketContainerScope:{})",scope); + WeldConversationContext.activate(boundConversationContext); + WeldSessionContext.activate(beanManager); + WeldRequestContext.activate(boundRequestContext); + } + + public void deactivate(WebSocketContainerScope scope) + { + LOG.info("deactivate(WebSocketContainerScope:{})",scope); + WeldConversationContext.deactivate(); + WeldSessionContext.deactivate(); + WeldRequestContext.deactivate(); + } + + public void invalidate(WebSocketContainerScope scope) + { + LOG.info("invalidate(WebSocketContainerScope:{})",scope); + WeldConversationContext.invalidate(); + WeldSessionContext.invalidate(); + WeldRequestContext.invalidate(); + } +} diff --git a/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldSessionContext.java b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldSessionContext.java new file mode 100644 index 00000000000..dee4a891eb6 --- /dev/null +++ b/jetty-cdi/src/main/java/org/eclipse/jetty/cdi/weld/WeldSessionContext.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import org.jboss.weld.manager.BeanManagerImpl; + +public class WeldSessionContext +{ + + public static void activate(BeanManagerImpl beanManager) + { + // TODO Auto-generated method stub + + } + + public static void deactivate() + { + // TODO Auto-generated method stub + + } + + public static void invalidate() + { + // TODO Auto-generated method stub + + } + +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/EventDebugExtension.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/EventDebugExtension.java new file mode 100644 index 00000000000..76ffb2a632b --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/EventDebugExtension.java @@ -0,0 +1,72 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi; + +import java.util.logging.Logger; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.BeforeBeanDiscovery; +import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.ProcessAnnotatedType; +import javax.enterprise.inject.spi.ProcessBean; +import javax.enterprise.inject.spi.ProcessInjectionPoint; +import javax.enterprise.inject.spi.ProcessInjectionTarget; + +import org.jboss.weld.bootstrap.events.ContainerEvent; + +public class EventDebugExtension implements Extension +{ + private static final Logger LOG = Logger.getLogger(EventDebugExtension.class.getName()); + + void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) + { + LOG.info("finished the scanning process"); + } + + void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) + { + LOG.info("beginning the scanning process"); + } + + void containerEvent(@Observes ContainerEvent evt) + { + LOG.info("container event: " + evt); + } + + void processAnnotatedType(@Observes ProcessAnnotatedType pat) + { + LOG.info("scanning type: " + pat.getAnnotatedType().getJavaClass().getName()); + } + + void processBean(@Observes ProcessBean bean) + { + LOG.info("process bean: " + bean.getBean()); + } + + void processInjectionPoint(@Observes ProcessInjectionPoint inj) + { + LOG.info("process injection point: " + inj.getInjectionPoint()); + } + + void processInjectionPoint(@Observes ProcessInjectionTarget inj) + { + LOG.info("process injection target: " + inj.getInjectionTarget()); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/CheckSocket.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/CheckSocket.java new file mode 100644 index 00000000000..52af93ff5c5 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/CheckSocket.java @@ -0,0 +1,99 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.toolchain.test.EventQueue; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.websocket.api.Session; +import org.eclipse.jetty.websocket.api.WebSocketAdapter; +import org.eclipse.jetty.websocket.api.annotations.WebSocket; + +@WebSocket +public class CheckSocket extends WebSocketAdapter +{ + private static final Logger LOG = Log.getLogger(CheckSocket.class); + private CountDownLatch closeLatch = new CountDownLatch(1); + private CountDownLatch openLatch = new CountDownLatch(1); + private EventQueue textMessages = new EventQueue<>(); + + public void awaitClose(int timeout, TimeUnit timeunit) throws InterruptedException + { + assertTrue("Timeout waiting for close",closeLatch.await(timeout,timeunit)); + } + + public void awaitOpen(int timeout, TimeUnit timeunit) throws InterruptedException + { + assertTrue("Timeout waiting for open",openLatch.await(timeout,timeunit)); + } + + public EventQueue getTextMessages() + { + return textMessages; + } + + @Override + public void onWebSocketClose(int statusCode, String reason) + { + LOG.debug("Close: {}, {}",statusCode,reason); + super.onWebSocketClose(statusCode,reason); + closeLatch.countDown(); + } + + @Override + public void onWebSocketConnect(Session sess) + { + LOG.debug("Open: {}",sess); + super.onWebSocketConnect(sess); + openLatch.countDown(); + } + + @Override + public void onWebSocketError(Throwable cause) + { + LOG.warn("WebSocket Error",cause); + super.onWebSocketError(cause); + } + + @Override + public void onWebSocketText(String message) + { + LOG.debug("TEXT: {}",message); + textMessages.add(message); + } + + public void sendText(String msg) throws IOException + { + if (isConnected()) + { + getRemote().sendString(msg); + } + } + + public void close(int statusCode, String reason) + { + getSession().close(statusCode,reason); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializerTest.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializerTest.java new file mode 100644 index 00000000000..4917016f760 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/WeldScopeInitializerTest.java @@ -0,0 +1,216 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import java.io.File; +import java.net.URI; +import java.util.concurrent.TimeUnit; + +import javax.websocket.server.ServerContainer; + +import org.eclipse.jetty.cdi.embedded.EmbeddedCdiHandler; +import org.eclipse.jetty.cdi.weld.basicapp.EchoSocket; +import org.eclipse.jetty.cdi.weld.cdiapp.CdiInfoSocket; +import org.eclipse.jetty.cdi.weld.cdiapp.RequestInfoServlet; +import org.eclipse.jetty.cdi.weld.cdiapp.TimeServlet; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.toolchain.test.MavenTestingUtils; +import org.eclipse.jetty.toolchain.test.SimpleRequest; +import org.eclipse.jetty.util.log.JettyLogHandler; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.websocket.api.StatusCode; +import org.eclipse.jetty.websocket.client.WebSocketClient; +import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class WeldScopeInitializerTest +{ + private static final Logger LOG = Log.getLogger(WeldScopeInitializerTest.class); + private static Server server; + private static URI serverHttpURI; + private static URI serverWebsocketURI; + + @BeforeClass + public static void startServer() throws Exception + { + JettyLogHandler.config(); + + server = new Server(); + ServerConnector connector = new ServerConnector(server); + connector.setPort(0); + server.addConnector(connector); + + EmbeddedCdiHandler context = new EmbeddedCdiHandler(); + + File baseDir = MavenTestingUtils.getTestResourcesDir(); + + context.setBaseResource(Resource.newResource(baseDir)); + context.setContextPath("/"); + server.setHandler(context); + + // Add some servlets + context.addServlet(TimeServlet.class,"/time"); + context.addServlet(RequestInfoServlet.class,"/req-info"); + + // Add some websockets + ServerContainer container = WebSocketServerContainerInitializer.configureContext(context); + container.addEndpoint(EchoSocket.class); + container.addEndpoint(CdiInfoSocket.class); + + server.start(); + + String host = connector.getHost(); + if (host == null) + { + host = "localhost"; + } + int port = connector.getLocalPort(); + serverHttpURI = new URI(String.format("http://%s:%d/",host,port)); + serverWebsocketURI = new URI(String.format("ws://%s:%d/",host,port)); + } + + @AfterClass + public static void stopServer() + { + try + { + server.stop(); + } + catch (Exception e) + { + LOG.warn(e); + } + } + + @Test + public void testWebSocketActivated() throws Exception + { + WebSocketClient client = new WebSocketClient(); + try + { + client.start(); + CheckSocket socket = new CheckSocket(); + client.connect(socket,serverWebsocketURI.resolve("/echo")); + + socket.awaitOpen(2,TimeUnit.SECONDS); + socket.sendText("Hello"); + socket.close(StatusCode.NORMAL,"Test complete"); + socket.awaitClose(2,TimeUnit.SECONDS); + + assertThat("Messages received",socket.getTextMessages().size(),is(1)); + assertThat("Message[0]",socket.getTextMessages().poll(),is("Hello")); + } + finally + { + client.stop(); + } + } + + @Test + public void testWebSocketInfo() throws Exception + { + WebSocketClient client = new WebSocketClient(); + try + { + client.start(); + CheckSocket socket = new CheckSocket(); + client.connect(socket,serverWebsocketURI.resolve("/cdi-info")); + + socket.awaitOpen(2,TimeUnit.SECONDS); + socket.sendText("info"); + socket.close(StatusCode.NORMAL,"Test complete"); + socket.awaitClose(2,TimeUnit.SECONDS); + + assertThat("Messages received",socket.getTextMessages().size(),is(1)); + String response = socket.getTextMessages().poll(); + System.err.println(response); + + assertThat("Message[0]",response, + allOf( + containsString("websocketSession is PRESENT"), + containsString("httpSession is PRESENT"), + containsString("servletContext is PRESENT") + )); + } + finally + { + client.stop(); + } + } + + @Test + public void testWebSocketEcho() throws Exception + { + WebSocketClient client = new WebSocketClient(); + try + { + client.start(); + CheckSocket socket = new CheckSocket(); + client.connect(socket,serverWebsocketURI.resolve("/echo")); + + socket.awaitOpen(2,TimeUnit.SECONDS); + socket.sendText("Hello World"); + socket.close(StatusCode.NORMAL,"Test complete"); + socket.awaitClose(2,TimeUnit.SECONDS); + + assertThat("Messages received",socket.getTextMessages().size(),is(1)); + String response = socket.getTextMessages().poll(); + System.err.println(response); + + assertThat("Message[0]",response,is("Hello World")); + } + finally + { + client.stop(); + } + } + + @Test + public void testRequestParamServletDefault() throws Exception + { + SimpleRequest req = new SimpleRequest(serverHttpURI); + String resp = req.getString("req-info"); + + System.out.println(resp); + + assertThat("Response",resp,containsString("request is PRESENT")); + assertThat("Response",resp,containsString("parameters.size = [0]")); + } + + @Test + public void testRequestParamServletAbc() throws Exception + { + SimpleRequest req = new SimpleRequest(serverHttpURI); + String resp = req.getString("req-info?abc=123"); + + System.out.println(resp); + + assertThat("Response",resp,containsString("request is PRESENT")); + assertThat("Response",resp,containsString("parameters.size = [1]")); + assertThat("Response",resp,containsString(" param[abc] = [123]")); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/basicapp/EchoSocket.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/basicapp/EchoSocket.java new file mode 100644 index 00000000000..693948384e1 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/basicapp/EchoSocket.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.basicapp; + +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +@ServerEndpoint("/echo") +public class EchoSocket +{ + private static final Logger LOG = Log.getLogger(EchoSocket.class); + @SuppressWarnings("unused") + private Session session; + + @OnOpen + public void onOpen(Session session) + { + LOG.debug("onOpen(): {}",session); + this.session = session; + } + + @OnClose + public void onClose(CloseReason close) + { + LOG.debug("onClose(): {}",close); + this.session = null; + } + + @OnMessage + public String onMessage(String msg) + { + return msg; + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/CdiInfoSocket.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/CdiInfoSocket.java new file mode 100644 index 00000000000..a61cd481ca3 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/CdiInfoSocket.java @@ -0,0 +1,91 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.logging.Level; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.websocket.CloseReason; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +@ServerEndpoint("/cdi-info") +public class CdiInfoSocket +{ + private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CdiInfoSocket.class.getName()); + + @RequestScoped + @Inject + private HttpSession httpSession; + + @Inject + private ServletContext servletContext; + + private Session session; + + public CdiInfoSocket() + { + Thread.dumpStack(); + } + + @OnOpen + public void onOpen(Session session) + { + LOG.log(Level.INFO,"onOpen(): {0}",session); + this.session = session; + } + + @OnClose + public void onClose(CloseReason close) + { + LOG.log(Level.INFO,"onClose(): {}",close); + this.session = null; + } + + @OnMessage + public String onMessage(String msg) + { + StringWriter str = new StringWriter(); + PrintWriter out = new PrintWriter(str); + + switch (msg) + { + case "info": + out.printf("websocketSession is %s%n",asPresent(session)); + out.printf("httpSession: %s%n",asPresent(httpSession)); + out.printf("servletContext: %s%n",asPresent(servletContext)); + break; + } + + return str.toString(); + } + + private String asPresent(Object obj) + { + return obj == null ? "NULL" : "PRESENT"; + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/Dumper.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/Dumper.java new file mode 100644 index 00000000000..5f07dc84c7c --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/Dumper.java @@ -0,0 +1,27 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.io.IOException; +import java.io.PrintWriter; + +public interface Dumper +{ + public void dump(PrintWriter out) throws IOException; +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/IsoTimeFormatter.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/IsoTimeFormatter.java new file mode 100644 index 00000000000..dd53d8511e8 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/IsoTimeFormatter.java @@ -0,0 +1,39 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; +import java.util.TimeZone; + +import javax.inject.Named; + +@Named("iso") +public class IsoTimeFormatter implements TimeFormatter +{ + @Override + public String format(Calendar cal) + { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'",Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.format(cal.getTime()); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/LocaleTimeFormatter.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/LocaleTimeFormatter.java new file mode 100644 index 00000000000..3050d49310d --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/LocaleTimeFormatter.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import javax.enterprise.inject.Default; +import javax.inject.Named; + +@Named("locale") +@Default +public class LocaleTimeFormatter implements TimeFormatter +{ + public static final TimeFormatter INSTANCE = new LocaleTimeFormatter(); + + @Override + public String format(Calendar cal) + { + return new SimpleDateFormat().format(cal.getTime()); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/NamedLiteral.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/NamedLiteral.java new file mode 100644 index 00000000000..0c95d97c958 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/NamedLiteral.java @@ -0,0 +1,45 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import javax.enterprise.util.AnnotationLiteral; +import javax.inject.Named; + +@SuppressWarnings("serial") +public class NamedLiteral extends AnnotationLiteral implements Named +{ + private final String value; + + public String value() + { + return value; + } + + public NamedLiteral(String name) + { + if (name == null) + { + this.value = ""; + } + else + { + this.value = name; + } + } +} \ No newline at end of file diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestInfoServlet.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestInfoServlet.java new file mode 100644 index 00000000000..c5a75dfa638 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestInfoServlet.java @@ -0,0 +1,67 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +@WebServlet("/req-info") +public class RequestInfoServlet extends HttpServlet +{ + @Inject + @Any + private Instance dumpers; + + @Inject + @Named("params") + private Dumper defaultDumper; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + resp.setContentType("text/plain"); + PrintWriter out = resp.getWriter(); + + Dumper dumper = defaultDumper; + + String dumperId = req.getParameter("dumperId"); + + if (dumperId != null) + { + Instance inst = dumpers.select(new NamedLiteral(dumperId)); + if (!inst.isAmbiguous() && !inst.isUnsatisfied()) + { + dumper = inst.get(); + } + } + + dumper.dump(out); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestParamsDumper.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestParamsDumper.java new file mode 100644 index 00000000000..386a98d1083 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/RequestParamsDumper.java @@ -0,0 +1,71 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.inject.Named; +import javax.servlet.http.HttpServletRequest; + +@Named("params") +@RequestScoped +public class RequestParamsDumper implements Dumper +{ + @Inject + private HttpServletRequest request; + + @Override + public void dump(PrintWriter out) throws IOException + { + out.printf("request is %s%n",request == null ? "NULL" : "PRESENT"); + + if (request != null) + { + Map params = request.getParameterMap(); + List paramNames = new ArrayList<>(); + paramNames.addAll(params.keySet()); + Collections.sort(paramNames); + + out.printf("parameters.size = [%d]%n",params.size()); + + for (String name : paramNames) + { + out.printf(" param[%s] = [",name); + boolean delim = false; + for (String val : params.get(name)) + { + if (delim) + { + out.print(", "); + } + out.print(val); + delim = true; + } + out.println("]"); + } + } + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeFormatter.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeFormatter.java new file mode 100644 index 00000000000..9611e17113d --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeFormatter.java @@ -0,0 +1,26 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.util.Calendar; + +public interface TimeFormatter +{ + public String format(Calendar cal); +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeServlet.java b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeServlet.java new file mode 100644 index 00000000000..2294185f0a0 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/cdi/weld/cdiapp/TimeServlet.java @@ -0,0 +1,57 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.cdi.weld.cdiapp; + +import java.io.IOException; +import java.util.Calendar; + +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Instance; +import javax.inject.Inject; +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@SuppressWarnings("serial") +@WebServlet(urlPatterns = "/time") +public class TimeServlet extends HttpServlet +{ + @Inject + @Any + Instance formatters; + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + resp.setContentType("text/plain"); + + String timeType = req.getParameter("type"); + TimeFormatter time = LocaleTimeFormatter.INSTANCE; + + Instance inst = formatters.select(new NamedLiteral(timeType)); + if (!inst.isAmbiguous() && !inst.isUnsatisfied()) + { + time = inst.get(); + } + + resp.getWriter().println(time.format(Calendar.getInstance())); + } +} diff --git a/jetty-cdi/src/test/java/org/eclipse/jetty/util/log/JettyLogHandler.java b/jetty-cdi/src/test/java/org/eclipse/jetty/util/log/JettyLogHandler.java new file mode 100644 index 00000000000..fbb221062e3 --- /dev/null +++ b/jetty-cdi/src/test/java/org/eclipse/jetty/util/log/JettyLogHandler.java @@ -0,0 +1,198 @@ +// +// ======================================================================== +// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.util.log; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.text.MessageFormat; +import java.util.ResourceBundle; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.LogRecord; +import java.util.regex.Pattern; + +/** + * Redirect java.util.logging events to Jetty Log + */ +public class JettyLogHandler extends java.util.logging.Handler +{ + public static void config() + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + URL url = cl.getResource("logging.properties"); + if (url != null) + { + System.err.printf("Initializing java.util.logging from %s%n",url); + try (InputStream in = url.openStream()) + { + LogManager.getLogManager().readConfiguration(in); + } + catch (IOException e) + { + e.printStackTrace(System.err); + } + } + else + { + System.err.printf("WARNING: java.util.logging failed to initialize: logging.properties not found%n"); + } + + System.setProperty("org.apache.commons.logging.Log","org.apache.commons.logging.impl.Jdk14Logger"); + } + + public JettyLogHandler() + { + if (Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.DEBUG","false"))) + { + setLevel(Level.FINEST); + } + + if (Boolean.parseBoolean(Log.__props.getProperty("org.eclipse.jetty.util.log.IGNORED","false"))) + { + setLevel(Level.ALL); + } + + System.err.printf("%s Initialized at level [%s]%n",this.getClass().getName(),getLevel().getName()); + } + + private synchronized String formatMessage(LogRecord record) + { + String msg = getMessage(record); + + try + { + Object params[] = record.getParameters(); + if ((params == null) || (params.length == 0)) + { + return msg; + } + + if (Pattern.compile("\\{\\d+\\}").matcher(msg).find()) + { + return MessageFormat.format(msg,params); + } + + return msg; + } + catch (Exception ex) + { + return msg; + } + } + + private String getMessage(LogRecord record) + { + ResourceBundle bundle = record.getResourceBundle(); + if (bundle != null) + { + try + { + return bundle.getString(record.getMessage()); + } + catch (java.util.MissingResourceException ex) + { + } + } + + return record.getMessage(); + } + + @Override + public void publish(LogRecord record) + { + org.eclipse.jetty.util.log.Logger JLOG = getJettyLogger(record.getLoggerName()); + + int level = record.getLevel().intValue(); + if (level >= Level.OFF.intValue()) + { + // nothing to log, skip it. + return; + } + + Throwable cause = record.getThrown(); + String msg = formatMessage(record); + + if (level >= Level.WARNING.intValue()) + { + // log at warn + if (cause != null) + { + JLOG.warn(msg,cause); + } + else + { + JLOG.warn(msg); + } + return; + } + + if (level >= Level.INFO.intValue()) + { + // log at info + if (cause != null) + { + JLOG.info(msg,cause); + } + else + { + JLOG.info(msg); + } + return; + } + + if (level >= Level.FINEST.intValue()) + { + // log at debug + if (cause != null) + { + JLOG.debug(msg,cause); + } + else + { + JLOG.debug(msg); + } + return; + } + + if (level >= Level.ALL.intValue()) + { + // only corresponds with ignore (in jetty speak) + JLOG.ignore(cause); + return; + } + } + + private Logger getJettyLogger(String loggerName) + { + return org.eclipse.jetty.util.log.Log.getLogger(loggerName); + } + + @Override + public void flush() + { + // ignore + } + + @Override + public void close() throws SecurityException + { + // ignore + } +} diff --git a/jetty-cdi/src/test/resources/META-INF/beans.xml b/jetty-cdi/src/test/resources/META-INF/beans.xml new file mode 100644 index 00000000000..f158a71b6e5 --- /dev/null +++ b/jetty-cdi/src/test/resources/META-INF/beans.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file diff --git a/jetty-cdi/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/jetty-cdi/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 00000000000..1f8343968ec --- /dev/null +++ b/jetty-cdi/src/test/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +org.eclipse.jetty.cdi.EventDebugExtension \ No newline at end of file diff --git a/jetty-cdi/src/test/resources/jetty-logging.properties b/jetty-cdi/src/test/resources/jetty-logging.properties new file mode 100644 index 00000000000..65289d2cff6 --- /dev/null +++ b/jetty-cdi/src/test/resources/jetty-logging.properties @@ -0,0 +1,10 @@ +org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog +org.jboss.LEVEL=DEBUG +org.eclipse.jetty.LEVEL=INFO + +org.eclipse.jetty.util.DecoratedObjectFactory.LEVEL=DEBUG + +# org.eclipse.jetty.LEVEL=DEBUG +# org.eclipse.jetty.websocket.LEVEL=DEBUG +# org.eclipse.jetty.websocket.client.LEVEL=DEBUG + diff --git a/jetty-cdi/src/test/resources/logging.properties b/jetty-cdi/src/test/resources/logging.properties new file mode 100644 index 00000000000..cfec8c7ab58 --- /dev/null +++ b/jetty-cdi/src/test/resources/logging.properties @@ -0,0 +1,2 @@ +handlers = org.eclipse.jetty.util.log.JettyLogHandler +.level=FINE diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/DecoratedObjectFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/DecoratedObjectFactory.java index 128fc81fadf..9ea81c0d9a1 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/DecoratedObjectFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/DecoratedObjectFactory.java @@ -47,6 +47,7 @@ public class DecoratedObjectFactory implements Iterable public void addDecorator(Decorator decorator) { + LOG.debug("Adding Decorator: {}", decorator); this.decorators.add(decorator); } diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java index 8ddb3875604..e4e678c5c3a 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/WebSocketSessionScope.java @@ -25,7 +25,13 @@ import org.eclipse.jetty.websocket.common.WebSocketSession; */ public interface WebSocketSessionScope { + /** + * Active {@link WebSocketSession} associated with this scope. + */ WebSocketSession getWebSocketSession(); + /** + * The parent {@link WebSocketContainerScope} for this session scope. + */ WebSocketContainerScope getContainerScope(); } diff --git a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java index 018c2079b5f..85aa4d187c2 100644 --- a/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java +++ b/jetty-websocket/websocket-server/src/main/java/org/eclipse/jetty/websocket/server/WebSocketServerFactory.java @@ -393,13 +393,14 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc @Override public void init(ServletContext context) throws ServletException { + // Setup ObjectFactory this.objectFactory = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR); if (this.objectFactory == null) { this.objectFactory = new DecoratedObjectFactory(); } - + // Validate Environment ContextHandler handler = ContextHandler.getContextHandler(context); if (handler == null)