Author: richard.opalka(a)jboss.com
Date: 2009-10-12 09:08:34 -0400 (Mon, 12 Oct 2009)
New Revision: 10888
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java
Removed:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java
Log:
[JBWS-2674][JBWS-2754] refactoring (WIP)
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandlerImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,208 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.management.ObjectName;
+import javax.xml.ws.WebServiceException;
+
+import org.jboss.logging.Logger;
+import org.jboss.ws.Constants;
+import org.jboss.ws.WSException;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandlerImpl;
+import org.jboss.wsf.common.ObjectNameFactory;
+import org.jboss.wsf.common.injection.InjectionHelper;
+import org.jboss.wsf.common.injection.PreDestroyHolder;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.Endpoint;
+import org.jboss.wsf.spi.invocation.EndpointAssociation;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+import org.jboss.wsf.spi.invocation.RequestHandler;
+import org.jboss.wsf.spi.management.EndpointRegistry;
+import org.jboss.wsf.spi.management.EndpointRegistryFactory;
+import org.jboss.wsf.spi.management.EndpointResolver;
+import org.jboss.wsf.stack.jbws.WebAppResolver;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+final class NettyCallbackHandlerImpl implements NettyCallbackHandler
+{
+ private static final Logger LOGGER = Logger.getLogger(RMCallbackHandlerImpl.class);
+
+ private final String handledPath;
+
+ private final SPIProvider spiProvider =
SPIProviderResolver.getInstance().getProvider();
+
+ private EndpointRegistry epRegistry;
+
+ private Endpoint endpoint;
+
+ private List<PreDestroyHolder> preDestroyRegistry = new
LinkedList<PreDestroyHolder>();
+
+ /**
+ * Request path to listen for incomming messages
+ * @param handledPath
+ */
+ public NettyCallbackHandlerImpl(String path, String context, String
endpointRegistryPath)
+ {
+ super();
+ this.initRegistry();
+ this.initEndpoint(context, endpointRegistryPath);
+ this.handledPath = path;
+ }
+
+ /**
+ * Initializes endpoint registry
+ */
+ private void initRegistry()
+ {
+ epRegistry =
spiProvider.getSPI(EndpointRegistryFactory.class).getEndpointRegistry();
+ }
+
+ /**
+ * Initialize the service endpoint
+ * @param contextPath context path
+ * @param servletName servlet name
+ */
+ private void initEndpoint(final String context, final String endpointRegistryPath)
+ {
+ final EndpointResolver resolver = new WebAppResolver(context,
endpointRegistryPath);
+ this.endpoint = epRegistry.resolve(resolver);
+
+ if (this.endpoint == null)
+ {
+ ObjectName oname = ObjectNameFactory.create(Endpoint.SEPID_DOMAIN +
":" + Endpoint.SEPID_PROPERTY_CONTEXT
+ + "=" + context + "," +
Endpoint.SEPID_PROPERTY_ENDPOINT + "=" + endpointRegistryPath);
+ throw new WebServiceException("Cannot obtain endpoint for: " +
oname);
+ }
+ }
+
+ public int handle(String method, InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx)
+ throws IOException
+ {
+ Integer statusCode = null;
+ try
+ {
+ if (method.equals("POST"))
+ {
+ this.handle(inputStream, outputStream, invCtx, false);
+ statusCode = (Integer) invCtx.getProperty(Constants.NETTY_STATUS_CODE);
+ }
+ else if (method.equals("GET"))
+ {
+ this.handle(inputStream, outputStream, invCtx, true);
+ }
+ else
+ {
+ throw new WSException("Unsupported HTTP method: " + method);
+ }
+ }
+ catch (Exception e)
+ {
+ NettyCallbackHandlerImpl.LOGGER.error(e.getMessage(), e);
+ statusCode = 500;
+ }
+
+ return statusCode == null ? 200 : statusCode;
+ }
+
+ public String getPath()
+ {
+ return this.handledPath;
+ }
+
+ private void handle(final InputStream inputStream, final OutputStream outputStream,
final InvocationContext invCtx, final boolean wsdlRequest) throws IOException
+ {
+ try
+ {
+ EndpointAssociation.setEndpoint(this.endpoint);
+ final RequestHandler requestHandler = this.endpoint.getRequestHandler();
+
+ if (wsdlRequest)
+ {
+ requestHandler.handleWSDLRequest(this.endpoint, outputStream, invCtx);
+ }
+ else
+ {
+ requestHandler.handleRequest(this.endpoint, inputStream, outputStream,
invCtx);
+ }
+ }
+ finally
+ {
+ this.registerForPreDestroy(this.endpoint);
+ EndpointAssociation.removeEndpoint();
+ }
+ }
+
+ private void registerForPreDestroy(final Endpoint ep)
+ {
+ final PreDestroyHolder holder = (PreDestroyHolder)
ep.getAttachment(PreDestroyHolder.class);
+ if (holder != null)
+ {
+ synchronized (this.preDestroyRegistry)
+ {
+ if (!this.preDestroyRegistry.contains(holder))
+ {
+ this.preDestroyRegistry.add(holder);
+ }
+ }
+ ep.removeAttachment(PreDestroyHolder.class);
+ }
+ }
+
+ public final void init()
+ {
+ // does nothing
+ }
+
+ public final void destroy()
+ {
+ synchronized (this.preDestroyRegistry)
+ {
+ for (final PreDestroyHolder holder : this.preDestroyRegistry)
+ {
+ try
+ {
+ final Object targetBean = holder.getObject();
+ InjectionHelper.callPreDestroyMethod(targetBean);
+ }
+ catch (Exception exception)
+ {
+ NettyCallbackHandlerImpl.LOGGER.error(exception.getMessage(), exception);
+ }
+ }
+ this.preDestroyRegistry.clear();
+ this.preDestroyRegistry = null;
+ }
+ }
+
+}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -1,259 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.net.InetSocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import javax.xml.ws.WebServiceException;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
- */
-final class NettyHttpServer implements Runnable
-{
-
- private static final Logger LOG = Logger.getLogger(NettyHttpServer.class);
-
- private static final Lock CLASS_LOCK = new ReentrantLock();
-
- private static final long WAIT_PERIOD = 100;
-
- private static Map<String, NettyHttpServer> SERVERS = new HashMap<String,
NettyHttpServer>();
-
- static final ChannelGroup channelGroup = new
DefaultChannelGroup("rmBackPortsServer");
-
- private final Object instanceLock = new Object();
-
- private final String scheme;
-
- private final String host;
-
- private final int port;
-
- private boolean started;
-
- private boolean stopped;
-
- private boolean terminated;
-
- private ChannelFactory factory;
-
- private NettyInvocationHandler handler;
-
- private NettyHttpServer(String scheme, String host, int port)
- {
- super();
- this.scheme = scheme;
- this.host = host;
- this.port = port;
- try
- {
- factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
-
- ServerBootstrap bootstrap = new ServerBootstrap(factory);
- this.handler = new NettyInvocationHandler();
- WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
- channelPipelineFactory.setRequestHandler(this.handler);
- bootstrap.setPipelineFactory(channelPipelineFactory);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
- // Bind and start to accept incoming connections.
- Channel c = bootstrap.bind(new InetSocketAddress(this.port));
- channelGroup.add(c);
- if (LOG.isDebugEnabled())
- LOG.debug("Netty http server started on port: " + this.port);
- }
- catch (Exception e)
- {
- LOG.warn(e.getMessage(), e);
- throw new WebServiceException(e.getMessage(), e);
- }
- }
-
- public final void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
- {
- this.handler.registerCallback(callbackHandler);
- }
-
- public final void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
- {
- this.handler.unregisterCallback(callbackHandler);
- if (!this.hasMoreCallbacks())
- {
- this.terminate();
- }
- }
-
- public final NettyHttpServerCallbackHandler getCallback(String requestPath)
- {
- return this.handler.getCallback(requestPath);
- }
-
- public final boolean hasMoreCallbacks()
- {
- return this.handler.hasMoreCallbacks();
- }
-
- public final String getScheme()
- {
- return this.scheme;
- }
-
- public final String getHost()
- {
- return this.host;
- }
-
- public final int getPort()
- {
- return this.port;
- }
-
- public final void run()
- {
- synchronized (this.instanceLock)
- {
- if (this.started)
- return;
-
- this.started = true;
-
- while (this.stopped == false)
- {
- try
- {
- this.instanceLock.wait(WAIT_PERIOD);
- LOG.debug("serving requests");
- }
- catch (InterruptedException ie)
- {
- LOG.warn(ie.getMessage(), ie);
- }
- }
- try
- {
- //Close all connections and server sockets.
- channelGroup.close().awaitUninterruptibly();
- //Shutdown the selector loop (boss and worker).
- if (factory != null)
- {
- factory.releaseExternalResources();
- }
- }
- finally
- {
- LOG.debug("terminated");
- this.terminated = true;
- }
- }
- }
-
- public final void terminate()
- {
- synchronized (this.instanceLock)
- {
- if (this.stopped == true)
- return;
-
- this.stopped = true;
- LOG.debug("termination forced");
- SERVERS.remove(scheme + "://" + host + ":" + port +
"/");
- while (this.terminated == false)
- {
- try
- {
- LOG.debug("waiting for termination");
- this.instanceLock.wait(WAIT_PERIOD);
- }
- catch (InterruptedException ie)
- {
- LOG.warn(ie.getMessage(), ie);
- }
- }
- }
- }
-
- /**
- * Starts back ports server on the background if method is called for the first time
- * @param scheme protocol
- * @param host hostname
- * @param port port
- * @return netty http server
- */
- public static NettyHttpServer getInstance(String scheme, String host, int port)
- {
- CLASS_LOCK.lock();
- try
- {
- String key = scheme + "://" + host + ":" + port +
"/";
- NettyHttpServer server = SERVERS.get(key);
- if (server == null)
- {
- server = new NettyHttpServer(scheme, host, (port == -1) ? 80 : port);
- SERVERS.put(key, server);
- // forking back ports server
- Thread t = new Thread(server, "NettyHttpServer listening on " +
key);
- t.setDaemon(true);
- t.start();
- // registering shutdown hook
- final NettyHttpServer s = server;
- Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
- {
- public void run()
- {
- s.terminate();
- }
- }, "NettyHttpServerShutdownHook(" + key + ")"));
- }
- else
- {
- boolean schemeEquals = server.getScheme().equals(scheme);
- boolean hostEquals = server.getHost().equals(host);
- boolean portEquals = server.getPort() == ((port == -1) ? 80 : port);
- if ((schemeEquals == false) || (hostEquals == false) || (portEquals ==
false))
- throw new IllegalArgumentException();
- }
- return server;
- }
- finally
- {
- CLASS_LOCK.unlock();
- }
- }
-
-}
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -27,6 +27,10 @@
import javax.xml.ws.Endpoint;
import org.jboss.ws.core.jaxws.spi.EndpointImpl;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.core.server.netty.NettyHttpServer;
+import org.jboss.ws.core.server.netty.NettyHttpServerFactory;
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
import org.jboss.wsf.common.ResourceLoaderAdapter;
import org.jboss.wsf.framework.deployment.BackwardCompatibleContextRootDeploymentAspect;
import org.jboss.wsf.framework.deployment.DeploymentAspectManagerImpl;
@@ -70,6 +74,8 @@
/** Deployment model factory. */
private static final DeploymentModelFactory DEPLOYMENT_FACTORY =
NettyHttpServerAdapter.SPI_PROVIDER
.getSPI(DeploymentModelFactory.class);
+
+ private static final NettyRequestHandlerFactory requestHandlerFactory =
NettyRequestHandlerFactoryImpl.getInstance();
/**
* Constructor.
@@ -88,8 +94,8 @@
public void destroy(HttpContext context, Endpoint endpoint)
{
EndpointImpl epImpl = (EndpointImpl) endpoint;
- NettyHttpServer server = NettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
- NettyHttpServerCallbackHandler callback = server.getCallback(epImpl.getPath());
+ NettyHttpServer server =
NettyHttpServerFactory.getNettyHttpServer(epImpl.getPort(), this.requestHandlerFactory);
+ NettyCallbackHandler callback = server.getCallback(epImpl.getPath());
server.unregisterCallback(callback);
DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
@@ -108,8 +114,8 @@
daManager.deploy(dep);
epImpl.setDeployment(dep);
- NettyHttpServer server = NettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
- NettyHttpServerCallbackHandler callback = new
NettyHttpServerCallbackHandler(epImpl.getPath(), contextRoot, this
+ NettyHttpServer server =
NettyHttpServerFactory.getNettyHttpServer(epImpl.getPort(), requestHandlerFactory);
+ NettyCallbackHandler callback = new NettyCallbackHandlerImpl(epImpl.getPath(),
contextRoot, this
.getEndpointRegistryPath(epImpl));
server.registerCallback(callback);
}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -1,202 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.LinkedList;
-import java.util.List;
-
-import javax.management.ObjectName;
-import javax.xml.ws.WebServiceException;
-
-import org.jboss.logging.Logger;
-import org.jboss.ws.Constants;
-import org.jboss.ws.WSException;
-import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandlerImpl;
-import org.jboss.wsf.common.ObjectNameFactory;
-import org.jboss.wsf.common.injection.InjectionHelper;
-import org.jboss.wsf.common.injection.PreDestroyHolder;
-import org.jboss.wsf.spi.SPIProvider;
-import org.jboss.wsf.spi.SPIProviderResolver;
-import org.jboss.wsf.spi.deployment.Endpoint;
-import org.jboss.wsf.spi.invocation.EndpointAssociation;
-import org.jboss.wsf.spi.invocation.InvocationContext;
-import org.jboss.wsf.spi.invocation.RequestHandler;
-import org.jboss.wsf.spi.management.EndpointRegistry;
-import org.jboss.wsf.spi.management.EndpointRegistryFactory;
-import org.jboss.wsf.spi.management.EndpointResolver;
-import org.jboss.wsf.stack.jbws.WebAppResolver;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
- */
-final class NettyHttpServerCallbackHandler // TODO: review class name
-{
- private static final Logger LOGGER = Logger.getLogger(RMCallbackHandlerImpl.class);
-
- private final String handledPath;
-
- private final SPIProvider spiProvider =
SPIProviderResolver.getInstance().getProvider();
-
- private EndpointRegistry epRegistry;
-
- private Endpoint endpoint;
-
- private List<PreDestroyHolder> preDestroyRegistry = new
LinkedList<PreDestroyHolder>();
-
- /**
- * Request path to listen for incomming messages
- * @param handledPath
- */
- public NettyHttpServerCallbackHandler(String path, String context, String
endpointRegistryPath)
- {
- super();
- this.initRegistry();
- this.initEndpoint(context, endpointRegistryPath);
- this.handledPath = path;
- }
-
- /**
- * Initializes endpoint registry
- */
- private void initRegistry()
- {
- epRegistry =
spiProvider.getSPI(EndpointRegistryFactory.class).getEndpointRegistry();
- }
-
- /**
- * Initialize the service endpoint
- * @param contextPath context path
- * @param servletName servlet name
- */
- private void initEndpoint(final String context, final String endpointRegistryPath)
- {
- final EndpointResolver resolver = new WebAppResolver(context,
endpointRegistryPath);
- this.endpoint = epRegistry.resolve(resolver);
-
- if (this.endpoint == null)
- {
- ObjectName oname = ObjectNameFactory.create(Endpoint.SEPID_DOMAIN +
":" + Endpoint.SEPID_PROPERTY_CONTEXT
- + "=" + context + "," +
Endpoint.SEPID_PROPERTY_ENDPOINT + "=" + endpointRegistryPath);
- throw new WebServiceException("Cannot obtain endpoint for: " +
oname);
- }
- }
-
- public int handle(String method, InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx)
- throws IOException
- {
- Integer statusCode = null;
- try
- {
- if (method.equals("POST"))
- {
- this.handle(inputStream, outputStream, invCtx, false);
- statusCode = (Integer) invCtx.getProperty(Constants.NETTY_STATUS_CODE);
- }
- else if (method.equals("GET"))
- {
- this.handle(inputStream, outputStream, invCtx, true);
- }
- else
- {
- throw new WSException("Unsupported HTTP method: " + method);
- }
- }
- catch (Exception e)
- {
- NettyHttpServerCallbackHandler.LOGGER.error(e.getMessage(), e);
- statusCode = 500;
- }
-
- return statusCode == null ? 200 : statusCode;
- }
-
- public String getHandledPath()
- {
- return this.handledPath;
- }
-
- private void handle(final InputStream inputStream, final OutputStream outputStream,
final InvocationContext invCtx, final boolean wsdlRequest) throws IOException
- {
- try
- {
- EndpointAssociation.setEndpoint(this.endpoint);
- final RequestHandler requestHandler = this.endpoint.getRequestHandler();
-
- if (wsdlRequest)
- {
- requestHandler.handleWSDLRequest(this.endpoint, outputStream, invCtx);
- }
- else
- {
- requestHandler.handleRequest(this.endpoint, inputStream, outputStream,
invCtx);
- }
- }
- finally
- {
- this.registerForPreDestroy(this.endpoint);
- EndpointAssociation.removeEndpoint();
- }
- }
-
- private void registerForPreDestroy(final Endpoint ep)
- {
- final PreDestroyHolder holder = (PreDestroyHolder)
ep.getAttachment(PreDestroyHolder.class);
- if (holder != null)
- {
- synchronized (this.preDestroyRegistry)
- {
- if (!this.preDestroyRegistry.contains(holder))
- {
- this.preDestroyRegistry.add(holder);
- }
- }
- ep.removeAttachment(PreDestroyHolder.class);
- }
- }
-
- public final void destroy()
- {
- synchronized (this.preDestroyRegistry)
- {
- for (final PreDestroyHolder holder : this.preDestroyRegistry)
- {
- try
- {
- final Object targetBean = holder.getObject();
- InjectionHelper.callPreDestroyMethod(targetBean);
- }
- catch (Exception exception)
- {
- NettyHttpServerCallbackHandler.LOGGER.error(exception.getMessage(),
exception);
- }
- }
- this.preDestroyRegistry.clear();
- this.preDestroyRegistry = null;
- }
- }
-
-}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -1,333 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.ws.core.jaxws.spi.http;
-
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFuture;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.http.Cookie;
-import org.jboss.netty.handler.codec.http.CookieDecoder;
-import org.jboss.netty.handler.codec.http.CookieEncoder;
-import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
-import org.jboss.netty.handler.codec.http.HttpHeaders;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.codec.http.HttpResponseStatus;
-import org.jboss.netty.handler.codec.http.HttpVersion;
-import org.jboss.ws.Constants;
-import org.jboss.ws.core.client.transport.NettyTransportOutputStream;
-import org.jboss.wsf.spi.invocation.InvocationContext;
-
-/**
- * TODO: javadoc
- *
- * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
- */
-final class NettyInvocationHandler extends SimpleChannelUpstreamHandler
-{
- private static final Logger LOG = Logger.getLogger(NettyInvocationHandler.class);
-
- private final List<NettyHttpServerCallbackHandler> callbacks = new
LinkedList<NettyHttpServerCallbackHandler>();
-
- private final Lock lock = new ReentrantLock();
-
- public NettyInvocationHandler()
- {
- super();
- }
-
- @Override
- public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
- {
- // HERE: Add all accepted channels to the group
- // so that they are closed properly on shutdown
- // If the added channel is closed before shutdown,
- // it will be removed from the group automatically.
- NettyHttpServer.channelGroup.add(ctx.getChannel());
- }
-
- public boolean hasMoreCallbacks()
- {
- return this.callbacks.size() > 0;
- }
-
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception
- {
- HttpRequest request = (HttpRequest) e.getMessage();
- ChannelBuffer content = request.getContent();
- OutputStream baos = new ByteArrayOutputStream();
- OutputStream outputStream = new BufferedOutputStream(baos);
- Integer statusCode = null;
-
- InvocationContext invCtx = new InvocationContext();
- Map<String, List<String>> requestHeaders = new HashMap<String,
List<String>>();
- Map<String, List<String>> responseHeaders = new HashMap<String,
List<String>>();
- invCtx.setProperty(Constants.NETTY_REQUEST_HEADERS, requestHeaders);
- invCtx.setProperty(Constants.NETTY_RESPONSE_HEADERS, responseHeaders);
- for (String headerName : request.getHeaderNames())
- {
- requestHeaders.put(headerName, request.getHeaders(headerName));
- }
- try
- {
- String requestPath = request.getUri();
- int paramIndex = requestPath.indexOf('?');
- if (paramIndex != -1)
- {
- requestPath = requestPath.substring(0, paramIndex);
- }
- String httpMethod = request.getMethod().getName();
- statusCode = handle(requestPath, httpMethod, getInputStream(content),
outputStream, invCtx);
- }
- catch (Throwable t)
- {
- statusCode = 500;
- LOG.error(t);
- }
- finally
- {
- writeResponse(e, request, baos.toString(), statusCode, responseHeaders,
ctx.getChannel());
- }
- }
-
- private InputStream getInputStream(ChannelBuffer content)
- {
- return new ChannelBufferInputStream(content);
- }
-
- private int handle(String requestPath, String httpMethod, InputStream inputStream,
OutputStream outputStream,
- InvocationContext invCtx) throws IOException
- {
- boolean handlerExists = false;
- String handledPath = null;
- requestPath = truncateHostName(requestPath);
- for (NettyHttpServerCallbackHandler handler : this.callbacks)
- {
- handledPath = truncateHostName(handler.getHandledPath());
- if (requestPath.equals(handledPath))
- {
- handlerExists = true;
- if (LOG.isDebugEnabled())
- LOG.debug("Handling request path: " + requestPath);
- return handler.handle(httpMethod, inputStream, outputStream, invCtx);
- }
- }
- if (handlerExists == false)
- LOG.warn("No callback handler registered for path: " + requestPath);
-
- return 500;
- }
-
- private String truncateHostName(String s)
- {
- String retVal = s;
- if (s.startsWith("http"))
- {
- try
- {
- retVal = new URL(s).getPath();
- }
- catch (MalformedURLException mue)
- {
- LOG.error(mue.getMessage(), mue);
- }
- }
-
- while (retVal.endsWith("/"))
- {
- retVal = retVal.substring(0, retVal.length() - 1);
- }
- return retVal;
- }
-
- private void writeResponse(MessageEvent e, HttpRequest request, String content, int
statusCode,
- Map<String, List<String>> responseHeaders, Channel channel) throws
IOException
- {
- // Build the response object.
- HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
getResponseStatus(statusCode));
-
- Iterator<String> iterator = responseHeaders.keySet().iterator();
- String key = null;
- List<String> values = null;
- while (iterator.hasNext())
- {
- key = iterator.next();
- values = responseHeaders.get(key);
- values = removeProhibitedCharacters(values);
- response.setHeader(key, values);
- }
- if (!responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
- {
- response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/xml;
charset=UTF-8");
- response.setHeader(HttpHeaders.Names.CONTENT_LENGTH,
String.valueOf(content.length()));
- response.setContent(ChannelBuffers.copiedBuffer(content, "UTF-8"));
- }
- else
- {
- response.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, "chunked");
- }
-
- String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
- if (cookieString != null)
- {
- CookieDecoder cookieDecoder = new CookieDecoder();
- Set<Cookie> cookies = cookieDecoder.decode(cookieString);
- if (!cookies.isEmpty())
- {
- // Reset the cookies if necessary.
- CookieEncoder cookieEncoder = new CookieEncoder(true);
- for (Cookie cookie : cookies)
- {
- cookieEncoder.addCookie(cookie);
- }
- response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
- }
- }
-
- // Write the response.
- ChannelFuture cf = e.getChannel().write(response);
- if (responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
- {
- NettyTransportOutputStream out = new NettyTransportOutputStream(channel, 1024);
- out.write(content.getBytes("UTF-8"));
- out.close();
- out.getChannelFuture().awaitUninterruptibly();
- }
- else
- {
- cf.awaitUninterruptibly();
- }
- }
-
- private List<String> removeProhibitedCharacters(List<String> values)
- {
- List<String> retVal = new LinkedList<String>();
- for (int i = 0; i < values.size(); i++)
- {
- retVal.add(i, removeProhibitedCharacters(values.get(i)));
- }
-
- return retVal;
- }
-
- private String removeProhibitedCharacters(String s)
- {
- String retVal = s;
-
- retVal = retVal.replace('\r', ' ');
- retVal = retVal.replace('\n', ' ');
-
- return retVal;
- }
-
- private HttpResponseStatus getResponseStatus(int statusCode)
- {
- // TODO:
https://jira.jboss.org/jira/browse/NETTY-233
- if (statusCode == 500)
- return HttpResponseStatus.INTERNAL_SERVER_ERROR;
- if (statusCode == 202)
- return HttpResponseStatus.ACCEPTED;
- if (statusCode == 204)
- return HttpResponseStatus.NO_CONTENT;
-
- return HttpResponseStatus.OK;
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws
Exception
- {
- e.getCause().printStackTrace();
- e.getChannel().close();
- }
-
- public NettyHttpServerCallbackHandler getCallback(String requestPath)
- {
- this.lock.lock();
- try
- {
- for (NettyHttpServerCallbackHandler handler : this.callbacks)
- {
- if (handler.getHandledPath().equals(requestPath))
- return handler;
- }
- }
- finally
- {
- this.lock.unlock();
- }
-
- return null;
- }
-
- public void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
- {
- this.lock.lock();
- try
- {
- this.callbacks.add(callbackHandler);
- }
- finally
- {
- this.lock.unlock();
- }
- }
-
- public void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
- {
- this.lock.lock();
- try
- {
- this.callbacks.remove(callbackHandler);
- callbackHandler.destroy();
- }
- finally
- {
- this.lock.unlock();
- }
- }
-
-}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerFactoryImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
+
+/**
+ * Netty request handler factory for endpoint publish API.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+final class NettyRequestHandlerFactoryImpl implements
NettyRequestHandlerFactory<NettyRequestHandlerImpl>
+{
+
+ private static final NettyRequestHandlerFactory<NettyRequestHandlerImpl>
SINGLETON = new NettyRequestHandlerFactoryImpl();
+
+ private NettyRequestHandlerFactoryImpl()
+ {
+ super();
+ }
+
+ public NettyRequestHandlerImpl newNettyRequestHandler()
+ {
+ return new NettyRequestHandlerImpl();
+ }
+
+ public static NettyRequestHandlerFactory<NettyRequestHandlerImpl> getInstance()
+ {
+ return SINGLETON;
+ }
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyRequestHandlerImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,261 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.jaxws.spi.http;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferInputStream;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.jboss.netty.handler.codec.http.Cookie;
+import org.jboss.netty.handler.codec.http.CookieDecoder;
+import org.jboss.netty.handler.codec.http.CookieEncoder;
+import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
+import org.jboss.netty.handler.codec.http.HttpHeaders;
+import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponse;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.jboss.netty.handler.codec.http.HttpVersion;
+import org.jboss.ws.Constants;
+import org.jboss.ws.core.client.transport.NettyTransportOutputStream;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
+import org.jboss.ws.core.server.netty.AbstractNettyRequestHandler;
+import org.jboss.wsf.spi.invocation.InvocationContext;
+
+/**
+ * Netty request handler for endpoint publish API.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+final class NettyRequestHandlerImpl extends AbstractNettyRequestHandler
+{
+ private static final Logger LOG = Logger.getLogger(NettyRequestHandlerImpl.class);
+
+ public NettyRequestHandlerImpl()
+ {
+ super();
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception
+ {
+ HttpRequest request = (HttpRequest) e.getMessage();
+ ChannelBuffer content = request.getContent();
+ OutputStream baos = new ByteArrayOutputStream();
+ OutputStream outputStream = new BufferedOutputStream(baos);
+ Integer statusCode = null;
+
+ InvocationContext invCtx = new InvocationContext();
+ Map<String, List<String>> requestHeaders = new HashMap<String,
List<String>>();
+ Map<String, List<String>> responseHeaders = new HashMap<String,
List<String>>();
+ invCtx.setProperty(Constants.NETTY_REQUEST_HEADERS, requestHeaders);
+ invCtx.setProperty(Constants.NETTY_RESPONSE_HEADERS, responseHeaders);
+ for (String headerName : request.getHeaderNames())
+ {
+ requestHeaders.put(headerName, request.getHeaders(headerName));
+ }
+ try
+ {
+ String requestPath = request.getUri();
+ int paramIndex = requestPath.indexOf('?');
+ if (paramIndex != -1)
+ {
+ requestPath = requestPath.substring(0, paramIndex);
+ }
+ String httpMethod = request.getMethod().getName();
+ statusCode = handle(requestPath, httpMethod, getInputStream(content),
outputStream, invCtx);
+ }
+ catch (Throwable t)
+ {
+ statusCode = 500;
+ LOG.error(t);
+ }
+ finally
+ {
+ writeResponse(e, request, baos.toString(), statusCode, responseHeaders,
ctx.getChannel());
+ }
+ }
+
+ private InputStream getInputStream(ChannelBuffer content)
+ {
+ return new ChannelBufferInputStream(content);
+ }
+
+ private int handle(String requestPath, String httpMethod, InputStream inputStream,
OutputStream outputStream,
+ InvocationContext invCtx) throws IOException
+ {
+ boolean handlerExists = false;
+ String handledPath = null;
+ requestPath = truncateHostName(requestPath);
+ NettyCallbackHandlerImpl handler =
(NettyCallbackHandlerImpl)this.getCallback(requestPath);
+ if (handler != null)
+ {
+ handlerExists = true;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Handling request path: " + requestPath);
+
+ return handler.handle(httpMethod, inputStream, outputStream, invCtx);
+ }
+ if (handlerExists == false)
+ LOG.warn("No callback handler registered for path: " + requestPath);
+
+ return 500;
+ }
+
+ private String truncateHostName(String s)
+ {
+ String retVal = s;
+ if (s.startsWith("http"))
+ {
+ try
+ {
+ retVal = new URL(s).getPath();
+ }
+ catch (MalformedURLException mue)
+ {
+ LOG.error(mue.getMessage(), mue);
+ }
+ }
+
+ while (retVal.endsWith("/"))
+ {
+ retVal = retVal.substring(0, retVal.length() - 1);
+ }
+ return retVal;
+ }
+
+ private void writeResponse(MessageEvent e, HttpRequest request, String content, int
statusCode,
+ Map<String, List<String>> responseHeaders, Channel channel) throws
IOException
+ {
+ // Build the response object.
+ HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
getResponseStatus(statusCode));
+
+ Iterator<String> iterator = responseHeaders.keySet().iterator();
+ String key = null;
+ List<String> values = null;
+ while (iterator.hasNext())
+ {
+ key = iterator.next();
+ values = responseHeaders.get(key);
+ values = removeProhibitedCharacters(values);
+ response.setHeader(key, values);
+ }
+ if (!responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
+ {
+ response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/xml;
charset=UTF-8");
+ response.setHeader(HttpHeaders.Names.CONTENT_LENGTH,
String.valueOf(content.length()));
+ response.setContent(ChannelBuffers.copiedBuffer(content, "UTF-8"));
+ }
+ else
+ {
+ response.setHeader(HttpHeaders.Names.TRANSFER_ENCODING, "chunked");
+ }
+
+ String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
+ if (cookieString != null)
+ {
+ CookieDecoder cookieDecoder = new CookieDecoder();
+ Set<Cookie> cookies = cookieDecoder.decode(cookieString);
+ if (!cookies.isEmpty())
+ {
+ // Reset the cookies if necessary.
+ CookieEncoder cookieEncoder = new CookieEncoder(true);
+ for (Cookie cookie : cookies)
+ {
+ cookieEncoder.addCookie(cookie);
+ }
+ response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
+ }
+ }
+
+ // Write the response.
+ ChannelFuture cf = e.getChannel().write(response);
+ if (responseHeaders.containsKey(HttpHeaders.Names.CONTENT_TYPE))
+ {
+ NettyTransportOutputStream out = new NettyTransportOutputStream(channel, 1024);
+ out.write(content.getBytes("UTF-8"));
+ out.close();
+ out.getChannelFuture().awaitUninterruptibly();
+ }
+ else
+ {
+ cf.awaitUninterruptibly();
+ }
+ }
+
+ private List<String> removeProhibitedCharacters(List<String> values)
+ {
+ List<String> retVal = new LinkedList<String>();
+ for (int i = 0; i < values.size(); i++)
+ {
+ retVal.add(i, removeProhibitedCharacters(values.get(i)));
+ }
+
+ return retVal;
+ }
+
+ private String removeProhibitedCharacters(String s)
+ {
+ String retVal = s;
+
+ retVal = retVal.replace('\r', ' ');
+ retVal = retVal.replace('\n', ' ');
+
+ return retVal;
+ }
+
+ private HttpResponseStatus getResponseStatus(int statusCode)
+ {
+ // TODO:
https://jira.jboss.org/jira/browse/NETTY-233
+ if (statusCode == 500)
+ return HttpResponseStatus.INTERNAL_SERVER_ERROR;
+ if (statusCode == 202)
+ return HttpResponseStatus.ACCEPTED;
+ if (statusCode == 204)
+ return HttpResponseStatus.NO_CONTENT;
+
+ return HttpResponseStatus.OK;
+ }
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/AbstractNettyRequestHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipelineCoverage;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+/**
+ * Abstract Netty request handler.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:asoldano@redhat.com">Alessio
Soldano</a>
+ */
+@ChannelPipelineCoverage("one")
+public abstract class AbstractNettyRequestHandler extends SimpleChannelUpstreamHandler
+{
+
+ /** Callbacks registry. */
+ private final List<NettyCallbackHandler> callbacks = new
LinkedList<NettyCallbackHandler>();
+ /** Callback registry lock. */
+ private final Lock callbackRegistryLock = new ReentrantLock();
+
+ /**
+ * Constructor.
+ */
+ protected AbstractNettyRequestHandler()
+ {
+ super();
+ }
+
+ /**
+ * Template method implementation.
+ *
+ * @param ctx channel handler context
+ * @param e channel state event
+ */
+ @Override
+ public final void channelOpen(final ChannelHandlerContext ctx, final ChannelStateEvent
e)
+ {
+ // HERE: Add all accepted channels to the group
+ // so that they are closed properly on shutdown
+ // If the added channel is closed before shutdown,
+ // it will be removed from the group automatically.
+ NettyHttpServerImpl.channelGroup.add(ctx.getChannel());
+ }
+
+ /**
+ * Template method implementation.
+ *
+ * @param ctx channel handler context
+ * @param e exception event
+ * @throws Exception if some error occurs
+ */
+ @Override
+ public final void exceptionCaught(final ChannelHandlerContext ctx, final
ExceptionEvent e) throws Exception
+ {
+ e.getCause().printStackTrace();
+ e.getChannel().close();
+ }
+
+ /**
+ * Template method for processing incoming requests.
+ *
+ * @param ctx channel handler context
+ * @param e message event
+ * @throws Exception if some error occurs
+ */
+ @Override
+ public abstract void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception;
+
+ /**
+ * Returns true if request handler have at least one callback registered, false
otherwise.
+ *
+ * @return true if at least one callback is registered, false otherwise
+ */
+ public final boolean hasMoreCallbacks()
+ {
+ this.callbackRegistryLock.lock();
+ try
+ {
+ return this.callbacks.size() > 0;
+ }
+ finally
+ {
+ this.callbackRegistryLock.unlock();
+ }
+ }
+
+ /**
+ * Returns callback handler associated with request path.
+ *
+ * @param requestPath to get handler for
+ * @return callback handler
+ */
+ public final NettyCallbackHandler getCallback(final String requestPath)
+ {
+ this.callbackRegistryLock.lock();
+ try
+ {
+ for (final NettyCallbackHandler handler : this.callbacks)
+ {
+ if (handler.getPath().equals(requestPath))
+ {
+ return handler;
+ }
+ }
+ }
+ finally
+ {
+ this.callbackRegistryLock.unlock();
+ }
+
+ return null;
+ }
+
+ /**
+ * Registers callback.
+ *
+ * @param callback netty callback
+ */
+ public final void registerCallback(final NettyCallbackHandler callback)
+ {
+ this.callbackRegistryLock.lock();
+ try
+ {
+ callback.init();
+ this.callbacks.add(callback);
+ }
+ finally
+ {
+ this.callbackRegistryLock.unlock();
+ }
+ }
+
+ /**
+ * Unregisters callback.
+ *
+ * @param callback netty callback
+ */
+ public final void unregisterCallback(final NettyCallbackHandler callback)
+ {
+ this.callbackRegistryLock.lock();
+ try
+ {
+ this.callbacks.remove(callback);
+ callback.destroy();
+ }
+ finally
+ {
+ this.callbackRegistryLock.unlock();
+ }
+ }
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyCallbackHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty callback handler abstraction.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public interface NettyCallbackHandler
+{
+
+ /**
+ * Template method to initialize callback handler.
+ */
+ void init();
+
+ /**
+ * Returns path callback handler operates on.
+ *
+ * @return callback working path
+ */
+ String getPath();
+
+ /**
+ * Template method to destroy callback handler.
+ */
+ void destroy();
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServer.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,68 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty Http Server abstraction.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public interface NettyHttpServer
+{
+
+ /**
+ * Registers new callback.
+ *
+ * @param callback netty callback
+ */
+ void registerCallback(NettyCallbackHandler callback);
+
+ /**
+ * Registers old callback.
+ *
+ * @param callback netty callback
+ */
+ void unregisterCallback(NettyCallbackHandler callback);
+
+ /**
+ * Returns registered callback associated with request path.
+ *
+ * @param requestPath request path to get associated callback for
+ * @return callback handler
+ */
+ NettyCallbackHandler getCallback(String requestPath);
+
+ /**
+ * Returns true if server has some callbacks registered, false otherwise.
+ *
+ * @return true if callbacks are available, false otherwise
+ */
+ boolean hasMoreCallbacks();
+
+ /**
+ * Returns port this server runs on.
+ *
+ * @return server port
+ */
+ int getPort();
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerFactory.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,81 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Netty based http server factory.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public final class NettyHttpServerFactory
+{
+
+ /**
+ * Servers registry.
+ */
+ static final Map<Integer, NettyHttpServer> SERVERS = new HashMap<Integer,
NettyHttpServer>();
+
+ /**
+ * Constructor.
+ */
+ private NettyHttpServerFactory()
+ {
+ super();
+ }
+
+ /**
+ * Starts Netty based http server on the background if method is called for the first
time,
+ * otherwise returns already existing and running server instance.
+ *
+ * @param port server port
+ * @param requestHandlerFactory request handle factory
+ * @param <T> factory type
+ * @return running Netty based http server
+ */
+ public static <T extends NettyRequestHandlerFactory<?>> NettyHttpServer
getNettyHttpServer(final int port,
+ final T requestHandlerFactory)
+ {
+ if (port <= 0)
+ {
+ throw new IllegalArgumentException("Not positive port value");
+ }
+ if (requestHandlerFactory == null)
+ {
+ throw new NullPointerException("Factory cannot be null");
+ }
+
+ synchronized (NettyHttpServerFactory.SERVERS)
+ {
+ NettyHttpServer server = NettyHttpServerFactory.SERVERS.get(port);
+ if (server == null)
+ {
+ server = new NettyHttpServerImpl(port, requestHandlerFactory);
+ NettyHttpServerFactory.SERVERS.put(port, server);
+ }
+ return server;
+ }
+ }
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyHttpServerImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+import javax.xml.ws.WebServiceException;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
+
+/**
+ * Netty http server implementation.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ * @author <a href="mailto:asoldano@redhat.com">Alessio
Soldano</a>
+ */
+final class NettyHttpServerImpl implements NettyHttpServer, Runnable
+{
+
+ private static final Logger LOG = Logger.getLogger(NettyHttpServerImpl.class);
+
+ private static final long WAIT_PERIOD = 100;
+
+ static final ChannelGroup channelGroup = new
DefaultChannelGroup("NettyHttpServer");
+
+ private final Object instanceLock = new Object();
+
+ private final int port;
+
+ private boolean started;
+
+ private boolean stopped;
+
+ private boolean terminated;
+
+ private ChannelFactory factory;
+
+ private AbstractNettyRequestHandler handler;
+
+ NettyHttpServerImpl(int port, NettyRequestHandlerFactory<?>
nettyRequestHandlerFactory)
+ {
+ super();
+ this.port = port;
+ try
+ {
+ factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
+
+ ServerBootstrap bootstrap = new ServerBootstrap(factory);
+ this.handler = nettyRequestHandlerFactory.newNettyRequestHandler();
+ WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
+ channelPipelineFactory.setRequestHandler(this.handler);
+ bootstrap.setPipelineFactory(channelPipelineFactory);
+ bootstrap.setOption("child.tcpNoDelay", true);
+ bootstrap.setOption("child.keepAlive", true);
+ // Bind and start to accept incoming connections.
+ Channel c = bootstrap.bind(new InetSocketAddress(this.port));
+ channelGroup.add(c);
+ // forking Netty server
+ Thread t = new Thread(this, "NettyHttpServer listening on port " +
port);
+ t.setDaemon(true);
+ t.start();
+ // registering shutdown hook
+ Runnable shutdownHook = new NettyHttpServerShutdownHook(this);
+ Runtime.getRuntime().addShutdownHook(
+ new Thread(shutdownHook, "NettyHttpServerShutdownHook(port=" +
port + ")"));
+ if (LOG.isDebugEnabled())
+ LOG.debug("Netty http server started on port: " + this.port);
+ }
+ catch (Exception e)
+ {
+ LOG.warn(e.getMessage(), e);
+ throw new WebServiceException(e.getMessage(), e);
+ }
+ }
+
+ public final void registerCallback(final NettyCallbackHandler callback)
+ {
+ if (callback == null)
+ throw new IllegalArgumentException("Null callback handler");
+
+ this.ensureUpAndRunning();
+
+ this.handler.registerCallback(callback);
+ }
+
+ public final void unregisterCallback(final NettyCallbackHandler callback)
+ {
+ if (callback == null)
+ throw new IllegalArgumentException("Null callback handler");
+
+ this.ensureUpAndRunning();
+
+ try
+ {
+ this.handler.unregisterCallback(callback);
+ }
+ finally
+ {
+ if (!this.hasMoreCallbacks())
+ {
+ this.terminate();
+ }
+ }
+ }
+
+ public final NettyCallbackHandler getCallback(final String requestPath)
+ {
+ if (requestPath == null)
+ throw new IllegalArgumentException("Null request path");
+
+ this.ensureUpAndRunning();
+
+ return this.handler.getCallback(requestPath);
+ }
+
+ public final boolean hasMoreCallbacks()
+ {
+ this.ensureUpAndRunning();
+
+ return this.handler.hasMoreCallbacks();
+ }
+
+ public final int getPort()
+ {
+ this.ensureUpAndRunning();
+
+ return this.port;
+ }
+
+ private void ensureUpAndRunning()
+ {
+ synchronized (this.instanceLock)
+ {
+ if (this.stopped)
+ throw new IllegalStateException("Server is down");
+ }
+ }
+
+ public final void run()
+ {
+ synchronized (this.instanceLock)
+ {
+ if (this.started)
+ return;
+
+ this.started = true;
+
+ while (this.stopped == false)
+ {
+ try
+ {
+ this.instanceLock.wait(WAIT_PERIOD);
+ }
+ catch (InterruptedException ie)
+ {
+ LOG.warn(ie.getMessage(), ie);
+ }
+ }
+ try
+ {
+ //Close all connections and server sockets.
+ channelGroup.close().awaitUninterruptibly();
+ //Shutdown the selector loop (boss and worker).
+ if (factory != null)
+ {
+ factory.releaseExternalResources();
+ }
+ }
+ finally
+ {
+ LOG.debug("terminated");
+ this.terminated = true;
+ }
+ }
+ }
+
+ public final void terminate()
+ {
+ synchronized (this.instanceLock)
+ {
+ if (this.stopped == true)
+ return;
+
+ this.stopped = true;
+ LOG.debug("termination forced");
+ while (this.terminated == false)
+ {
+ try
+ {
+ LOG.debug("waiting for termination");
+ this.instanceLock.wait(WAIT_PERIOD);
+ }
+ catch (InterruptedException ie)
+ {
+ LOG.warn(ie.getMessage(), ie);
+ }
+ }
+ synchronized (NettyHttpServerFactory.SERVERS)
+ {
+ NettyHttpServerFactory.SERVERS.remove(port);
+ }
+ }
+ }
+
+ private static final class NettyHttpServerShutdownHook implements Runnable
+ {
+
+ private final NettyHttpServerImpl nettyHttpServer;
+
+ private NettyHttpServerShutdownHook(final NettyHttpServerImpl nettyHttpServer)
+ {
+ super();
+
+ this.nettyHttpServer = nettyHttpServer;
+ }
+
+ public void run()
+ {
+ this.nettyHttpServer.terminate();
+ }
+
+ }
+
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/netty/NettyRequestHandlerFactory.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.core.server.netty;
+
+/**
+ * Netty request handler factory.
+ *
+ * @param <T> netty request handler type
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public interface NettyRequestHandlerFactory<T extends AbstractNettyRequestHandler>
+{
+
+ /**
+ * Creates new Netty request handler instance.
+ * @return handler instance
+ */
+ T newNettyRequestHandler();
+
+}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsInvocationHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -1,220 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.ws.extensions.wsrm.transport.backchannel;
-
-import java.net.URL;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBufferInputStream;
-import org.jboss.netty.channel.ChannelFuture;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipelineCoverage;
-import org.jboss.netty.channel.ChannelStateEvent;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
-import org.jboss.netty.handler.codec.http.Cookie;
-import org.jboss.netty.handler.codec.http.CookieDecoder;
-import org.jboss.netty.handler.codec.http.CookieEncoder;
-import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
-import org.jboss.netty.handler.codec.http.HttpHeaders;
-import org.jboss.netty.handler.codec.http.HttpRequest;
-import org.jboss.netty.handler.codec.http.HttpResponse;
-import org.jboss.netty.handler.codec.http.HttpResponseStatus;
-import org.jboss.netty.handler.codec.http.HttpVersion;
-import org.jboss.ws.extensions.wsrm.transport.RMMessage;
-import org.jboss.ws.extensions.wsrm.transport.RMUnMarshaller;
-
-/**
- * TODO: Add comment
- *
- * @author richard.opalka(a)jboss.com
- * @author alessio.soldano(a)jboss.com
- *
- * @since Nov 20, 2007
- */
-@ChannelPipelineCoverage("one")
-public final class RMBackPortsInvocationHandler extends SimpleChannelUpstreamHandler
-{
- private static final Logger LOG =
Logger.getLogger(RMBackPortsInvocationHandler.class);
- private final List<RMCallbackHandler> callbacks = new
LinkedList<RMCallbackHandler>();
- private final Lock lock = new ReentrantLock();
-
-
- public RMBackPortsInvocationHandler()
- {
- }
-
- @Override
- public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
- {
- // HERE: Add all accepted channels to the group
- // so that they are closed properly on shutdown
- // If the added channel is closed before shutdown,
- // it will be removed from the group automatically.
- RMBackPortsServer.channelGroup.add(ctx.getChannel());
- }
-
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception
- {
- HttpRequest request = (HttpRequest)e.getMessage();
- ChannelBuffer content = request.getContent();
-
- Map<String, Object> requestHeaders = new HashMap<String, Object>();
- for (String headerName : request.getHeaderNames())
- {
- requestHeaders.put(headerName, request.getHeaders(headerName));
- }
- boolean error = false;
- try
- {
- String requestPath = new URL(request.getUri()).getPath();
- RMMessage message =
(RMMessage)RMUnMarshaller.getInstance().read(content.readable() ? new
ChannelBufferInputStream(content) : null, requestHeaders);
- handle(requestPath, message);
- }
- catch (Throwable t)
- {
- error = true;
- LOG.error("Error decoding request to the backport", t);
- }
- finally
- {
- writeResponse(e, request, error);
- }
- }
-
-
- private void handle(String requestPath, RMMessage message)
- {
- this.lock.lock();
- try
- {
- boolean handlerExists = false;
- for (RMCallbackHandler handler : this.callbacks)
- {
- if (handler.getHandledPath().equals(requestPath))
- {
- handlerExists = true;
- if (LOG.isDebugEnabled())
- LOG.debug("Handling request path: " + requestPath);
- handler.handle(message);
- break;
- }
- }
- if (handlerExists == false)
- LOG.warn("No callback handler registered for path: " +
requestPath);
- }
- finally
- {
- this.lock.unlock();
- }
- }
-
- private void writeResponse(MessageEvent e, HttpRequest request, boolean error)
- {
- // Build the response object.
- HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, error ?
HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.NO_CONTENT);
- response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain;
charset=UTF-8");
-
- String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
- if (cookieString != null)
- {
- CookieDecoder cookieDecoder = new CookieDecoder();
- Set<Cookie> cookies = cookieDecoder.decode(cookieString);
- if (!cookies.isEmpty())
- {
- // Reset the cookies if necessary.
- CookieEncoder cookieEncoder = new CookieEncoder(true);
- for (Cookie cookie : cookies)
- {
- cookieEncoder.addCookie(cookie);
- }
- response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
- }
- }
-
- // Write the response.
- ChannelFuture cf = e.getChannel().write(response);
- cf.awaitUninterruptibly();
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws
Exception
- {
- e.getCause().printStackTrace();
- e.getChannel().close();
- }
-
- public RMCallbackHandler getCallback(String requestPath)
- {
- this.lock.lock();
- try
- {
- for (RMCallbackHandler handler : this.callbacks)
- {
- if (handler.getHandledPath().equals(requestPath))
- return handler;
- }
- }
- finally
- {
- this.lock.unlock();
- }
-
- return null;
- }
-
- public void registerCallback(RMCallbackHandler callbackHandler)
- {
- this.lock.lock();
- try
- {
- this.callbacks.add(callbackHandler);
- }
- finally
- {
- this.lock.unlock();
- }
- }
-
- public void unregisterCallback(RMCallbackHandler callbackHandler)
- {
- this.lock.lock();
- try
- {
- this.callbacks.remove(callbackHandler);
- }
- finally
- {
- this.lock.unlock();
- }
- }
-}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMBackPortsServer.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -1,233 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.jboss.ws.extensions.wsrm.transport.backchannel;
-
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executors;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import org.jboss.logging.Logger;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.group.ChannelGroup;
-import org.jboss.netty.channel.group.DefaultChannelGroup;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.jboss.ws.core.client.transport.WSServerPipelineFactory;
-import org.jboss.ws.extensions.wsrm.api.RMException;
-
-/**
- * Back ports server used by addressable clients
- *
- * @author richard.opalka(a)jboss.com
- * @author alessio.soldano(a)jboss.com
- *
- * @since Nov 20, 2007
- */
-public final class RMBackPortsServer implements Runnable
-{
- private static final Logger LOG = Logger.getLogger(RMBackPortsServer.class);
- private static final Lock CLASS_LOCK = new ReentrantLock();
- private static final long WAIT_PERIOD = 100;
- private static RMBackPortsServer INSTANCE;
- static final ChannelGroup channelGroup = new
DefaultChannelGroup("rmBackPortsServer");
-
- private final Object instanceLock = new Object();
- private final String scheme;
- private final String host;
- private final int port;
- private RMBackPortsInvocationHandler handler;
- private boolean started;
- private boolean stopped;
- private boolean terminated;
- private ChannelFactory factory;
-
- public final void registerCallback(RMCallbackHandler callbackHandler)
- {
- this.handler.registerCallback(callbackHandler);
- }
-
- public final void unregisterCallback(RMCallbackHandler callbackHandler)
- {
- this.handler.unregisterCallback(callbackHandler);
- }
-
- public final RMCallbackHandler getCallback(String requestPath)
- {
- return this.handler.getCallback(requestPath);
- }
-
- private RMBackPortsServer(String scheme, String host, int port) throws RMException
- {
- super();
- this.scheme = scheme;
- this.host = host;
- this.port = port;
- try
- {
- factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
-
- ServerBootstrap bootstrap = new ServerBootstrap(factory);
- this.handler = new RMBackPortsInvocationHandler();
- WSServerPipelineFactory channelPipelineFactory = new WSServerPipelineFactory();
- channelPipelineFactory.setRequestHandler(this.handler);
- bootstrap.setPipelineFactory(channelPipelineFactory);
- bootstrap.setOption("child.tcpNoDelay", true);
- bootstrap.setOption("child.keepAlive", true);
- // Bind and start to accept incoming connections.
- Channel c = bootstrap.bind(new InetSocketAddress(this.port));
- channelGroup.add(c);
- if (LOG.isDebugEnabled())
- LOG.debug("WS-RM Backports Server started on port: " + this.port);
- }
- catch (Exception e)
- {
- LOG.warn(e.getMessage(), e);
- throw new RMException(e.getMessage(), e);
- }
- }
-
- public final String getScheme()
- {
- return this.scheme;
- }
-
- public final String getHost()
- {
- return this.host;
- }
-
- public final int getPort()
- {
- return this.port;
- }
-
- public final void run()
- {
- synchronized (this.instanceLock)
- {
- if (this.started)
- return;
-
- this.started = true;
-
- while (this.stopped == false)
- {
- try
- {
- this.instanceLock.wait(WAIT_PERIOD);
- LOG.debug("serving requests");
- }
- catch (InterruptedException ie)
- {
- LOG.warn(ie.getMessage(), ie);
- }
- }
- try
- {
- //Close all connections and server sockets.
- channelGroup.close().awaitUninterruptibly();
- //Shutdown the selector loop (boss and worker).
- if (factory != null)
- {
- factory.releaseExternalResources();
- }
- }
- finally
- {
- LOG.debug("terminated");
- this.terminated = true;
- }
- }
- }
-
- public final void terminate()
- {
- synchronized (this.instanceLock)
- {
- if (this.stopped == true)
- return;
-
- this.stopped = true;
- LOG.debug("termination forced");
- while (this.terminated == false)
- {
- try
- {
- LOG.debug("waiting for termination");
- this.instanceLock.wait(WAIT_PERIOD);
- }
- catch (InterruptedException ie)
- {
- LOG.warn(ie.getMessage(), ie);
- }
- }
- }
- }
-
- /**
- * Starts back ports server on the background if method is called for the first time
- * @param scheme protocol
- * @param host hostname
- * @param port port
- * @return WS-RM back ports server
- * @throws RMException
- */
- public static RMBackPortsServer getInstance(String scheme, String host, int port)
throws RMException
- {
- CLASS_LOCK.lock();
- try
- {
- if (INSTANCE == null)
- {
- INSTANCE = new RMBackPortsServer(scheme, host, (port == -1) ? 80 : port);
- // forking back ports server
- Thread t = new Thread(INSTANCE, "RMBackPortsServer");
- t.setDaemon(true);
- t.start();
- // registering shutdown hook
- final RMBackPortsServer server = INSTANCE;
- Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
- public void run()
- {
- server.terminate();
- }
- }, "RMBackPortsServerShutdownHook"));
- }
- else
- {
- boolean schemeEquals = INSTANCE.getScheme().equals(scheme);
- boolean hostEquals = INSTANCE.getHost().equals(host);
- boolean portEquals = INSTANCE.getPort() == ((port == -1) ? 80 : port);
- if ((schemeEquals == false) || (hostEquals == false) || (portEquals ==
false))
- throw new IllegalArgumentException();
- }
- return INSTANCE;
- }
- finally
- {
- CLASS_LOCK.unlock();
- }
- }
-
-}
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandler.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -21,6 +21,7 @@
*/
package org.jboss.ws.extensions.wsrm.transport.backchannel;
+import org.jboss.ws.core.server.netty.NettyCallbackHandler;
import org.jboss.ws.extensions.wsrm.transport.RMMessage;
import org.jboss.ws.extensions.wsrm.transport.RMUnassignedMessageListener;
@@ -31,9 +32,8 @@
*
* @since Nov 21, 2007
*/
-public interface RMCallbackHandler
+public interface RMCallbackHandler extends NettyCallbackHandler
{
- String getHandledPath();
void handle(RMMessage message);
RMMessage getMessage(String messageId);
Throwable getFault(String messageId);
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerFactory.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -25,6 +25,9 @@
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
+import org.jboss.ws.core.server.netty.NettyHttpServer;
+import org.jboss.ws.core.server.netty.NettyHttpServerFactory;
+
/**
* Callback factory
*
@@ -34,7 +37,7 @@
*/
public final class RMCallbackHandlerFactory
{
- private static RMBackPortsServer server;
+ private static NettyHttpServer server;
private static Lock lock = new ReentrantLock();
private RMCallbackHandlerFactory()
@@ -49,9 +52,9 @@
{
if (server == null)
{
- server = RMBackPortsServer.getInstance(backPort.getScheme(),
backPort.getHost(), backPort.getPort());
+ server = NettyHttpServerFactory.getNettyHttpServer(backPort.getPort(),
RMRequestHandlerFactory.getInstance());
}
- RMCallbackHandler callbackHandler = server.getCallback(backPort.getPath());
+ RMCallbackHandler callbackHandler =
(RMCallbackHandler)server.getCallback(backPort.getPath());
if (callbackHandler == null)
{
callbackHandler = new RMCallbackHandlerImpl(backPort.getPath());
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java 2009-10-12
05:48:22 UTC (rev 10887)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMCallbackHandlerImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -59,13 +59,23 @@
logger.debug("Registered callback handler listening on '" +
handledPath + "' request path");
}
+ public void init()
+ {
+ // does nothing
+ }
+
+ public void destroy()
+ {
+ // does nothing
+ }
+
public Throwable getFault(String messageId)
{
// TODO implement
return null;
}
- public final String getHandledPath()
+ public final String getPath()
{
return this.handledPath;
}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerFactory.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.extensions.wsrm.transport.backchannel;
+
+import org.jboss.ws.core.server.netty.NettyRequestHandlerFactory;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+final class RMRequestHandlerFactory implements
NettyRequestHandlerFactory<RMRequestHandlerImpl>
+{
+ private static final NettyRequestHandlerFactory<RMRequestHandlerImpl> SINGLETON
= new RMRequestHandlerFactory();
+
+ public RMRequestHandlerImpl newNettyRequestHandler()
+ {
+ return new RMRequestHandlerImpl();
+ }
+
+ public static NettyRequestHandlerFactory<RMRequestHandlerImpl> getInstance()
+ {
+ return SINGLETON;
+ }
+}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/extensions/wsrm/transport/backchannel/RMRequestHandlerImpl.java 2009-10-12
13:08:34 UTC (rev 10888)
@@ -0,0 +1,137 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.extensions.wsrm.transport.backchannel;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.logging.Logger;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferInputStream;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.handler.codec.http.Cookie;
+import org.jboss.netty.handler.codec.http.CookieDecoder;
+import org.jboss.netty.handler.codec.http.CookieEncoder;
+import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
+import org.jboss.netty.handler.codec.http.HttpHeaders;
+import org.jboss.netty.handler.codec.http.HttpRequest;
+import org.jboss.netty.handler.codec.http.HttpResponse;
+import org.jboss.netty.handler.codec.http.HttpResponseStatus;
+import org.jboss.netty.handler.codec.http.HttpVersion;
+import org.jboss.ws.core.server.netty.AbstractNettyRequestHandler;
+import org.jboss.ws.extensions.wsrm.transport.RMMessage;
+import org.jboss.ws.extensions.wsrm.transport.RMUnMarshaller;
+
+/**
+ * RM backports server request handler.
+ *
+ * @author richard.opalka(a)jboss.com
+ * @author alessio.soldano(a)jboss.com
+ */
+public final class RMRequestHandlerImpl extends AbstractNettyRequestHandler
+{
+ private static final Logger LOG = Logger.getLogger(RMRequestHandlerImpl.class);
+
+ /**
+ * Constructor.
+ */
+ public RMRequestHandlerImpl()
+ {
+ super();
+ }
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception
+ {
+ HttpRequest request = (HttpRequest)e.getMessage();
+ ChannelBuffer content = request.getContent();
+
+ Map<String, Object> requestHeaders = new HashMap<String, Object>();
+ for (String headerName : request.getHeaderNames())
+ {
+ requestHeaders.put(headerName, request.getHeaders(headerName));
+ }
+ boolean error = false;
+ try
+ {
+ String requestPath = new URL(request.getUri()).getPath();
+ RMMessage message =
(RMMessage)RMUnMarshaller.getInstance().read(content.readable() ? new
ChannelBufferInputStream(content) : null, requestHeaders);
+ handle(requestPath, message);
+ }
+ catch (Throwable t)
+ {
+ error = true;
+ LOG.error("Error decoding request to the backport", t);
+ }
+ finally
+ {
+ writeResponse(e, request, error);
+ }
+ }
+
+
+ private void handle(String requestPath, RMMessage message)
+ {
+ RMCallbackHandler handler = (RMCallbackHandler)this.getCallback(requestPath);
+ if (handler != null)
+ {
+ handler.handle(message);
+ }
+ else
+ {
+ LOG.warn("No callback handler registered for path: " + requestPath);
+ }
+ }
+
+ private void writeResponse(MessageEvent e, HttpRequest request, boolean error)
+ {
+ // Build the response object.
+ HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, error ?
HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.NO_CONTENT);
+ response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/plain;
charset=UTF-8");
+
+ String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
+ if (cookieString != null)
+ {
+ CookieDecoder cookieDecoder = new CookieDecoder();
+ Set<Cookie> cookies = cookieDecoder.decode(cookieString);
+ if (!cookies.isEmpty())
+ {
+ // Reset the cookies if necessary.
+ CookieEncoder cookieEncoder = new CookieEncoder(true);
+ for (Cookie cookie : cookies)
+ {
+ cookieEncoder.addCookie(cookie);
+ }
+ response.addHeader(HttpHeaders.Names.SET_COOKIE, cookieEncoder.encode());
+ }
+ }
+
+ // Write the response.
+ ChannelFuture cf = e.getChannel().write(response);
+ cf.awaitUninterruptibly();
+ }
+
+}