Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: cometd/cometd
base: ca26dc10a9
...
head fork: cometd/cometd
compare: 85d09c592b
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
View
7 cometd-java/cometd-java-examples/pom.xml
@@ -48,6 +48,13 @@
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson-version}</version>
</dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>${slf4j-version}</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<profiles>
View
161 cometd-java/cometd-java-examples/src/main/java/org/cometd/examples/MultiTentantDemo.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.cometd.examples;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.bayeux.server.ConfigurableServerChannel;
+import org.cometd.bayeux.server.ServerChannel;
+import org.cometd.bayeux.server.ServerMessage.Mutable;
+import org.cometd.bayeux.server.ServerSession;
+import org.cometd.examples.CometdDemoServlet.EchoRPC;
+import org.cometd.examples.CometdDemoServlet.Monitor;
+import org.cometd.java.annotation.AnnotationCometdServlet;
+import org.cometd.java.annotation.ServerAnnotationProcessor;
+import org.cometd.server.BayeuxServerImpl;
+import org.cometd.server.CometdServlet;
+import org.cometd.server.DefaultSecurityPolicy;
+import org.cometd.server.MultiTenantCometdServlet;
+import org.cometd.server.authorizer.GrantAuthorizer;
+import org.cometd.server.ext.AcknowledgedMessagesExtension;
+import org.cometd.server.ext.TimesyncExtension;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.server.handler.ContextHandlerCollection;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.servlet.DefaultServlet;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.util.resource.Resource;
+import org.eclipse.jetty.util.resource.ResourceCollection;
+import org.eclipse.jetty.util.thread.QueuedThreadPool;
+
+/* ------------------------------------------------------------ */
+/**
+ * Main class for cometd demo.
+ */
+public class MultiTentantDemo
+{
+ /* ------------------------------------------------------------ */
+ /**
+ * @param args
+ */
+ public static void main(String[] args) throws Exception
+ {
+ int port = args.length==0?8080:Integer.parseInt(args[0]);
+
+ // Manually contruct context to avoid hassles with webapp classloaders for now.
+ Server server = new Server();
+ QueuedThreadPool qtp = new QueuedThreadPool();
+ qtp.setMinThreads(5);
+ qtp.setMaxThreads(200);
+ server.setThreadPool(qtp);
+
+ SelectChannelConnector connector=new SelectChannelConnector();
+ // SocketConnector connector=new SocketConnector();
+ connector.setPort(port);
+ connector.setMaxIdleTime(120000);
+ connector.setLowResourcesMaxIdleTime(60000);
+ connector.setLowResourcesConnections(20000);
+ connector.setAcceptQueueSize(5000);
+ server.addConnector(connector);
+ SocketConnector bconnector=new SocketConnector();
+ bconnector.setPort(port+1);
+ server.addConnector(bconnector);
+
+
+ ContextHandlerCollection contexts = new ContextHandlerCollection();
+ server.setHandler(contexts);
+
+ // MovedContextHandler moved = new MovedContextHandler(contexts,"/","/cometd");
+ // moved.setDiscardPathInfo(true);
+
+ ServletContextHandler context = new ServletContextHandler(contexts,"/",ServletContextHandler.SESSIONS);
+ context.setBaseResource(
+ new ResourceCollection(new Resource[]
+ {
+ Resource.newResource("../../cometd-demo/src/main/webapp/"),
+
+ Resource.newResource("../../cometd-javascript/common/src/main/webapp/"),
+ Resource.newResource("../../cometd-javascript/common-test/target/scripts/"),
+ Resource.newResource("../../cometd-javascript/jquery/src/main/webapp/"),
+ Resource.newResource("../../cometd-javascript/examples-jquery/src/main/webapp/"),
+
+ Resource.newResource("../../cometd-javascript/dojo/src/main/webapp/"),
+ Resource.newResource("../../cometd-javascript/examples-dojo/src/main/webapp/"),
+ Resource.newResource("../../cometd-javascript/dojo/target/war/work/org.dojotoolkit/dojo-war/")
+ }));
+
+
+ ServletHolder dftServlet = context.addServlet(DefaultServlet.class, "/");
+ dftServlet.setInitOrder(1);
+
+ // Cometd servlet
+ CometdServlet cometdServlet = new MultiTenantCometdServlet()
+ {
+
+ @Override
+ protected void customise(BayeuxServerImpl bayeux)
+ {
+ bayeux.setSecurityPolicy(new DefaultSecurityPolicy());
+ bayeux.createIfAbsent("/**",new ServerChannel.Initializer()
+ {
+ public void configureChannel(ConfigurableServerChannel channel)
+ {
+ channel.addAuthorizer(GrantAuthorizer.GRANT_NONE);
+ }
+ });
+ bayeux.getChannel(ServerChannel.META_HANDSHAKE).addAuthorizer(GrantAuthorizer.GRANT_PUBLISH);
+
+
+ bayeux.addExtension(new TimesyncExtension());
+ bayeux.addExtension(new AcknowledgedMessagesExtension());
+
+ ServerAnnotationProcessor processor = new ServerAnnotationProcessor(bayeux);
+ processor.process(new ChatService());
+ processor.process(new EchoRPC());
+ processor.process(new Monitor());
+
+ // TODO find a way to deprocess services on stop/idle tenant
+ }
+
+ @Override
+ protected String getTenantId(HttpServletRequest request)
+ {
+ // Use local address as simple tenant ID
+ return request.getLocalAddr().toString().replace('/','_');
+ }
+
+ };
+
+ ServletHolder comet = new ServletHolder(cometdServlet);
+ context.addServlet(comet, "/cometd/*");
+ comet.setInitParameter("timeout","20000");
+ comet.setInitParameter("interval","100");
+ comet.setInitParameter("maxInterval","10000");
+ comet.setInitParameter("multiFrameInterval","5000");
+ comet.setInitParameter("logLevel","1");
+ comet.setInitParameter("transports","org.cometd.websocket.server.WebSocketTransport");
+ comet.setInitOrder(2);
+
+
+ server.start();
+
+
+ }
+}
View
48 cometd-java/cometd-java-server/src/main/java/org/cometd/server/MultiTenantCometdServlet.java
@@ -8,12 +8,24 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.eclipse.jetty.util.log.Log;
-import org.eclipse.jetty.util.log.Logger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class MultiTenantCometdServlet extends CometdServlet
+/**
+ * Multi Tenant Cometd Servlet
+ * <p>
+ * This servlet creates multiple instances of the {@link BayeuxServerImpl} based on tenant ID's that
+ * are obtained by passing the request to the abstract method {@link #getTenantId(HttpServletRequest)}.
+ * The implementation of this method may determine a tenant ID by cookies, headers, target IP address, port, session
+ * or any other HTTP mechanism available.
+ * <p>
+ * The first time a new tenantID is seen, a new {@link BayeuxServerImpl} instance is created and is passed
+ * to the abstract method {@link #customise(BayeuxServerImpl)} so that services and extensions may be added.
+ *
+ */
+public abstract class MultiTenantCometdServlet extends CometdServlet
{
- private final static Logger LOG = Log.getLogger(MultiTenantCometdServlet.class);
+ protected final Logger _logger = LoggerFactory.getLogger(getClass());
private final ConcurrentMap<String, BayeuxServerImpl> _bayeux= new ConcurrentHashMap<String, BayeuxServerImpl>();
/**
@@ -47,7 +59,10 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
bayeux.start();
BayeuxServerImpl b=_bayeux.putIfAbsent(tenantId,bayeux);
if (b==null)
- LOG.info("New tenant: "+tenantId);
+ {
+ _logger.info("New tenant: "+tenantId);
+ customise(bayeux);
+ }
else
{
bayeux.stop();
@@ -57,7 +72,7 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
}
catch (Exception e)
{
- LOG.warn(e);
+ _logger.warn("",e);
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
@@ -65,15 +80,30 @@ protected void service(HttpServletRequest request, HttpServletResponse response)
service(bayeux,request,response);
}
- protected String getTenantId(HttpServletRequest request)
+ @Override
+ public BayeuxServerImpl getBayeux()
{
- return request.getLocalAddr().toString().replace('/','_');
+ throw new UnsupportedOperationException("Multitenanted mode");
}
+ abstract protected void customise(BayeuxServerImpl bayeux);
+
+ abstract protected String getTenantId(HttpServletRequest request);
+
@Override
public void destroy()
{
- // TODO Auto-generated method stub
+ for (BayeuxServerImpl bayeux : _bayeux.values())
+ {
+ try
+ {
+ bayeux.stop();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("",e);
+ }
+ }
}
}

No commit comments for this range

Something went wrong with that request. Please try again.