453834 - CDI Support for WebSocket
+ Verifying ServletContextHandler behavior of Decorators + Marking old ServletContextHandler methods as deprecated + Updates to DecoratedObjectFactory + Removing customized weld scopes/context (for now) + Deferring JSR356 ServerContainer endpoint init till Container.doStart() to allow weld to init properly first + Removing JSR356 BasicServerEndpointConfigurator in favor of ContainerDefaultEndpointConfigurator + Only decorating server endpoints if they were created by ContainerDefaultEndpointConfigurator, all others are trusted to be complete and injected already.
This commit is contained in:
parent
e213c4488e
commit
87246263b8
|
@ -16,25 +16,22 @@
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
//
|
//
|
||||||
|
|
||||||
package org.eclipse.jetty.cdi.weld;
|
package org.eclipse.jetty.cdi.producers;
|
||||||
|
|
||||||
import java.util.Map;
|
import javax.enterprise.inject.Produces;
|
||||||
|
import javax.enterprise.inject.spi.InjectionPoint;
|
||||||
|
|
||||||
import org.jboss.weld.context.bound.BoundRequest;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
|
|
||||||
public class WebSocketBoundRequest implements BoundRequest
|
/**
|
||||||
|
* CDI Producer of Jetty Logging instances.
|
||||||
|
*/
|
||||||
|
public class JettyLogFactory
|
||||||
{
|
{
|
||||||
@Override
|
@Produces
|
||||||
public Map<String, Object> getRequestMap()
|
public Logger createLogger(InjectionPoint injectionPoint)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
return Log.getLogger(injectionPoint.getMember().getDeclaringClass());
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> getSessionMap(boolean create)
|
|
||||||
{
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// 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
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// 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
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// 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
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -47,9 +47,9 @@ import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class WeldScopeInitializerTest
|
public class WeldInitializationTest
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(WeldScopeInitializerTest.class);
|
private static final Logger LOG = Log.getLogger(WeldInitializationTest.class);
|
||||||
private static Server server;
|
private static Server server;
|
||||||
private static URI serverHttpURI;
|
private static URI serverHttpURI;
|
||||||
private static URI serverWebsocketURI;
|
private static URI serverWebsocketURI;
|
|
@ -47,11 +47,6 @@ public class CdiInfoSocket
|
||||||
|
|
||||||
private Session session;
|
private Session session;
|
||||||
|
|
||||||
public CdiInfoSocket()
|
|
||||||
{
|
|
||||||
Thread.dumpStack();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnOpen
|
@OnOpen
|
||||||
public void onOpen(Session session)
|
public void onOpen(Session session)
|
||||||
{
|
{
|
||||||
|
@ -76,8 +71,8 @@ public class CdiInfoSocket
|
||||||
{
|
{
|
||||||
case "info":
|
case "info":
|
||||||
out.printf("websocketSession is %s%n",asPresent(session));
|
out.printf("websocketSession is %s%n",asPresent(session));
|
||||||
out.printf("httpSession: %s%n",asPresent(httpSession));
|
out.printf("httpSession is %s%n",asPresent(httpSession));
|
||||||
out.printf("servletContext: %s%n",asPresent(servletContext));
|
out.printf("servletContext is %s%n",asPresent(servletContext));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
|
|
||||||
public interface ServletContainerInitializerCaller extends LifeCycle {};
|
public interface ServletContainerInitializerCaller extends LifeCycle {};
|
||||||
|
|
||||||
protected final DecoratedObjectFactory _instantiator= new DecoratedObjectFactory();
|
protected final DecoratedObjectFactory _objFactory = new DecoratedObjectFactory();
|
||||||
protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass=org.eclipse.jetty.security.ConstraintSecurityHandler.class;
|
protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass=org.eclipse.jetty.security.ConstraintSecurityHandler.class;
|
||||||
protected SessionHandler _sessionHandler;
|
protected SessionHandler _sessionHandler;
|
||||||
protected SecurityHandler _securityHandler;
|
protected SecurityHandler _securityHandler;
|
||||||
|
@ -252,7 +252,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
@Override
|
@Override
|
||||||
protected void doStart() throws Exception
|
protected void doStart() throws Exception
|
||||||
{
|
{
|
||||||
setAttribute(DecoratedObjectFactory.ATTR, _instantiator);
|
getServletContext().setAttribute(DecoratedObjectFactory.ATTR, _objFactory);
|
||||||
super.doStart();
|
super.doStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
super.doStop();
|
super.doStop();
|
||||||
_instantiator.clear();
|
_objFactory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -331,7 +331,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
{
|
{
|
||||||
for (ListenerHolder holder:_servletHandler.getListeners())
|
for (ListenerHolder holder:_servletHandler.getListeners())
|
||||||
{
|
{
|
||||||
_instantiator.decorate(holder.getListener());
|
_objFactory.decorate(holder.getListener());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -648,16 +648,27 @@ public class ServletContextHandler extends ContextHandler
|
||||||
relinkHandlers();
|
relinkHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* The DecoratedObjectFactory for use by IoC containers (weld / spring / etc)
|
||||||
|
*
|
||||||
|
* @return The DecoratedObjectFactory
|
||||||
|
*/
|
||||||
|
public DecoratedObjectFactory getObjectFactory()
|
||||||
|
{
|
||||||
|
return _objFactory;
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @return The decorator list used to resource inject new Filters, Servlets and EventListeners
|
* @return The decorator list used to resource inject new Filters, Servlets and EventListeners
|
||||||
* @deprecated use getAttribute("org.eclipse.jetty.util.DecoratedObjectFactory") instead
|
* @deprecated use the {@link DecoratedObjectFactory} from getAttribute("org.eclipse.jetty.util.DecoratedObjectFactory") or {@link #getObjectFactory()} instead
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public List<Decorator> getDecorators()
|
public List<Decorator> getDecorators()
|
||||||
{
|
{
|
||||||
List<Decorator> ret = new ArrayList<ServletContextHandler.Decorator>();
|
List<Decorator> ret = new ArrayList<ServletContextHandler.Decorator>();
|
||||||
for (org.eclipse.jetty.util.Decorator decorator : _instantiator)
|
for (org.eclipse.jetty.util.Decorator decorator : _objFactory)
|
||||||
{
|
{
|
||||||
ret.add(new LegacyDecorator(decorator));
|
ret.add(new LegacyDecorator(decorator));
|
||||||
}
|
}
|
||||||
|
@ -667,31 +678,35 @@ public class ServletContextHandler extends ContextHandler
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param decorators The list of {@link Decorator}s
|
* @param decorators The list of {@link Decorator}s
|
||||||
|
* @deprecated use the {@link DecoratedObjectFactory} from getAttribute("org.eclipse.jetty.util.DecoratedObjectFactory") or {@link #getObjectFactory()} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setDecorators(List<Decorator> decorators)
|
public void setDecorators(List<Decorator> decorators)
|
||||||
{
|
{
|
||||||
_instantiator.setDecorators(decorators);
|
_objFactory.setDecorators(decorators);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
/**
|
/**
|
||||||
* @param decorator The decorator to add
|
* @param decorator The decorator to add
|
||||||
|
* @deprecated use the {@link DecoratedObjectFactory} from getAttribute("org.eclipse.jetty.util.DecoratedObjectFactory") or {@link #getObjectFactory()} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void addDecorator(Decorator decorator)
|
public void addDecorator(Decorator decorator)
|
||||||
{
|
{
|
||||||
_instantiator.addDecorator(decorator);
|
_objFactory.addDecorator(decorator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
void destroyServlet(Servlet servlet)
|
void destroyServlet(Servlet servlet)
|
||||||
{
|
{
|
||||||
_instantiator.destroy(servlet);
|
_objFactory.destroy(servlet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
void destroyFilter(Filter filter)
|
void destroyFilter(Filter filter)
|
||||||
{
|
{
|
||||||
_instantiator.destroy(filter);
|
_objFactory.destroy(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------ */
|
/* ------------------------------------------------------------ */
|
||||||
|
@ -1244,7 +1259,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
T f = createInstance(c);
|
T f = createInstance(c);
|
||||||
f = _instantiator.decorate(f);
|
f = _objFactory.decorate(f);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -1260,7 +1275,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
T s = createInstance(c);
|
T s = createInstance(c);
|
||||||
s = _instantiator.decorate(s);
|
s = _objFactory.decorate(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -1403,7 +1418,7 @@ public class ServletContextHandler extends ContextHandler
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
T l = createInstance(clazz);
|
T l = createInstance(clazz);
|
||||||
l = _instantiator.decorate(l);
|
l = _objFactory.decorate(l);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
@ -18,15 +18,12 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.servlet;
|
package org.eclipse.jetty.servlet;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.*;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
@ -52,6 +49,8 @@ import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||||
import org.eclipse.jetty.server.session.SessionHandler;
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
|
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||||
|
import org.eclipse.jetty.util.Decorator;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
@ -362,6 +361,59 @@ public class ServletContextHandlerTest
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test behavior of legacy {@link ServletContextHandler.Decorator}, with
|
||||||
|
* new DecoratedObjectFactory class
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Test
|
||||||
|
public void testLegacyDecorator() throws Exception
|
||||||
|
{
|
||||||
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
|
context.addDecorator(new DummyLegacyDecorator());
|
||||||
|
_server.setHandler(context);
|
||||||
|
|
||||||
|
context.addServlet(DecoratedObjectFactoryServlet.class, "/objfactory/*");
|
||||||
|
_server.start();
|
||||||
|
|
||||||
|
String response= _connector.getResponses("GET /objfactory/ HTTP/1.0\r\n\r\n");
|
||||||
|
assertThat("Response status code", response, containsString("200 OK"));
|
||||||
|
|
||||||
|
String expected = String.format("Attribute[%s] = %s", DecoratedObjectFactory.ATTR, DecoratedObjectFactory.class.getName());
|
||||||
|
assertThat("Has context attribute", response, containsString(expected));
|
||||||
|
|
||||||
|
assertThat("Decorators size", response, containsString("Decorators.size = [1]"));
|
||||||
|
|
||||||
|
expected = String.format("decorator[] = %s", DummyLegacyDecorator.class.getName());
|
||||||
|
assertThat("Specific Legacy Decorator", response, containsString(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test behavior of new {@link org.eclipse.jetty.util.Decorator}, with
|
||||||
|
* new DecoratedObjectFactory class
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testUtilDecorator() throws Exception
|
||||||
|
{
|
||||||
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
|
context.getObjectFactory().addDecorator(new DummyUtilDecorator());
|
||||||
|
_server.setHandler(context);
|
||||||
|
|
||||||
|
context.addServlet(DecoratedObjectFactoryServlet.class, "/objfactory/*");
|
||||||
|
_server.start();
|
||||||
|
|
||||||
|
String response= _connector.getResponses("GET /objfactory/ HTTP/1.0\r\n\r\n");
|
||||||
|
assertThat("Response status code", response, containsString("200 OK"));
|
||||||
|
|
||||||
|
String expected = String.format("Attribute[%s] = %s", DecoratedObjectFactory.ATTR, DecoratedObjectFactory.class.getName());
|
||||||
|
assertThat("Has context attribute", response, containsString(expected));
|
||||||
|
|
||||||
|
assertThat("Decorators size", response, containsString("Decorators.size = [1]"));
|
||||||
|
|
||||||
|
expected = String.format("decorator[] = %s", DummyUtilDecorator.class.getName());
|
||||||
|
assertThat("Specific Legacy Decorator", response, containsString(expected));
|
||||||
|
}
|
||||||
|
|
||||||
private int assertResponseContains(String expected, String response)
|
private int assertResponseContains(String expected, String response)
|
||||||
{
|
{
|
||||||
int idx = response.indexOf(expected);
|
int idx = response.indexOf(expected);
|
||||||
|
@ -392,6 +444,66 @@ public class ServletContextHandlerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class DummyUtilDecorator implements org.eclipse.jetty.util.Decorator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public <T> T decorate(T o)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(Object o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DummyLegacyDecorator implements org.eclipse.jetty.servlet.ServletContextHandler.Decorator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public <T> T decorate(T o)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(Object o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DecoratedObjectFactoryServlet extends HttpServlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
resp.setContentType("text/plain");
|
||||||
|
resp.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
|
||||||
|
Object obj = req.getServletContext().getAttribute(DecoratedObjectFactory.ATTR);
|
||||||
|
out.printf("Attribute[%s] = %s%n",DecoratedObjectFactory.ATTR,obj.getClass().getName());
|
||||||
|
|
||||||
|
if (obj instanceof DecoratedObjectFactory)
|
||||||
|
{
|
||||||
|
out.printf("Object is a DecoratedObjectFactory%n");
|
||||||
|
DecoratedObjectFactory objFactory = (DecoratedObjectFactory)obj;
|
||||||
|
List<Decorator> decorators = objFactory.getDecorators();
|
||||||
|
out.printf("Decorators.size = [%d]%n",decorators.size());
|
||||||
|
for (Decorator decorator : decorators)
|
||||||
|
{
|
||||||
|
out.printf(" decorator[] = %s%n",decorator.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.printf("Object is NOT a DecoratedObjectFactory%n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TestServlet extends HttpServlet
|
public static class TestServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class DecoratedObjectFactory implements Iterable<Decorator>
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
LOG.debug("Creating Instance: " + clazz,new Throwable("Creation Stack"));
|
LOG.debug("Creating Instance: " + clazz);
|
||||||
}
|
}
|
||||||
T o = clazz.newInstance();
|
T o = clazz.newInstance();
|
||||||
return decorate(o);
|
return decorate(o);
|
||||||
|
@ -106,4 +106,14 @@ public class DecoratedObjectFactory implements Iterable<Decorator>
|
||||||
this.decorators.addAll(decorators);
|
this.decorators.addAll(decorators);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
str.append(this.getClass().getName()).append("[decorators=");
|
||||||
|
str.append(Integer.toString(decorators.size()));
|
||||||
|
str.append("]");
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(ClientContainer.class);
|
private static final Logger LOG = Log.getLogger(ClientContainer.class);
|
||||||
|
|
||||||
|
/** The delegated Container Scope */
|
||||||
|
private final WebSocketContainerScope scopeDelegate;
|
||||||
/** Tracking all primitive decoders for the container */
|
/** Tracking all primitive decoders for the container */
|
||||||
private final DecoderFactory decoderFactory;
|
private final DecoderFactory decoderFactory;
|
||||||
/** Tracking all primitive encoders for the container */
|
/** Tracking all primitive encoders for the container */
|
||||||
|
@ -89,8 +91,6 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
/** The jetty websocket client in use for this container */
|
/** The jetty websocket client in use for this container */
|
||||||
private WebSocketClient client;
|
private WebSocketClient client;
|
||||||
|
|
||||||
protected DecoratedObjectFactory objectFactory;
|
|
||||||
|
|
||||||
public ClientContainer()
|
public ClientContainer()
|
||||||
{
|
{
|
||||||
// This constructor is used with Standalone JSR Client usage.
|
// This constructor is used with Standalone JSR Client usage.
|
||||||
|
@ -102,6 +102,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
{
|
{
|
||||||
boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
boolean trustAll = Boolean.getBoolean("org.eclipse.jetty.websocket.jsr356.ssl-trust-all");
|
||||||
|
|
||||||
|
this.scopeDelegate = scope;
|
||||||
client = new WebSocketClient(scope, new SslContextFactory(trustAll));
|
client = new WebSocketClient(scope, new SslContextFactory(trustAll));
|
||||||
client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy()));
|
client.setEventDriverFactory(new JsrEventDriverFactory(client.getPolicy()));
|
||||||
SessionFactory sessionFactory = new JsrSessionFactory(this,this,client);
|
SessionFactory sessionFactory = new JsrSessionFactory(this,this,client);
|
||||||
|
@ -112,10 +113,6 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE);
|
this.decoderFactory = new DecoderFactory(this,PrimitiveDecoderMetadataSet.INSTANCE);
|
||||||
this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE);
|
this.encoderFactory = new EncoderFactory(this,PrimitiveEncoderMetadataSet.INSTANCE);
|
||||||
|
|
||||||
EmptyClientEndpointConfig empty = new EmptyClientEndpointConfig();
|
|
||||||
this.decoderFactory.init(empty);
|
|
||||||
this.encoderFactory.init(empty);
|
|
||||||
|
|
||||||
ShutdownThread.register(this);
|
ShutdownThread.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,6 +194,17 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
return connect(instance,path);
|
return connect(instance,path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStart() throws Exception
|
||||||
|
{
|
||||||
|
super.doStart();
|
||||||
|
|
||||||
|
// Initialize the default decoder / encoder factories
|
||||||
|
EmptyClientEndpointConfig empty = new EmptyClientEndpointConfig();
|
||||||
|
this.decoderFactory.init(empty);
|
||||||
|
this.encoderFactory.init(empty);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doStop() throws Exception
|
protected void doStop() throws Exception
|
||||||
{
|
{
|
||||||
|
@ -208,7 +216,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
@Override
|
@Override
|
||||||
public ByteBufferPool getBufferPool()
|
public ByteBufferPool getBufferPool()
|
||||||
{
|
{
|
||||||
return client.getBufferPool();
|
return scopeDelegate.getBufferPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
public WebSocketClient getClient()
|
public WebSocketClient getClient()
|
||||||
|
@ -297,7 +305,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
@Override
|
@Override
|
||||||
public Executor getExecutor()
|
public Executor getExecutor()
|
||||||
{
|
{
|
||||||
return client.getExecutor();
|
return scopeDelegate.getExecutor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -317,7 +325,7 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
@Override
|
@Override
|
||||||
public DecoratedObjectFactory getObjectFactory()
|
public DecoratedObjectFactory getObjectFactory()
|
||||||
{
|
{
|
||||||
return client.getObjectFactory();
|
return scopeDelegate.getObjectFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,13 +339,13 @@ public class ClientContainer extends ContainerLifeCycle implements WebSocketCont
|
||||||
@Override
|
@Override
|
||||||
public WebSocketPolicy getPolicy()
|
public WebSocketPolicy getPolicy()
|
||||||
{
|
{
|
||||||
return client.getPolicy();
|
return scopeDelegate.getPolicy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SslContextFactory getSslContextFactory()
|
public SslContextFactory getSslContextFactory()
|
||||||
{
|
{
|
||||||
return client.getSslContextFactory();
|
return scopeDelegate.getSslContextFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
private EndpointInstance newClientEndpointInstance(Class<?> endpointClass, ClientEndpointConfig config)
|
private EndpointInstance newClientEndpointInstance(Class<?> endpointClass, ClientEndpointConfig config)
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import javax.websocket.Decoder;
|
import javax.websocket.Decoder;
|
||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
|
@ -76,7 +75,7 @@ public class DecoderFactory implements Configurable
|
||||||
private static final Logger LOG = Log.getLogger(DecoderFactory.class);
|
private static final Logger LOG = Log.getLogger(DecoderFactory.class);
|
||||||
|
|
||||||
private final DecoderMetadataSet metadatas;
|
private final DecoderMetadataSet metadatas;
|
||||||
private final DecoratedObjectFactory objectFactory;
|
private final WebSocketContainerScope containerScope;
|
||||||
private DecoderFactory parentFactory;
|
private DecoderFactory parentFactory;
|
||||||
private Map<Class<?>, Wrapper> activeWrappers;
|
private Map<Class<?>, Wrapper> activeWrappers;
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ public class DecoderFactory implements Configurable
|
||||||
protected DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory)
|
protected DecoderFactory(WebSocketContainerScope containerScope, DecoderMetadataSet metadatas, DecoderFactory parentFactory)
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(containerScope,"Container Scope cannot be null");
|
Objects.requireNonNull(containerScope,"Container Scope cannot be null");
|
||||||
this.objectFactory = containerScope.getObjectFactory();
|
this.containerScope = containerScope;
|
||||||
this.metadatas = metadatas;
|
this.metadatas = metadatas;
|
||||||
this.activeWrappers = new ConcurrentHashMap<>();
|
this.activeWrappers = new ConcurrentHashMap<>();
|
||||||
this.parentFactory = parentFactory;
|
this.parentFactory = parentFactory;
|
||||||
|
@ -186,7 +185,7 @@ public class DecoderFactory implements Configurable
|
||||||
Class<? extends Decoder> decoderClass = metadata.getCoderClass();
|
Class<? extends Decoder> decoderClass = metadata.getCoderClass();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Decoder decoder = objectFactory.createInstance(decoderClass);
|
Decoder decoder = containerScope.getObjectFactory().createInstance(decoderClass);
|
||||||
return new Wrapper(decoder,metadata);
|
return new Wrapper(decoder,metadata);
|
||||||
}
|
}
|
||||||
catch (InstantiationException | IllegalAccessException e)
|
catch (InstantiationException | IllegalAccessException e)
|
||||||
|
|
|
@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import javax.websocket.Encoder;
|
import javax.websocket.Encoder;
|
||||||
import javax.websocket.EndpointConfig;
|
import javax.websocket.EndpointConfig;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
||||||
|
@ -69,7 +68,7 @@ public class EncoderFactory implements Configurable
|
||||||
private static final Logger LOG = Log.getLogger(EncoderFactory.class);
|
private static final Logger LOG = Log.getLogger(EncoderFactory.class);
|
||||||
|
|
||||||
private final EncoderMetadataSet metadatas;
|
private final EncoderMetadataSet metadatas;
|
||||||
private final DecoratedObjectFactory objectFactory;
|
private final WebSocketContainerScope containerScope;
|
||||||
private EncoderFactory parentFactory;
|
private EncoderFactory parentFactory;
|
||||||
private Map<Class<?>, Wrapper> activeWrappers;
|
private Map<Class<?>, Wrapper> activeWrappers;
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ public class EncoderFactory implements Configurable
|
||||||
protected EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory)
|
protected EncoderFactory(WebSocketContainerScope containerScope, EncoderMetadataSet metadatas, EncoderFactory parentFactory)
|
||||||
{
|
{
|
||||||
Objects.requireNonNull(containerScope,"Container Scope cannot be null");
|
Objects.requireNonNull(containerScope,"Container Scope cannot be null");
|
||||||
this.objectFactory = containerScope.getObjectFactory();
|
this.containerScope = containerScope;
|
||||||
this.metadatas = metadatas;
|
this.metadatas = metadatas;
|
||||||
this.activeWrappers = new ConcurrentHashMap<>();
|
this.activeWrappers = new ConcurrentHashMap<>();
|
||||||
this.parentFactory = parentFactory;
|
this.parentFactory = parentFactory;
|
||||||
|
@ -179,7 +178,7 @@ public class EncoderFactory implements Configurable
|
||||||
Class<? extends Encoder> encoderClass = metadata.getCoderClass();
|
Class<? extends Encoder> encoderClass = metadata.getCoderClass();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Encoder encoder = objectFactory.createInstance(encoderClass);
|
Encoder encoder = containerScope.getObjectFactory().createInstance(encoderClass);
|
||||||
return new Wrapper(encoder,metadata);
|
return new Wrapper(encoder,metadata);
|
||||||
}
|
}
|
||||||
catch (InstantiationException | IllegalAccessException e)
|
catch (InstantiationException | IllegalAccessException e)
|
||||||
|
|
|
@ -22,16 +22,24 @@ import javax.websocket.ContainerProvider;
|
||||||
import javax.websocket.WebSocketContainer;
|
import javax.websocket.WebSocketContainer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client {@link ContainerProvider} implementation
|
* Client {@link ContainerProvider} implementation.
|
||||||
|
* <p>
|
||||||
|
* Created by a {@link java.util.ServiceLoader} call in the
|
||||||
|
* {@link javax.websocket.ContainerProvider#getWebSocketContainer()} call.
|
||||||
*/
|
*/
|
||||||
public class JettyClientContainerProvider extends ContainerProvider
|
public class JettyClientContainerProvider extends ContainerProvider
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Used by {@link ContainerProvider#getWebSocketContainer()} to get a new instance
|
||||||
|
* of the Client {@link WebSocketContainer}.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected WebSocketContainer getContainer()
|
protected WebSocketContainer getContainer()
|
||||||
{
|
{
|
||||||
ClientContainer container = new ClientContainer();
|
ClientContainer container = new ClientContainer();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// We need to start this container properly.
|
||||||
container.start();
|
container.start();
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
org.eclipse.jetty.LEVEL=WARN
|
org.eclipse.jetty.LEVEL=WARN
|
||||||
|
|
||||||
|
# org.eclipse.jetty.websocket.LEVEL=INFO
|
||||||
# org.eclipse.jetty.websocket.LEVEL=ALL
|
# org.eclipse.jetty.websocket.LEVEL=ALL
|
||||||
# org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG
|
# org.eclipse.jetty.websocket.jsr356.LEVEL=DEBUG
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cfgr = new BasicServerEndpointConfigurator(containerScope);
|
cfgr = new ContainerDefaultConfigurator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -144,7 +144,6 @@ public class AnnotatedServerEndpointConfig implements ServerEndpointConfig
|
||||||
|
|
||||||
// Make sure all Configurators obtained are decorated
|
// Make sure all Configurators obtained are decorated
|
||||||
this.configurator = containerScope.getObjectFactory().decorate(cfgr);
|
this.configurator = containerScope.getObjectFactory().decorate(cfgr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig
|
||||||
this.subprotocols = new ArrayList<>();
|
this.subprotocols = new ArrayList<>();
|
||||||
this.extensions = new ArrayList<>();
|
this.extensions = new ArrayList<>();
|
||||||
this.userProperties = new HashMap<>();
|
this.userProperties = new HashMap<>();
|
||||||
this.configurator = new BasicServerEndpointConfigurator(containerScope);
|
this.configurator = new ContainerDefaultConfigurator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig copy)
|
public BasicServerEndpointConfig(WebSocketContainerScope containerScope, ServerEndpointConfig copy)
|
||||||
|
@ -73,7 +73,7 @@ public class BasicServerEndpointConfig implements ServerEndpointConfig
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cfgr = new BasicServerEndpointConfigurator(containerScope);
|
cfgr = new ContainerDefaultConfigurator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all Configurators obtained are decorated
|
// Make sure all Configurators obtained are decorated
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
//
|
|
||||||
// ========================================================================
|
|
||||||
// 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.websocket.jsr356.server;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
|
||||||
import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Basic Configurator
|
|
||||||
*/
|
|
||||||
public class BasicServerEndpointConfigurator extends ContainerDefaultConfigurator
|
|
||||||
{
|
|
||||||
private static final Logger LOG = Log.getLogger(BasicServerEndpointConfigurator.class);
|
|
||||||
private final DecoratedObjectFactory objectFactory;
|
|
||||||
|
|
||||||
public BasicServerEndpointConfigurator(WebSocketContainerScope containerScope)
|
|
||||||
{
|
|
||||||
super();
|
|
||||||
this.objectFactory = containerScope.getObjectFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException
|
|
||||||
{
|
|
||||||
if (LOG.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOG.debug(".getEndpointInstance({})",endpointClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return objectFactory.createInstance(endpointClass);
|
|
||||||
}
|
|
||||||
catch (IllegalAccessException e)
|
|
||||||
{
|
|
||||||
throw new InstantiationException(String.format("%s: %s",e.getClass().getName(),e.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.websocket.api.util.QuoteUtil;
|
||||||
*
|
*
|
||||||
* @see ServiceLoader behavior of {@link ServerEndpointConfig.Configurator}
|
* @see ServiceLoader behavior of {@link ServerEndpointConfig.Configurator}
|
||||||
*/
|
*/
|
||||||
public class ContainerDefaultConfigurator extends Configurator
|
public final class ContainerDefaultConfigurator extends Configurator
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(ContainerDefaultConfigurator.class);
|
private static final Logger LOG = Log.getLogger(ContainerDefaultConfigurator.class);
|
||||||
private static final String NO_SUBPROTOCOL = "";
|
private static final String NO_SUBPROTOCOL = "";
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
||||||
import javax.websocket.Extension;
|
import javax.websocket.Extension;
|
||||||
import javax.websocket.Extension.Parameter;
|
import javax.websocket.Extension.Parameter;
|
||||||
import javax.websocket.server.ServerEndpointConfig;
|
import javax.websocket.server.ServerEndpointConfig;
|
||||||
|
import javax.websocket.server.ServerEndpointConfig.Configurator;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
@ -137,7 +138,13 @@ public class JsrCreator implements WebSocketCreator
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Class<?> endpointClass = config.getEndpointClass();
|
Class<?> endpointClass = config.getEndpointClass();
|
||||||
Object endpoint = config.getConfigurator().getEndpointInstance(endpointClass);
|
Configurator configr = config.getConfigurator();
|
||||||
|
Object endpoint = configr.getEndpointInstance(endpointClass);
|
||||||
|
if (configr instanceof ContainerDefaultConfigurator)
|
||||||
|
{
|
||||||
|
// default impl always decorates (custom ones do not)
|
||||||
|
endpoint = containerScope.getObjectFactory().decorate(endpoint);
|
||||||
|
}
|
||||||
PathSpec pathSpec = hsreq.getRequestPathSpec();
|
PathSpec pathSpec = hsreq.getRequestPathSpec();
|
||||||
if (pathSpec instanceof WebSocketPathSpec)
|
if (pathSpec instanceof WebSocketPathSpec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.websocket.jsr356.server;
|
package org.eclipse.jetty.websocket.jsr356.server;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import javax.websocket.DeploymentException;
|
import javax.websocket.DeploymentException;
|
||||||
|
@ -43,16 +45,19 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||||
|
|
||||||
private final MappedWebSocketCreator mappedCreator;
|
private final MappedWebSocketCreator mappedCreator;
|
||||||
private final WebSocketServerFactory webSocketServerFactory;
|
private final WebSocketServerFactory webSocketServerFactory;
|
||||||
|
private List<Class<?>> deferredEndpointClasses;
|
||||||
|
private List<ServerEndpointConfig> deferredEndpointConfigs;
|
||||||
|
|
||||||
public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
|
public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
|
||||||
{
|
{
|
||||||
super();
|
super(factory);
|
||||||
this.mappedCreator = creator;
|
this.mappedCreator = creator;
|
||||||
this.webSocketServerFactory = factory;
|
this.webSocketServerFactory = factory;
|
||||||
EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
|
EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
|
||||||
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
|
eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
|
||||||
eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
|
eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
|
||||||
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this,this));
|
this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this,this));
|
||||||
|
addBean(webSocketServerFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
|
public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
|
||||||
|
@ -75,12 +80,23 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEndpoint(Class<?> endpointClass) throws DeploymentException
|
public void addEndpoint(Class<?> endpointClass) throws DeploymentException
|
||||||
|
{
|
||||||
|
if (isStarted() || isStarting())
|
||||||
{
|
{
|
||||||
ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass,null);
|
ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass,null);
|
||||||
addEndpoint(metadata);
|
addEndpoint(metadata);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (deferredEndpointClasses == null)
|
||||||
|
{
|
||||||
|
deferredEndpointClasses = new ArrayList<Class<?>>();
|
||||||
|
}
|
||||||
|
deferredEndpointClasses.add(endpointClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
|
private void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
|
||||||
{
|
{
|
||||||
JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory());
|
JsrCreator creator = new JsrCreator(this,metadata,webSocketServerFactory.getExtensionFactory());
|
||||||
mappedCreator.addMapping(new WebSocketPathSpec(metadata.getPath()),creator);
|
mappedCreator.addMapping(new WebSocketPathSpec(metadata.getPath()),creator);
|
||||||
|
@ -88,6 +104,8 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addEndpoint(ServerEndpointConfig config) throws DeploymentException
|
public void addEndpoint(ServerEndpointConfig config) throws DeploymentException
|
||||||
|
{
|
||||||
|
if (isStarted() || isStarting())
|
||||||
{
|
{
|
||||||
if (LOG.isDebugEnabled())
|
if (LOG.isDebugEnabled())
|
||||||
{
|
{
|
||||||
|
@ -96,6 +114,42 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
|
||||||
ServerEndpointMetadata metadata = getServerEndpointMetadata(config.getEndpointClass(),config);
|
ServerEndpointMetadata metadata = getServerEndpointMetadata(config.getEndpointClass(),config);
|
||||||
addEndpoint(metadata);
|
addEndpoint(metadata);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (deferredEndpointConfigs == null)
|
||||||
|
{
|
||||||
|
deferredEndpointConfigs = new ArrayList<ServerEndpointConfig>();
|
||||||
|
}
|
||||||
|
deferredEndpointConfigs.add(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStart() throws Exception
|
||||||
|
{
|
||||||
|
// Proceed with Normal Startup
|
||||||
|
super.doStart();
|
||||||
|
|
||||||
|
// Process Deferred Endpoints
|
||||||
|
if (deferredEndpointClasses != null)
|
||||||
|
{
|
||||||
|
for (Class<?> endpointClass : deferredEndpointClasses)
|
||||||
|
{
|
||||||
|
addEndpoint(endpointClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deferredEndpointConfigs != null)
|
||||||
|
{
|
||||||
|
for (ServerEndpointConfig config : deferredEndpointConfigs)
|
||||||
|
{
|
||||||
|
addEndpoint(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deferredEndpointClasses.clear();
|
||||||
|
deferredEndpointConfigs.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
|
public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
|
||||||
{
|
{
|
||||||
|
|
|
@ -58,7 +58,6 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||||
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
||||||
|
|
||||||
// Create the Jetty ServerContainer implementation
|
// Create the Jetty ServerContainer implementation
|
||||||
filter.getFactory().init(context);
|
|
||||||
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),context.getServer().getThreadPool());
|
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),context.getServer().getThreadPool());
|
||||||
context.addBean(jettyContainer);
|
context.addBean(jettyContainer);
|
||||||
|
|
||||||
|
@ -79,7 +78,6 @@ public class WebSocketServerContainerInitializer implements ServletContainerInit
|
||||||
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
|
||||||
|
|
||||||
// Create the Jetty ServerContainer implementation
|
// Create the Jetty ServerContainer implementation
|
||||||
filter.getFactory().init(context);
|
|
||||||
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),jettyContext.getServer().getThreadPool());
|
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory(),jettyContext.getServer().getThreadPool());
|
||||||
jettyContext.addBean(jettyContainer);
|
jettyContext.addBean(jettyContainer);
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,7 @@ public class WebSocketServerFactory extends ContainerLifeCycle implements WebSoc
|
||||||
|
|
||||||
public void init(ServletContextHandler context) throws ServletException
|
public void init(ServletContextHandler context) throws ServletException
|
||||||
{
|
{
|
||||||
this.objectFactory = (DecoratedObjectFactory)context.getAttribute(DecoratedObjectFactory.ATTR);
|
this.objectFactory = (DecoratedObjectFactory)context.getServletContext().getAttribute(DecoratedObjectFactory.ATTR);
|
||||||
if (this.objectFactory == null)
|
if (this.objectFactory == null)
|
||||||
{
|
{
|
||||||
this.objectFactory = new DecoratedObjectFactory();
|
this.objectFactory = new DecoratedObjectFactory();
|
||||||
|
|
|
@ -257,7 +257,8 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
factory.init(config.getServletContext());
|
ServletContext ctx = config.getServletContext();
|
||||||
|
factory.init(ctx);
|
||||||
WebSocketPolicy policy = factory.getPolicy();
|
WebSocketPolicy policy = factory.getPolicy();
|
||||||
|
|
||||||
String max = config.getInitParameter("maxIdleTime");
|
String max = config.getInitParameter("maxIdleTime");
|
||||||
|
@ -291,7 +292,7 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
|
||||||
key = WebSocketUpgradeFilter.class.getName();
|
key = WebSocketUpgradeFilter.class.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
setToAttribute(config.getServletContext(), key);
|
setToAttribute(ctx, key);
|
||||||
|
|
||||||
factory.start();
|
factory.start();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// 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.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
|
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||||
|
import org.eclipse.jetty.util.Decorator;
|
||||||
|
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||||
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DecoratorsLegacyTest
|
||||||
|
{
|
||||||
|
private static class DecoratorsSocket extends WebSocketAdapter
|
||||||
|
{
|
||||||
|
private final DecoratedObjectFactory objFactory;
|
||||||
|
|
||||||
|
public DecoratorsSocket(DecoratedObjectFactory objFactory)
|
||||||
|
{
|
||||||
|
this.objFactory = objFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketText(String message)
|
||||||
|
{
|
||||||
|
StringWriter str = new StringWriter();
|
||||||
|
PrintWriter out = new PrintWriter(str);
|
||||||
|
|
||||||
|
if (objFactory != null)
|
||||||
|
{
|
||||||
|
out.printf("Object is a DecoratedObjectFactory%n");
|
||||||
|
List<Decorator> decorators = objFactory.getDecorators();
|
||||||
|
out.printf("Decorators.size = [%d]%n",decorators.size());
|
||||||
|
for (Decorator decorator : decorators)
|
||||||
|
{
|
||||||
|
out.printf(" decorator[] = %s%n",decorator.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.printf("DecoratedObjectFactory is NULL%n");
|
||||||
|
}
|
||||||
|
|
||||||
|
getRemote().sendStringByFuture(str.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DecoratorsCreator implements WebSocketCreator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||||
|
{
|
||||||
|
ServletContext servletContext = req.getHttpServletRequest().getServletContext();
|
||||||
|
DecoratedObjectFactory objFactory = (DecoratedObjectFactory)servletContext.getAttribute(DecoratedObjectFactory.ATTR);
|
||||||
|
return new DecoratorsSocket(objFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DecoratorsRequestServlet extends WebSocketServlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final WebSocketCreator creator;
|
||||||
|
|
||||||
|
public DecoratorsRequestServlet(WebSocketCreator creator)
|
||||||
|
{
|
||||||
|
this.creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(WebSocketServletFactory factory)
|
||||||
|
{
|
||||||
|
factory.setCreator(this.creator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DummyLegacyDecorator implements org.eclipse.jetty.servlet.ServletContextHandler.Decorator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public <T> T decorate(T o)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(Object o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimpleServletServer server;
|
||||||
|
private static DecoratorsCreator decoratorsCreator;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
|
{
|
||||||
|
decoratorsCreator = new DecoratorsCreator();
|
||||||
|
server = new SimpleServletServer(new DecoratorsRequestServlet(decoratorsCreator))
|
||||||
|
{
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
@Override
|
||||||
|
protected void configureServletContextHandler(ServletContextHandler context)
|
||||||
|
{
|
||||||
|
// Add decorator in the legacy way
|
||||||
|
context.addDecorator(new DummyLegacyDecorator());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopServer()
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAccessRequestCookies() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.setTimeout(1,TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
client.write(new TextFrame().setPayload("info"));
|
||||||
|
|
||||||
|
EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
|
||||||
|
WebSocketFrame resp = frames.poll();
|
||||||
|
String textMsg = resp.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory"));
|
||||||
|
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
||||||
|
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyLegacyDecorator.class.getName()));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,178 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// 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.websocket.server;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||||
|
import org.eclipse.jetty.toolchain.test.EventQueue;
|
||||||
|
import org.eclipse.jetty.util.DecoratedObjectFactory;
|
||||||
|
import org.eclipse.jetty.util.Decorator;
|
||||||
|
import org.eclipse.jetty.websocket.api.WebSocketAdapter;
|
||||||
|
import org.eclipse.jetty.websocket.common.WebSocketFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.frames.TextFrame;
|
||||||
|
import org.eclipse.jetty.websocket.common.test.BlockheadClient;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||||
|
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class DecoratorsTest
|
||||||
|
{
|
||||||
|
private static class DecoratorsSocket extends WebSocketAdapter
|
||||||
|
{
|
||||||
|
private final DecoratedObjectFactory objFactory;
|
||||||
|
|
||||||
|
public DecoratorsSocket(DecoratedObjectFactory objFactory)
|
||||||
|
{
|
||||||
|
this.objFactory = objFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWebSocketText(String message)
|
||||||
|
{
|
||||||
|
StringWriter str = new StringWriter();
|
||||||
|
PrintWriter out = new PrintWriter(str);
|
||||||
|
|
||||||
|
if (objFactory != null)
|
||||||
|
{
|
||||||
|
out.printf("Object is a DecoratedObjectFactory%n");
|
||||||
|
List<Decorator> decorators = objFactory.getDecorators();
|
||||||
|
out.printf("Decorators.size = [%d]%n",decorators.size());
|
||||||
|
for (Decorator decorator : decorators)
|
||||||
|
{
|
||||||
|
out.printf(" decorator[] = %s%n",decorator.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.printf("DecoratedObjectFactory is NULL%n");
|
||||||
|
}
|
||||||
|
|
||||||
|
getRemote().sendStringByFuture(str.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DecoratorsCreator implements WebSocketCreator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp)
|
||||||
|
{
|
||||||
|
ServletContext servletContext = req.getHttpServletRequest().getServletContext();
|
||||||
|
DecoratedObjectFactory objFactory = (DecoratedObjectFactory)servletContext.getAttribute(DecoratedObjectFactory.ATTR);
|
||||||
|
return new DecoratorsSocket(objFactory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DecoratorsRequestServlet extends WebSocketServlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final WebSocketCreator creator;
|
||||||
|
|
||||||
|
public DecoratorsRequestServlet(WebSocketCreator creator)
|
||||||
|
{
|
||||||
|
this.creator = creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configure(WebSocketServletFactory factory)
|
||||||
|
{
|
||||||
|
factory.setCreator(this.creator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DummyUtilDecorator implements org.eclipse.jetty.util.Decorator
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public <T> T decorate(T o)
|
||||||
|
{
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(Object o)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimpleServletServer server;
|
||||||
|
private static DecoratorsCreator decoratorsCreator;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void startServer() throws Exception
|
||||||
|
{
|
||||||
|
decoratorsCreator = new DecoratorsCreator();
|
||||||
|
server = new SimpleServletServer(new DecoratorsRequestServlet(decoratorsCreator))
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void configureServletContextHandler(ServletContextHandler context)
|
||||||
|
{
|
||||||
|
// Add decorator in the new util way
|
||||||
|
context.getObjectFactory().addDecorator(new DummyUtilDecorator());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
server.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void stopServer()
|
||||||
|
{
|
||||||
|
server.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAccessRequestCookies() throws Exception
|
||||||
|
{
|
||||||
|
BlockheadClient client = new BlockheadClient(server.getServerUri());
|
||||||
|
client.setTimeout(1,TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
client.connect();
|
||||||
|
client.sendStandardRequest();
|
||||||
|
client.expectUpgradeResponse();
|
||||||
|
|
||||||
|
client.write(new TextFrame().setPayload("info"));
|
||||||
|
|
||||||
|
EventQueue<WebSocketFrame> frames = client.readFrames(1,1,TimeUnit.SECONDS);
|
||||||
|
WebSocketFrame resp = frames.poll();
|
||||||
|
String textMsg = resp.getPayloadAsUTF8();
|
||||||
|
|
||||||
|
assertThat("DecoratedObjectFactory", textMsg, containsString("Object is a DecoratedObjectFactory"));
|
||||||
|
assertThat("decorators.size", textMsg, containsString("Decorators.size = [1]"));
|
||||||
|
assertThat("decorator type", textMsg, containsString("decorator[] = " + DummyUtilDecorator.class.getName()));
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
client.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -114,6 +114,7 @@ public class SimpleServletServer
|
||||||
|
|
||||||
ServletContextHandler context = new ServletContextHandler();
|
ServletContextHandler context = new ServletContextHandler();
|
||||||
context.setContextPath("/");
|
context.setContextPath("/");
|
||||||
|
configureServletContextHandler(context);
|
||||||
server.setHandler(context);
|
server.setHandler(context);
|
||||||
|
|
||||||
// Serve capture servlet
|
// Serve capture servlet
|
||||||
|
@ -138,6 +139,10 @@ public class SimpleServletServer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void configureServletContextHandler(ServletContextHandler context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
public void stop()
|
public void stop()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.websocket.servlet;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -129,9 +130,11 @@ public abstract class WebSocketServlet extends HttpServlet
|
||||||
|
|
||||||
configure(factory);
|
configure(factory);
|
||||||
|
|
||||||
factory.init(getServletContext());
|
ServletContext ctx = getServletContext();
|
||||||
|
|
||||||
getServletContext().setAttribute(WebSocketServletFactory.class.getName(),factory);
|
factory.init(ctx);
|
||||||
|
|
||||||
|
ctx.setAttribute(WebSocketServletFactory.class.getName(),factory);
|
||||||
}
|
}
|
||||||
catch (Exception x)
|
catch (Exception x)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue