Author: richard.opalka(a)jboss.com
Date: 2009-10-09 09:07:52 -0400 (Fri, 09 Oct 2009)
New Revision: 10873
Added:
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/NettyHttpServerCallbackHandler.java
Removed:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/EndpointImpl.java
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/NettyHttpServerFactory.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/UsecasesTestCase.java
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/endpoints/Endpoint1Impl.java
Log:
[JBWS-2674][JBWS-2754] removing useless start method, extending test + other refactorings
(WIP)
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/EndpointImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/EndpointImpl.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/EndpointImpl.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -45,7 +45,7 @@
import org.jboss.ws.core.jaxws.wsaddressing.EndpointReferenceUtil;
import org.jboss.wsf.spi.SPIProvider;
import org.jboss.wsf.spi.SPIProviderResolver;
-import org.jboss.wsf.spi.deployment.ArchiveDeployment;
+import org.jboss.wsf.spi.deployment.Deployment;
import org.jboss.wsf.spi.http.HttpContext;
import org.jboss.wsf.spi.http.HttpServer;
import org.jboss.wsf.spi.http.HttpServerFactory;
@@ -56,15 +56,13 @@
/**
* A Web service endpoint implementation.
*
- * @author Thomas.Diesler(a)jboss.com
- * @since 07-Jul-2006
+ * @author <a href="mailto:tdiesler@redhat.com">Thomas Diesler</a>
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
*/
public class EndpointImpl extends Endpoint
{
- // provide logging
- private final Logger log = Logger.getLogger(EndpointImpl.class);
- // The permission to publish an endpoint
+ private static final Logger log = Logger.getLogger(EndpointImpl.class);
private static final WebServicePermission ENDPOINT_PUBLISH_PERMISSION = new
WebServicePermission("publishEndpoint");
private Object implementor;
@@ -77,7 +75,7 @@
private boolean isPublished;
private boolean isDestroyed;
private URI address;
- private ArchiveDeployment dep;
+ private Deployment dep;
public EndpointImpl(String bindingId, Object implementor, WebServiceFeature[]
features)
{
@@ -128,8 +126,6 @@
// Create and start the HTTP server
SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
HttpServer httpServer =
spiProvider.getSPI(HttpServerFactory.class).getHttpServer();
- httpServer.setProperties(properties);
- httpServer.start();
String path = address.getPath();
String contextRoot = "/" + new StringTokenizer(path,
"/").nextToken();
@@ -148,7 +144,10 @@
@Override
public void publish(Object context)
{
- log.debug("publish: " + context);
+ if (context == null)
+ throw new IllegalArgumentException("Null context");
+
+ log.debug("publishing endpoint " + this + " to " + context);
if (isDestroyed)
throw new IllegalStateException("Endpoint already destroyed");
@@ -156,24 +155,6 @@
// Check with the security manger
checkPublishEndpointPermission();
- /* Check if we are standalone
- boolean isStandalone;
- try
- {
- SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
- spiProvider.getSPI(ServerConfigFactory.class).getServerConfig();
- isStandalone = false;
- }
- catch (Exception ex)
- {
- // ignore, there should be no ServerConfigFactory in VM
- isStandalone = true;
- }
-
- if (isStandalone == false)
- throw new IllegalStateException("Cannot publish endpoint from within
server");
- */
-
if (context instanceof HttpContext)
{
serverContext = (HttpContext)context;
@@ -185,6 +166,10 @@
httpServer.publish(serverContext, this);
isPublished = true;
}
+ else
+ {
+ throw new UnsupportedOperationException("Cannot handle contexts of type:
" + context);
+ }
}
private static URI getAddressFromConfigAndContext(HttpContext context)
@@ -245,7 +230,7 @@
@Override
public void setMetadata(List<Source> list)
{
- log.info("Ignore metadata, not implemented");
+ log.info("Ignore metadata, not implemented"); // TODO:
this.metadata = list;
}
@@ -258,7 +243,7 @@
@Override
public void setExecutor(Executor executor)
{
- log.info("Ignore executor, not implemented");
+ log.info("Ignore executor, not implemented"); // TODO
this.executor = executor;
}
@@ -300,7 +285,8 @@
{
if (isDestroyed || !isPublished)
throw new WebServiceException("Cannot get EPR for an unpubblished or
already destroyed endpoint!");
- if (getBinding() instanceof HTTPBinding )
+
+ if (getBinding() instanceof HTTPBinding)
{
throw new UnsupportedOperationException("Cannot get epr when using the
XML/HTTP binding");
}
@@ -313,6 +299,7 @@
for (Element el : referenceParameters)
builder.referenceParameter(el);
}
+
return EndpointReferenceUtil.transform(clazz, builder.build());
}
@@ -331,8 +318,9 @@
return this.address.getPort();
}
- public String getName()
+ public String getPathWithoutContext()
{
+ // TODO: optimize this method
StringTokenizer st = new StringTokenizer(this.getPath(), "/");
st.nextToken();
StringBuilder sb = new StringBuilder();
@@ -346,12 +334,15 @@
return sb.toString();
}
- public void setDeployment(ArchiveDeployment dep)
+ public void setDeployment(final Deployment dep)
{
- this.dep = dep;
+ if (this.dep == null)
+ {
+ this.dep = dep;
+ }
}
- public ArchiveDeployment getDeployment()
+ public Deployment getDeployment()
{
return this.dep;
}
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -1,204 +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 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 NettyCallbackHandler(String path, String context, String endpointClass)
- {
- super();
- this.initRegistry();
- this.initEndpoint(context, endpointClass);
- 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(String contextPath, String servletName)
- {
- final EndpointResolver resolver = new WebAppResolver(contextPath, servletName);
- this.endpoint = epRegistry.resolve(resolver);
-
- if (this.endpoint == null)
- {
- ObjectName oname = ObjectNameFactory.create(Endpoint.SEPID_DOMAIN +
":" +
- Endpoint.SEPID_PROPERTY_CONTEXT + "=" + contextPath + ","
+
- Endpoint.SEPID_PROPERTY_ENDPOINT + "=" + servletName
- );
- 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"))
- {
- doPost(inputStream, outputStream, invCtx);
- statusCode = (Integer)invCtx.getProperty(Constants.NETTY_STATUS_CODE);
- }
- else if (method.equals("GET"))
- {
- doGet(inputStream, outputStream, invCtx);
- }
- else
- {
- throw new WSException("Unsupported HTTP method: " + method);
- }
- }
- catch(Exception e)
- {
- logger.error(e.getMessage(), e);
- statusCode = 500;
- }
-
- return statusCode == null ? 200 : statusCode;
- }
-
- public final String getHandledPath()
- {
- return this.handledPath;
- }
-
- public void doGet(InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx) throws IOException
- {
- try
- {
- EndpointAssociation.setEndpoint(endpoint);
- RequestHandler requestHandler = endpoint.getRequestHandler();
- requestHandler.handleWSDLRequest(endpoint, outputStream, invCtx);
- }
- finally
- {
- EndpointAssociation.removeEndpoint();
- }
- }
-
- public void doPost(InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx) throws IOException
- {
- try
- {
- EndpointAssociation.setEndpoint(endpoint);
- RequestHandler requestHandler = endpoint.getRequestHandler();
- requestHandler.handleRequest(endpoint, inputStream, outputStream, invCtx);
- }
- finally
- {
- this.registerForPreDestroy(endpoint);
- EndpointAssociation.removeEndpoint();
- }
- }
-
- private void registerForPreDestroy(Endpoint ep)
- {
- 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)
- {
- logger.error(exception.getMessage(), exception);
- }
- }
- this.preDestroyRegistry.clear();
- this.preDestroyRegistry = null;
- }
- }
-
-}
Modified:
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-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -21,144 +21,226 @@
*/
package org.jboss.ws.core.jaxws.spi.http;
-import java.util.LinkedList;
-import java.util.List;
+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.Endpoint;
+import javax.xml.ws.WebServiceException;
-import org.jboss.ws.core.jaxws.spi.EndpointImpl;
-import org.jboss.wsf.common.ResourceLoaderAdapter;
-import org.jboss.wsf.framework.deployment.BackwardCompatibleContextRootDeploymentAspect;
-import org.jboss.wsf.framework.deployment.DeploymentAspectManagerImpl;
-import org.jboss.wsf.framework.deployment.EndpointAddressDeploymentAspect;
-import org.jboss.wsf.framework.deployment.EndpointHandlerDeploymentAspect;
-import org.jboss.wsf.framework.deployment.EndpointLifecycleDeploymentAspect;
-import org.jboss.wsf.framework.deployment.EndpointNameDeploymentAspect;
-import org.jboss.wsf.framework.deployment.EndpointRegistryDeploymentAspect;
-import org.jboss.wsf.framework.deployment.URLPatternDeploymentAspect;
-import org.jboss.wsf.spi.SPIProvider;
-import org.jboss.wsf.spi.SPIProviderResolver;
-import org.jboss.wsf.spi.deployment.AbstractExtensible;
-import org.jboss.wsf.spi.deployment.ArchiveDeployment;
-import org.jboss.wsf.spi.deployment.DeploymentAspect;
-import org.jboss.wsf.spi.deployment.DeploymentModelFactory;
-import org.jboss.wsf.spi.deployment.Deployment.DeploymentType;
-import org.jboss.wsf.spi.http.HttpContext;
-import org.jboss.wsf.spi.http.HttpContextFactory;
-import org.jboss.wsf.spi.http.HttpServer;
-import org.jboss.wsf.stack.jbws.EagerInitializeDeploymentAspect;
-import org.jboss.wsf.stack.jbws.PublishContractDeploymentAspect;
-import org.jboss.wsf.stack.jbws.ServiceEndpointInvokerDeploymentAspect;
-import org.jboss.wsf.stack.jbws.UnifiedMetaDataDeploymentAspect;
+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>
*/
-// TODO: review thread safety
-final class NettyHttpServer extends AbstractExtensible implements HttpServer
+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");
- /** JBossWS SPI provider. */
- private static final SPIProvider SPI_PROVIDER =
SPIProviderResolver.getInstance().getProvider();
- /** JBossWS Http Context factory. */
- private static final HttpContextFactory HTTP_CONTEXT_FACTORY =
NettyHttpServer.SPI_PROVIDER.getSPI(HttpContextFactory.class);
- /** Deployment model factory. */
- private final DeploymentModelFactory deploymentModelFactory;
+ 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;
- public NettyHttpServer()
+ 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());
- // deployment factory
- final SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
- this.deploymentModelFactory = spiProvider.getSPI(DeploymentModelFactory.class);
+ 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 HttpContext createContext(final String contextRoot)
+
+ public final void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
{
- return NettyHttpServer.HTTP_CONTEXT_FACTORY.newHttpContext(this, contextRoot);
+ this.handler.registerCallback(callbackHandler);
}
-
- public void destroy(HttpContext context, Endpoint endpoint)
+
+ public final void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
{
- EndpointImpl epImpl = (EndpointImpl)endpoint;
- RealNettyHttpServer server = RealNettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
- NettyCallbackHandler callback = server.getCallback(epImpl.getPath());
- server.unregisterCallback(callback);
-
- DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
- daManager.setDeploymentAspects(getDeploymentAspects());
- daManager.undeploy(epImpl.getDeployment());
+ this.handler.unregisterCallback(callbackHandler);
+ if (!this.hasMoreCallbacks())
+ {
+ this.terminate();
+ }
}
-
- public void publish(HttpContext context, Endpoint ep)
+
+ public final NettyHttpServerCallbackHandler getCallback(String requestPath)
{
- EndpointImpl epImpl = (EndpointImpl)ep;
- Class<?> endpointClass = this.getEndpointClass(ep);
- String contextRoot = context.getContextRoot();
- ClassLoader loader = endpointClass.getClassLoader();
- // TODO: should we use archive deployment - see META-INF/services ???
- final ArchiveDeployment dep = (ArchiveDeployment)
this.deploymentModelFactory.newDeployment(contextRoot, loader);
- final org.jboss.wsf.spi.deployment.Endpoint endpoint =
this.deploymentModelFactory.newEndpoint(endpointClass.getName());
- endpoint.setShortName(epImpl.getName() + "-port-" + epImpl.getPort()); //
we need to distinguish ports in endpoints registry
- endpoint.setURLPattern(epImpl.getName()); // TODO: rename method
- dep.getService().addEndpoint(endpoint);
- dep.setRootFile(new ResourceLoaderAdapter(loader));
- dep.setRuntimeClassLoader(loader);
- dep.setType(DeploymentType.JAXWS_JSE);
- dep.getService().setContextRoot(contextRoot);
- // TODO: remove this properties hack
- dep.getService().setProperty("protocol", "http");
- dep.getService().setProperty("host", "127.0.0.1");
- dep.getService().setProperty("port", epImpl.getPort());
-
- DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
- daManager.setDeploymentAspects(getDeploymentAspects());
- daManager.deploy(dep);
- epImpl.setDeployment(dep);
-
- RealNettyHttpServer server = RealNettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
- NettyCallbackHandler callback = new NettyCallbackHandler(epImpl.getPath(),
contextRoot, endpoint.getShortName());
- server.registerCallback(callback);
+ return this.handler.getCallback(requestPath);
}
- private List<DeploymentAspect> getDeploymentAspects()
+ public final boolean hasMoreCallbacks()
{
- List<DeploymentAspect> retVal = new LinkedList<DeploymentAspect>();
-
- // TODO: native stack can't use framework classes directly
- retVal.add(new EndpointHandlerDeploymentAspect()); // 13
- retVal.add(new BackwardCompatibleContextRootDeploymentAspect()); // 14
- retVal.add(new URLPatternDeploymentAspect()); // 15
- retVal.add(new EndpointAddressDeploymentAspect()); // 16
- retVal.add(new EndpointNameDeploymentAspect()); // 17
- retVal.add(new UnifiedMetaDataDeploymentAspect()); // 22
- retVal.add(new ServiceEndpointInvokerDeploymentAspect()); // 23
- retVal.add(new PublishContractDeploymentAspect()); // 24
- retVal.add(new EagerInitializeDeploymentAspect()); // 25
- retVal.add(new EndpointRegistryDeploymentAspect()); // 35
- retVal.add(new EndpointLifecycleDeploymentAspect()); // 37
-
- return retVal;
+ return this.handler.hasMoreCallbacks();
}
- public void start()
+ public final String getScheme()
{
- // does nothing
+ 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);
+ }
+ }
+ }
+ }
+
/**
- * Returns implementor class associated with endpoint.
- *
- * @param endpoint to get implementor class from
- * @return implementor class
+ * 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
*/
- private Class<?> getEndpointClass(final Endpoint endpoint)
+ public static NettyHttpServer getInstance(String scheme, String host, int port)
{
- final Object implementor = endpoint.getImplementor();
- return implementor instanceof Class<?> ? (Class<?>) implementor :
implementor.getClass();
+ 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();
+ }
}
-
+
}
Added:
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
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerAdapter.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -0,0 +1,173 @@
+/*
+ * 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.util.LinkedList;
+import java.util.List;
+
+import javax.xml.ws.Endpoint;
+
+import org.jboss.ws.core.jaxws.spi.EndpointImpl;
+import org.jboss.wsf.common.ResourceLoaderAdapter;
+import org.jboss.wsf.framework.deployment.BackwardCompatibleContextRootDeploymentAspect;
+import org.jboss.wsf.framework.deployment.DeploymentAspectManagerImpl;
+import org.jboss.wsf.framework.deployment.EndpointAddressDeploymentAspect;
+import org.jboss.wsf.framework.deployment.EndpointHandlerDeploymentAspect;
+import org.jboss.wsf.framework.deployment.EndpointLifecycleDeploymentAspect;
+import org.jboss.wsf.framework.deployment.EndpointNameDeploymentAspect;
+import org.jboss.wsf.framework.deployment.EndpointRegistryDeploymentAspect;
+import org.jboss.wsf.framework.deployment.URLPatternDeploymentAspect;
+import org.jboss.wsf.spi.SPIProvider;
+import org.jboss.wsf.spi.SPIProviderResolver;
+import org.jboss.wsf.spi.deployment.ArchiveDeployment;
+import org.jboss.wsf.spi.deployment.Deployment;
+import org.jboss.wsf.spi.deployment.DeploymentAspect;
+import org.jboss.wsf.spi.deployment.DeploymentModelFactory;
+import org.jboss.wsf.spi.deployment.Deployment.DeploymentType;
+import org.jboss.wsf.spi.http.HttpContext;
+import org.jboss.wsf.spi.http.HttpContextFactory;
+import org.jboss.wsf.spi.http.HttpServer;
+import org.jboss.wsf.stack.jbws.EagerInitializeDeploymentAspect;
+import org.jboss.wsf.stack.jbws.PublishContractDeploymentAspect;
+import org.jboss.wsf.stack.jbws.ServiceEndpointInvokerDeploymentAspect;
+import org.jboss.wsf.stack.jbws.UnifiedMetaDataDeploymentAspect;
+
+/**
+ * TODO: javadoc
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+// TODO: review thread safety
+final class NettyHttpServerAdapter implements HttpServer
+{
+
+ /** JBossWS SPI provider. */
+ private static final SPIProvider SPI_PROVIDER =
SPIProviderResolver.getInstance().getProvider();
+ /** JBossWS Http Context factory. */
+ private static final HttpContextFactory HTTP_CONTEXT_FACTORY =
NettyHttpServerAdapter.SPI_PROVIDER.getSPI(HttpContextFactory.class);
+ /** Deployment model factory. */
+ private static final DeploymentModelFactory DEPLOYMENT_FACTORY =
NettyHttpServerAdapter.SPI_PROVIDER.getSPI(DeploymentModelFactory.class);
+
+ /**
+ * Constructor.
+ */
+ public NettyHttpServerAdapter()
+ {
+ super();
+ }
+
+ public HttpContext createContext(final String contextRoot)
+ {
+ // TODO: check context is not already registered, throw exception otherwise
+ return NettyHttpServerAdapter.HTTP_CONTEXT_FACTORY.newHttpContext(this,
contextRoot);
+ }
+
+ 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());
+ server.unregisterCallback(callback);
+
+ DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
+ daManager.setDeploymentAspects(getDeploymentAspects());
+ daManager.undeploy(epImpl.getDeployment());
+ }
+
+ public void publish(HttpContext context, Endpoint ep)
+ {
+ EndpointImpl epImpl = (EndpointImpl)ep;
+ String contextRoot = context.getContextRoot();
+ Deployment dep = this.newDeployment(epImpl, contextRoot);
+
+ DeploymentAspectManagerImpl daManager = new DeploymentAspectManagerImpl();
+ daManager.setDeploymentAspects(getDeploymentAspects());
+ daManager.deploy(dep);
+ epImpl.setDeployment(dep);
+
+ NettyHttpServer server = NettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
+ NettyHttpServerCallbackHandler callback = new
NettyHttpServerCallbackHandler(epImpl.getPath(), contextRoot,
this.getEndpointRegistryPath(epImpl));
+ server.registerCallback(callback);
+ }
+
+ private String getEndpointRegistryPath(EndpointImpl endpoint)
+ {
+ // we need to distinguish ports in endpoints registry in JSE environment
+ return endpoint.getPathWithoutContext() + "-port-" + endpoint.getPort();
+ }
+
+ private Deployment newDeployment(EndpointImpl epImpl, String contextRoot)
+ {
+ Class<?> endpointClass = this.getEndpointClass(epImpl);
+ ClassLoader loader = endpointClass.getClassLoader();
+
+ final ArchiveDeployment dep = (ArchiveDeployment)
DEPLOYMENT_FACTORY.newDeployment(contextRoot, loader);
+ final org.jboss.wsf.spi.deployment.Endpoint endpoint =
DEPLOYMENT_FACTORY.newEndpoint(endpointClass.getName());
+ endpoint.setShortName(this.getEndpointRegistryPath(epImpl));
+ endpoint.setURLPattern(epImpl.getPathWithoutContext());
+ dep.getService().addEndpoint(endpoint);
+ dep.setRootFile(new ResourceLoaderAdapter(loader));
+ dep.setRuntimeClassLoader(loader);
+ dep.setType(DeploymentType.JAXWS_JSE);
+ dep.getService().setContextRoot(contextRoot);
+
+ // TODO: remove this properties hack
+ dep.getService().setProperty("protocol", "http");
+ dep.getService().setProperty("host", "127.0.0.1");
+ dep.getService().setProperty("port", epImpl.getPort());
+
+ return dep;
+ }
+
+ private List<DeploymentAspect> getDeploymentAspects()
+ {
+ List<DeploymentAspect> retVal = new LinkedList<DeploymentAspect>();
+
+ // TODO: native stack can't use framework classes directly
+ retVal.add(new EndpointHandlerDeploymentAspect()); // 13
+ retVal.add(new BackwardCompatibleContextRootDeploymentAspect()); // 14
+ retVal.add(new URLPatternDeploymentAspect()); // 15
+ retVal.add(new EndpointAddressDeploymentAspect()); // 16
+ retVal.add(new EndpointNameDeploymentAspect()); // 17
+ retVal.add(new UnifiedMetaDataDeploymentAspect()); // 22
+ retVal.add(new ServiceEndpointInvokerDeploymentAspect()); // 23
+ retVal.add(new PublishContractDeploymentAspect()); // 24
+ retVal.add(new EagerInitializeDeploymentAspect()); // 25
+ retVal.add(new EndpointRegistryDeploymentAspect()); // 35
+ retVal.add(new EndpointLifecycleDeploymentAspect()); // 37
+
+ return retVal;
+ }
+
+ /**
+ * Returns implementor class associated with endpoint.
+ *
+ * @param endpoint to get implementor class from
+ * @return implementor class
+ */
+ private Class<?> getEndpointClass(final Endpoint endpoint)
+ {
+ final Object implementor = endpoint.getImplementor();
+ return implementor instanceof Class<?> ? (Class<?>) implementor :
implementor.getClass();
+ }
+
+}
Added:
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
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerCallbackHandler.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -0,0 +1,205 @@
+/*
+ * 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
+{
+ 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"))
+ {
+ doPost(inputStream, outputStream, invCtx);
+ statusCode = (Integer)invCtx.getProperty(Constants.NETTY_STATUS_CODE);
+ }
+ else if (method.equals("GET"))
+ {
+ doGet(inputStream, outputStream, invCtx);
+ }
+ else
+ {
+ throw new WSException("Unsupported HTTP method: " + method);
+ }
+ }
+ catch(Exception e)
+ {
+ logger.error(e.getMessage(), e);
+ statusCode = 500;
+ }
+
+ return statusCode == null ? 200 : statusCode;
+ }
+
+ public final String getHandledPath()
+ {
+ return this.handledPath;
+ }
+
+ public void doGet(InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx) throws IOException
+ {
+ try
+ {
+ EndpointAssociation.setEndpoint(endpoint);
+ RequestHandler requestHandler = endpoint.getRequestHandler();
+ requestHandler.handleWSDLRequest(endpoint, outputStream, invCtx);
+ }
+ finally
+ {
+ EndpointAssociation.removeEndpoint();
+ }
+ }
+
+ public void doPost(InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx) throws IOException
+ {
+ try
+ {
+ EndpointAssociation.setEndpoint(endpoint);
+ RequestHandler requestHandler = endpoint.getRequestHandler();
+ requestHandler.handleRequest(endpoint, inputStream, outputStream, invCtx);
+ }
+ finally
+ {
+ this.registerForPreDestroy(endpoint);
+ EndpointAssociation.removeEndpoint();
+ }
+ }
+
+ private void registerForPreDestroy(Endpoint ep)
+ {
+ 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)
+ {
+ logger.error(exception.getMessage(), exception);
+ }
+ }
+ this.preDestroyRegistry.clear();
+ this.preDestroyRegistry = null;
+ }
+ }
+
+}
+
\ No newline at end of file
Modified:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerFactory.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerFactory.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServerFactory.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -32,7 +32,7 @@
public final class NettyHttpServerFactory extends HttpServerFactory
{
- private static final HttpServer NETTY_HTTP_SERVER = new NettyHttpServer();
+ private static final HttpServer NETTY_HTTP_SERVER = new NettyHttpServerAdapter();
/**
* Constructor.
Modified:
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-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -69,7 +69,7 @@
final class NettyInvocationHandler extends SimpleChannelUpstreamHandler
{
private static final Logger LOG = Logger.getLogger(NettyInvocationHandler.class);
- private final List<NettyCallbackHandler> callbacks = new
LinkedList<NettyCallbackHandler>();
+ private final List<NettyHttpServerCallbackHandler> callbacks = new
LinkedList<NettyHttpServerCallbackHandler>();
private final Lock lock = new ReentrantLock();
public NettyInvocationHandler()
@@ -84,7 +84,7 @@
// so that they are closed properly on shutdown
// If the added channel is closed before shutdown,
// it will be removed from the group automatically.
- RealNettyHttpServer.channelGroup.add(ctx.getChannel());
+ NettyHttpServer.channelGroup.add(ctx.getChannel());
}
public boolean hasMoreCallbacks()
@@ -143,7 +143,7 @@
boolean handlerExists = false;
String handledPath = null;
requestPath = truncateHostName(requestPath);
- for (NettyCallbackHandler handler : this.callbacks)
+ for (NettyHttpServerCallbackHandler handler : this.callbacks)
{
handledPath = truncateHostName(handler.getHandledPath());
if (requestPath.equals(handledPath))
@@ -279,12 +279,12 @@
e.getChannel().close();
}
- public NettyCallbackHandler getCallback(String requestPath)
+ public NettyHttpServerCallbackHandler getCallback(String requestPath)
{
this.lock.lock();
try
{
- for (NettyCallbackHandler handler : this.callbacks)
+ for (NettyHttpServerCallbackHandler handler : this.callbacks)
{
if (handler.getHandledPath().equals(requestPath))
return handler;
@@ -298,7 +298,7 @@
return null;
}
- public void registerCallback(NettyCallbackHandler callbackHandler)
+ public void registerCallback(NettyHttpServerCallbackHandler callbackHandler)
{
this.lock.lock();
try
@@ -311,7 +311,7 @@
}
}
- public void unregisterCallback(NettyCallbackHandler callbackHandler)
+ public void unregisterCallback(NettyHttpServerCallbackHandler callbackHandler)
{
this.lock.lock();
try
Deleted:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -1,246 +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 RealNettyHttpServer implements Runnable
-{
-
- private static final Logger LOG = Logger.getLogger(RealNettyHttpServer.class);
- private static final Lock CLASS_LOCK = new ReentrantLock();
- private static final long WAIT_PERIOD = 100;
- private static Map<String, RealNettyHttpServer> SERVERS = new HashMap<String,
RealNettyHttpServer>();
- 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 RealNettyHttpServer(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(NettyCallbackHandler callbackHandler)
- {
- this.handler.registerCallback(callbackHandler);
- }
-
- public final void unregisterCallback(NettyCallbackHandler callbackHandler)
- {
- this.handler.unregisterCallback(callbackHandler);
- if (!this.hasMoreCallbacks())
- {
- this.terminate();
- }
- }
-
- public final NettyCallbackHandler 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 RealNettyHttpServer getInstance(String scheme, String host, int port)
- {
- CLASS_LOCK.lock();
- try
- {
- String key = scheme + "://" + host + ":" + port +
"/";
- RealNettyHttpServer server = SERVERS.get(key);
- if (server == null)
- {
- server = new RealNettyHttpServer(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 RealNettyHttpServer 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/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/UsecasesTestCase.java
===================================================================
---
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/UsecasesTestCase.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/UsecasesTestCase.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -188,7 +188,7 @@
}
catch (Exception e)
{
- log.debug(e.getMessage());
+ assertEquals("Ooops", e.getMessage());
}
}
Modified:
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/endpoints/Endpoint1Impl.java
===================================================================
---
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/endpoints/Endpoint1Impl.java 2009-10-09
12:44:26 UTC (rev 10872)
+++
stack/native/branches/ropalka/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/endpoint/jse/endpoints/Endpoint1Impl.java 2009-10-09
13:07:52 UTC (rev 10873)
@@ -24,6 +24,8 @@
import java.io.IOException;
import javax.activation.DataHandler;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import javax.jws.WebService;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.MTOM;
@@ -44,25 +46,42 @@
{
private int count;
+ private boolean initialized;
public String echo(String input)
{
count++;
return input;
}
+
+ @PostConstruct
+ public void init()
+ {
+ System.out.println("Endpoint initialized: " + this);
+ this.initialized = true;
+ }
+ @PreDestroy
+ public void destroy()
+ {
+ System.out.println("Endpoint destroyed: " + this);
+ }
+
public int getCount()
{
+ this.ensureInit();
return count;
}
public void getException()
{
+ this.ensureInit();
throw new WebServiceException("Ooops");
}
public DHResponse echoDataHandler(DHRequest request)
{
+ this.ensureInit();
DataHandler dataHandler = request.getDataHandler();
try
@@ -84,5 +103,11 @@
DataHandler responseData = new DataHandler("Server data",
"text/plain");
return new DHResponse(responseData);
}
+
+ private void ensureInit()
+ {
+ if (!this.initialized)
+ throw new IllegalStateException();
+ }
}