Author: richard.opalka(a)jboss.com
Date: 2009-09-30 08:28:37 -0400 (Wed, 30 Sep 2009)
New Revision: 10805
Added:
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/NettyInvocationHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/wsf/stack/jbws/RequestHandlerImpl.java
Log:
[JBWS-2674][JBWS-2754] first working prototype (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-09-30
09:01:49 UTC (rev 10804)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/EndpointImpl.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -310,4 +310,20 @@
}
return EndpointReferenceUtil.transform(clazz, builder.build());
}
+
+ public String getPath()
+ {
+ return this.address.getPath();
+ }
+
+ public String getHost()
+ {
+ return this.address.getHost();
+ }
+
+ public int getPort()
+ {
+ return this.address.getPort();
+ }
+
}
Added:
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
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -0,0 +1,194 @@
+/*
+ * 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 java.util.Map;
+
+import javax.management.ObjectName;
+import javax.xml.ws.WebServiceException;
+
+import org.jboss.logging.Logger;
+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 void handle(String method, InputStream inputStream, OutputStream outputStream,
Map<String, Object> requestHeaders) throws IOException
+ {
+ InvocationContext invCtx = new InvocationContext();
+ invCtx.addAttachment(Map.class, requestHeaders);
+ if (method.equals("POST"))
+ {
+ doPost(inputStream, outputStream, invCtx);
+ }
+ else if (method.equals("GET"))
+ {
+ doGet(inputStream, outputStream, invCtx);
+ }
+ else
+ {
+ throw new WSException("Unsupported method: " + method);
+ }
+ }
+
+ 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() // TODO: provide interface method to be called
+ {
+ 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-09-30
09:01:49 UTC (rev 10804)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyHttpServer.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -26,6 +26,7 @@
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;
@@ -104,7 +105,10 @@
daManager.setDeploymentAspects(getDeploymentAspects());
daManager.deploy(dep);
- throw new UnsupportedOperationException("TODO: continue in
implementation");
+ EndpointImpl epImpl = (EndpointImpl)ep;
+ RealNettyHttpServer server = RealNettyHttpServer.getInstance("http",
"localhost", epImpl.getPort());
+ NettyCallbackHandler callback = new NettyCallbackHandler(epImpl.getPath(),
contextRoot, endpoint.getShortName());
+ server.registerCallback(callback);
}
private List<DeploymentAspect> getDeploymentAspects()
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-09-30
09:01:49 UTC (rev 10804)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -26,6 +26,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
@@ -54,12 +56,6 @@
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.wsf.common.injection.InjectionHelper;
-import org.jboss.wsf.common.injection.PreDestroyHolder;
-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;
/**
* TODO: javadoc
@@ -69,12 +65,12 @@
final class NettyInvocationHandler extends SimpleChannelUpstreamHandler
{
private static final Logger LOG = Logger.getLogger(NettyInvocationHandler.class);
+ private final List<NettyCallbackHandler> callbacks = new
LinkedList<NettyCallbackHandler>();
private final Lock lock = new ReentrantLock();
- protected Endpoint endpoint;
- private List<PreDestroyHolder> preDestroyRegistry = new
LinkedList<PreDestroyHolder>();
public NettyInvocationHandler()
{
+ super();
}
@Override
@@ -87,10 +83,14 @@
RealNettyHttpServer.channelGroup.add(ctx.getChannel());
}
+ public boolean hasMoreCallbacks()
+ {
+ return this.callbacks.size() > 0;
+ }
+
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws
Exception
{
- // TODO: distinguish between GET and POST methods
HttpRequest request = (HttpRequest)e.getMessage();
ChannelBuffer content = request.getContent();
OutputStream baos = new ByteArrayOutputStream();
@@ -104,8 +104,15 @@
boolean error = false;
try
{
- String requestPath = new URL(request.getUri()).getPath();
- handle(requestPath, getInputStream(content), outputStream);
+ String requestPath = request.getUri();
+ int paramIndex = requestPath.indexOf('?');
+ if (paramIndex != -1)
+ {
+ requestPath = requestPath.substring(0, paramIndex);
+ }
+ System.out.println("Request path: " + requestPath); // TODO: remove
this line
+ String httpMethod = request.getMethod().getName();
+ handle(requestPath, httpMethod, getInputStream(content), outputStream,
requestHeaders);
}
catch (Throwable t)
{
@@ -114,7 +121,7 @@
}
finally
{
- writeResponse(e, request, error, ChannelBuffers.copiedBuffer(baos.toString(),
"UTF-8"));
+ writeResponse(e, request, error, baos.toString());
}
}
@@ -123,78 +130,52 @@
return new ChannelBufferInputStream(content);
}
- private void handle(String requestPath, InputStream inputStream, OutputStream
outputStream) throws IOException
+ private void handle(String requestPath, String httpMethod, InputStream inputStream,
OutputStream outputStream, Map<String, Object> requestHeaders) throws IOException
{
- this.lock.lock();
- try
+ boolean handlerExists = false;
+ for (NettyCallbackHandler handler : this.callbacks)
{
- try
+ requestPath = truncateHostName(requestPath);
+ System.out.println("Request path 2: " + requestPath);
+ if (requestPath.startsWith(handler.getHandledPath()))
{
- EndpointAssociation.setEndpoint(endpoint);
- RequestHandler requestHandler = endpoint.getRequestHandler();
- requestHandler.handleRequest(endpoint, inputStream, outputStream, new
InvocationContext());
+ handlerExists = true;
+ if (LOG.isDebugEnabled())
+ LOG.debug("Handling request path: " + requestPath);
+ handler.handle(httpMethod, inputStream, outputStream, requestHeaders);
+ break;
}
- finally
- {
- this.registerForPreDestroy(endpoint);
- EndpointAssociation.removeEndpoint();
- }
}
- finally
- {
- this.lock.unlock();
- }
+ if (handlerExists == false)
+ LOG.warn("No callback handler registered for path: " + requestPath);
}
- protected final void postService()
+ private String truncateHostName(String s)
{
- }
-
- public final void destroy() // TODO: provide interface method to be called
- {
- synchronized(this.preDestroyRegistry)
+ if (s.startsWith("http"))
{
- for (final PreDestroyHolder holder : this.preDestroyRegistry)
+ try
{
- try
- {
- final Object targetBean = holder.getObject();
- InjectionHelper.callPreDestroyMethod(targetBean);
- }
- catch (Exception exception)
- {
- LOG.error(exception.getMessage(), exception);
- }
+ return new URL(s).getPath();
}
- this.preDestroyRegistry.clear();
- this.preDestroyRegistry = null;
- }
- }
-
- private void registerForPreDestroy(Endpoint ep)
- {
- PreDestroyHolder holder =
(PreDestroyHolder)ep.getAttachment(PreDestroyHolder.class);
- if (holder != null)
- {
- synchronized(this.preDestroyRegistry)
+ catch (MalformedURLException mue)
{
- if (!this.preDestroyRegistry.contains(holder))
- {
- this.preDestroyRegistry.add(holder);
- }
+ LOG.error(mue.getMessage(), mue);
}
- ep.removeAttachment(PreDestroyHolder.class);
}
+
+ return s;
}
-
- private void writeResponse(MessageEvent e, HttpRequest request, boolean error,
ChannelBuffer content)
+
+ private void writeResponse(MessageEvent e, HttpRequest request, boolean error, String
content)
{
// Build the response object.
HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, error ?
HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.OK);
response.setHeader(HttpHeaders.Names.CONTENT_TYPE, "text/xml;
charset=UTF-8");
if (!error)
{
- response.setContent(content);
+ response.setHeader(HttpHeaders.Names.CONTENT_LENGTH,
String.valueOf(content.length()));
+ response.setContent(ChannelBuffers.copiedBuffer(content, "UTF-8"));
}
String cookieString = request.getHeader(HttpHeaders.Names.COOKIE);
@@ -226,4 +207,50 @@
e.getChannel().close();
}
+ public NettyCallbackHandler getCallback(String requestPath)
+ {
+ this.lock.lock();
+ try
+ {
+ for (NettyCallbackHandler handler : this.callbacks)
+ {
+ if (handler.getHandledPath().equals(requestPath))
+ return handler;
+ }
+ }
+ finally
+ {
+ this.lock.unlock();
+ }
+
+ return null;
+ }
+
+ public void registerCallback(NettyCallbackHandler callbackHandler)
+ {
+ this.lock.lock();
+ try
+ {
+ this.callbacks.add(callbackHandler);
+ }
+ finally
+ {
+ this.lock.unlock();
+ }
+ }
+
+ public void unregisterCallback(NettyCallbackHandler 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/RealNettyHttpServer.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/RealNettyHttpServer.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -0,0 +1,239 @@
+/*
+ * 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.LinkedList;
+import java.util.List;
+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;
+import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandler;
+
+/**
+ * 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 RealNettyHttpServer 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 boolean started;
+ private boolean stopped;
+ private boolean terminated;
+ private ChannelFactory factory;
+ private NettyInvocationHandler handler;
+
+ private RealNettyHttpServer(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 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("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 void registerCallback(NettyCallbackHandler callbackHandler)
+ {
+ this.handler.registerCallback(callbackHandler);
+ }
+
+ public final void unregisterCallback(NettyCallbackHandler callbackHandler)
+ {
+ this.handler.unregisterCallback(callbackHandler);
+ }
+
+ 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");
+ 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 RealNettyHttpServer getInstance(String scheme, String host, int port)
throws RMException
+ {
+ CLASS_LOCK.lock();
+ try
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new RealNettyHttpServer(scheme, host, (port == -1) ? 80 : port);
+ // forking back ports server
+ Thread t = new Thread(INSTANCE, "NettyHttpServer");
+ t.setDaemon(true);
+ t.start();
+ // registering shutdown hook
+ final RealNettyHttpServer 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/wsf/stack/jbws/RequestHandlerImpl.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/wsf/stack/jbws/RequestHandlerImpl.java 2009-09-30
09:01:49 UTC (rev 10804)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/wsf/stack/jbws/RequestHandlerImpl.java 2009-09-30
12:28:37 UTC (rev 10805)
@@ -588,12 +588,19 @@
}
else
{
- String epAddress = endpoint.getAddress();
- if (epAddress == null)
- throw new IllegalArgumentException("Invalid endpoint address: "
+ epAddress);
+ if (context.getAttachment(Map.class) != null) // TODO: remove this ugly hack
+ {
+ handleWSDLRequestFromInvocationContext(endpoint, outStream, context);
+ }
+ else
+ {
+ String epAddress = endpoint.getAddress();
+ if (epAddress == null)
+ throw new IllegalArgumentException("Invalid endpoint address:
" + epAddress);
- URL wsdlUrl = new URL(epAddress + "?wsdl");
- IOUtils.copyStream(outStream, wsdlUrl.openStream());
+ URL wsdlUrl = new URL(epAddress + "?wsdl");
+ IOUtils.copyStream(outStream, wsdlUrl.openStream());
+ }
}
}
catch (RuntimeException rte)
@@ -634,6 +641,33 @@
new DOMWriter(writer).setPrettyprint(true).print(document.getDocumentElement());
}
+ private void handleWSDLRequestFromInvocationContext(Endpoint endpoint, OutputStream
outputStream, InvocationContext context) throws MalformedURLException, IOException
+ {
+ ServerEndpointMetaData epMetaData =
endpoint.getAttachment(ServerEndpointMetaData.class);
+ if (epMetaData == null)
+ throw new IllegalStateException("Cannot obtain endpoint meta data");
+
+ Map<String, Object> requestHeaders = (Map<String,
Object>)context.getAttachment(Map.class);
+
+ // For the base document the resourcePath should be null
+ String resPath = (String)requestHeaders.get("resource");
+ URL reqURL = new URL(endpoint.getAddress());
+
+ String wsdlHost = reqURL.getHost();
+
+ if (ServerConfig.UNDEFINED_HOSTNAME.equals(serverConfig.getWebServiceHost()) ==
false)
+ wsdlHost = serverConfig.getWebServiceHost();
+
+ if (log.isDebugEnabled())
+ log.debug("WSDL request, using host: " + wsdlHost);
+
+ WSDLRequestHandler wsdlRequestHandler = new WSDLRequestHandler(epMetaData);
+ Document document = wsdlRequestHandler.getDocumentForPath(reqURL, wsdlHost,
resPath);
+
+ OutputStreamWriter writer = new OutputStreamWriter(outputStream);
+ new DOMWriter(writer).setPrettyprint(true).print(document.getDocumentElement());
+ }
+
private void handleException(Exception ex) throws ServletException
{
log.error("Error processing web service request", ex);