Author: richard.opalka(a)jboss.com
Date: 2009-10-06 09:01:31 -0400 (Tue, 06 Oct 2009)
New Revision: 10839
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/NettyHeaderSource.java
Modified:
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/NettyInvocationHandler.java
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/wsf/stack/jbws/RequestHandlerImpl.java
Log:
[JBWS-2674][JBWS-2754] providing Netty header source impl + refactoring (WIP)
Modified:
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-06
07:30:11 UTC (rev 10838)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyCallbackHandler.java 2009-10-06
13:01:31 UTC (rev 10839)
@@ -26,14 +26,13 @@
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.Constants;
import org.jboss.ws.WSException;
-import org.jboss.ws.core.jaxws.handler.MessageContextJAXWS;
import org.jboss.ws.extensions.wsrm.transport.backchannel.RMCallbackHandlerImpl;
import org.jboss.wsf.common.ObjectNameFactory;
import org.jboss.wsf.common.injection.InjectionHelper;
@@ -103,17 +102,15 @@
}
}
- public int handle(String method, InputStream inputStream, OutputStream outputStream,
Map<String, Object> requestHeaders) throws IOException
+ public int handle(String method, InputStream inputStream, OutputStream outputStream,
InvocationContext invCtx) throws IOException
{
Integer statusCode = null;
try
{
- InvocationContext invCtx = new InvocationContext();
- invCtx.addAttachment(Map.class, requestHeaders);
if (method.equals("POST"))
{
doPost(inputStream, outputStream, invCtx);
- statusCode = invCtx.getAttachment(Integer.class);
+ statusCode = (Integer)invCtx.getProperty(Constants.NETTY_STATUS_CODE);
}
else if (method.equals("GET"))
{
@@ -183,7 +180,7 @@
}
}
- public final void destroy() // TODO: provide interface method to be called
+ public final void destroy()
{
synchronized(this.preDestroyRegistry)
{
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-06
07:30:11 UTC (rev 10838)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/jaxws/spi/http/NettyInvocationHandler.java 2009-10-06
13:01:31 UTC (rev 10839)
@@ -27,9 +27,9 @@
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.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -56,6 +56,8 @@
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.wsf.spi.invocation.InvocationContext;
/**
* TODO: javadoc
@@ -97,12 +99,15 @@
OutputStream outputStream = new BufferedOutputStream(baos);
Integer statusCode = null;
- Map<String, Object> requestHeaders = new HashMap<String, Object>();
+ 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));
}
- boolean error = false;
try
{
String requestPath = request.getUri();
@@ -112,7 +117,7 @@
requestPath = requestPath.substring(0, paramIndex);
}
String httpMethod = request.getMethod().getName();
- statusCode = handle(requestPath, httpMethod, getInputStream(content),
outputStream, requestHeaders);
+ statusCode = handle(requestPath, httpMethod, getInputStream(content),
outputStream, invCtx);
}
catch (Throwable t)
{
@@ -121,7 +126,7 @@
}
finally
{
- writeResponse(e, request, baos.toString(), statusCode);
+ writeResponse(e, request, baos.toString(), statusCode, responseHeaders);
}
}
@@ -130,7 +135,8 @@
return new ChannelBufferInputStream(content);
}
- private int handle(String requestPath, String httpMethod, InputStream inputStream,
OutputStream outputStream, Map<String, Object> requestHeaders) throws IOException
+ private int handle(String requestPath, String httpMethod, InputStream inputStream,
OutputStream outputStream,
+ InvocationContext invCtx) throws IOException
{
boolean handlerExists = false;
String handledPath = null;
@@ -138,17 +144,12 @@
for (NettyCallbackHandler handler : this.callbacks)
{
handledPath = truncateHostName(handler.getHandledPath());
- /*
- System.out.println("---");
- System.out.println("Request path 2: " + requestPath);
- System.out.println("Handled path 2: " + handledPath);
- */
if (requestPath.equals(handledPath))
{
handlerExists = true;
if (LOG.isDebugEnabled())
LOG.debug("Handling request path: " + requestPath);
- return handler.handle(httpMethod, inputStream, outputStream,
requestHeaders);
+ return handler.handle(httpMethod, inputStream, outputStream, invCtx);
}
}
if (handlerExists == false)
@@ -179,11 +180,20 @@
return retVal;
}
- private void writeResponse(MessageEvent e, HttpRequest request, String content,
Integer statusCode)
+ private void writeResponse(MessageEvent e, HttpRequest request, String content, int
statusCode, Map<String, List<String>> responseHeaders)
{
// Build the response object.
- HttpResponseStatus status = statusCode == 500 ?
HttpResponseStatus.INTERNAL_SERVER_ERROR : HttpResponseStatus.OK;
- HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status);
+ 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);
+ response.setHeader(key, values);
+ }
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"));
@@ -210,6 +220,16 @@
cf.awaitUninterruptibly();
}
+ 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
{
@@ -262,5 +282,5 @@
this.lock.unlock();
}
}
-
+
}
Added:
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/NettyHeaderSource.java
===================================================================
---
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/NettyHeaderSource.java
(rev 0)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/ws/core/server/NettyHeaderSource.java 2009-10-06
13:01:31 UTC (rev 10839)
@@ -0,0 +1,119 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.soap.MimeHeader;
+import javax.xml.soap.MimeHeaders;
+
+/**
+ * Netty headers abstraction.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public class NettyHeaderSource implements MimeHeaderSource
+{
+
+ private final Map<String, List<String>> req;
+ private final Map<String, List<String>> res;
+
+ public NettyHeaderSource(final Map<String, List<String>> req, final
Map<String, List<String>> res)
+ {
+ super();
+
+ this.req = req;
+ this.res = res;
+ }
+
+ public MimeHeaders getMimeHeaders()
+ {
+ if (req.size() == 0) return null;
+
+ MimeHeaders headers = new MimeHeaders();
+
+ Iterator<String> e = req.keySet().iterator();
+ String key = null;
+ String value = null;
+ while (e.hasNext())
+ {
+ key = e.next();
+ value = req.get(key).get(0);
+
+ headers.addHeader(key, value);
+ }
+
+ return headers;
+ }
+
+ public void setMimeHeaders(final MimeHeaders headers)
+ {
+ Iterator i = headers.getAllHeaders();
+ String key = null;
+ while (i.hasNext())
+ {
+ MimeHeader header = (MimeHeader)i.next();
+ key = header.getName();
+ List<String> values = new LinkedList<String>();
+ values.add(header.getValue());
+ res.put(key, values);
+ }
+ }
+
+ public Map<String, List<String>> getHeaderMap()
+ {
+ Map<String, List<String>> headerMap = new HashMap<String,
List<String>>();
+
+ Iterator<String> e = req.keySet().iterator();
+ if (e != null)
+ {
+ String key = null;
+ List<String> value = null;
+ while (e.hasNext())
+ {
+ key = e.next();
+ value = req.get(key);
+ headerMap.put(key, value);
+ }
+ }
+
+ return headerMap;
+ }
+
+ public void setHeaderMap(Map<String, List<String>> headers)
+ {
+ Iterator<String> it = headers.keySet().iterator();
+ String key = null;
+ List<String> value = null;
+ while (it.hasNext())
+ {
+ key = it.next();
+ value = headers.get(key);
+ res.put(key, value);
+ }
+ }
+
+}
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-10-06
07:30:11 UTC (rev 10838)
+++
stack/native/branches/ropalka/modules/core/src/main/java/org/jboss/wsf/stack/jbws/RequestHandlerImpl.java 2009-10-06
13:01:31 UTC (rev 10839)
@@ -66,6 +66,7 @@
import org.jboss.ws.core.jaxws.handler.MessageContextJAXWS;
import org.jboss.ws.core.jaxws.handler.SOAPMessageContextJAXWS;
import org.jboss.ws.core.server.MimeHeaderSource;
+import org.jboss.ws.core.server.NettyHeaderSource;
import org.jboss.ws.core.server.ServiceEndpointInvoker;
import org.jboss.ws.core.server.ServletHeaderSource;
import org.jboss.ws.core.server.ServletRequestContext;
@@ -260,6 +261,7 @@
// Set servlet specific properties
HttpServletResponse httpResponse = null;
ServletHeaderSource headerSource = null;
+ NettyHeaderSource nettyHeaderSource = this.getNettyHeadersSource(invContext);
if (invContext instanceof ServletRequestContext)
{
ServletRequestContext reqContext = (ServletRequestContext)invContext;
@@ -293,18 +295,39 @@
try
{
msgContext.setEndpointMetaData(sepMetaData);
- MessageAbstraction resMessage = processRequest(endpoint, headerSource,
invContext, inStream);
+ MessageAbstraction resMessage = processRequest(endpoint, nettyHeaderSource ==
null ? headerSource : nettyHeaderSource, invContext, inStream);
// Replace the message context with the response context
msgContext = MessageContextAssociation.peekMessageContext();
Map<String, List<String>> headers = (Map<String,
List<String>>)msgContext.get(MessageContextJAXWS.HTTP_RESPONSE_HEADERS);
- if (headerSource != null && headers != null)
- headerSource.setHeaderMap(headers);
+ if (headers != null)
+ {
+ if (headerSource != null)
+ {
+ headerSource.setHeaderMap(headers);
+ }
+ else if (nettyHeaderSource != null)
+ {
+ nettyHeaderSource.setHeaderMap(headers);
+ }
+ }
Integer code = (Integer)msgContext.get(MessageContextJAXWS.HTTP_RESPONSE_CODE);
- if (httpResponse != null && code != null)
- httpResponse.setStatus(code.intValue());
+ if (code != null)
+ {
+ if (httpResponse != null)
+ {
+ httpResponse.setStatus(code.intValue());
+ }
+ else
+ {
+ if (nettyHeaderSource != null)
+ {
+ invContext.setProperty(Constants.NETTY_STATUS_CODE, code.intValue());
+ }
+ }
+ }
boolean isFault = false;
if (resMessage instanceof SOAPMessage)
@@ -322,11 +345,17 @@
isFault = soapEnv != null && soapEnv.getBody().hasFault();
if (isFault)
{
- invContext.addAttachment(Integer.class,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
if (httpResponse != null)
{
httpResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
+ else
+ {
+ if (nettyHeaderSource != null)
+ {
+ invContext.setProperty(Constants.NETTY_STATUS_CODE,
HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
}
}
@@ -353,6 +382,19 @@
}
}
+ private NettyHeaderSource getNettyHeadersSource(final InvocationContext invContext)
+ {
+ Map<String, List<String>> nettyRequestHeaders = (Map<String,
List<String>>)invContext.getProperty(Constants.NETTY_REQUEST_HEADERS);
+ Map<String, List<String>> nettyResponseHeaders = (Map<String,
List<String>>)invContext.getProperty(Constants.NETTY_RESPONSE_HEADERS);
+
+ if (nettyRequestHeaders != null && nettyResponseHeaders != null)
+ {
+ return new NettyHeaderSource(nettyRequestHeaders, nettyResponseHeaders);
+ }
+
+ return null;
+ }
+
private void sendResponse(Endpoint endpoint, OutputStream output, boolean isFault)
throws SOAPException, IOException
{
CommonMessageContext msgContext = MessageContextAssociation.peekMessageContext();
@@ -586,25 +628,20 @@
try
{
- if (context instanceof ServletRequestContext)
+ if (this.validInvocationContext(context))
{
- handleWSDLRequestFromServletContext(endpoint, outStream, context);
+ final String resourcePath = this.getResourcePath(context);
+ final URL requestURL = this.getRequestURL(endpoint, context);
+ this.handleWSDLRequest(endpoint, outStream, resourcePath, requestURL);
}
else
{
- if (context != null && 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);
+ final 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());
- }
+ final URL wsdlUrl = new URL(epAddress + "?wsdl");
+ IOUtils.copyStream(outStream, wsdlUrl.openStream());
}
}
catch (RuntimeException rte)
@@ -617,46 +654,60 @@
}
}
- private void handleWSDLRequestFromServletContext(Endpoint endpoint, OutputStream
outputStream, InvocationContext context) throws MalformedURLException, IOException
+ private URL getRequestURL(Endpoint endpoint, InvocationContext context) throws
MalformedURLException
{
- ServerEndpointMetaData epMetaData =
endpoint.getAttachment(ServerEndpointMetaData.class);
- if (epMetaData == null)
- throw new IllegalStateException("Cannot obtain endpoint meta data");
+ URL requestURL = null;
- ServletRequestContext reqContext = (ServletRequestContext)context;
- HttpServletRequest req = reqContext.getHttpServletRequest();
+ if (context instanceof ServletRequestContext)
+ {
+ ServletRequestContext reqContext = (ServletRequestContext)context;
+ HttpServletRequest req = reqContext.getHttpServletRequest();
+ requestURL = new URL(req.getRequestURL().toString());
+ }
+ else if (context.getProperty(Constants.NETTY_REQUEST_HEADERS) != null)
+ {
+ requestURL = new URL(endpoint.getAddress());
+ }
+
+ return requestURL;
+ }
- // For the base document the resourcePath should be null
- String resPath = (String)req.getParameter("resource");
- URL reqURL = new URL(req.getRequestURL().toString());
+ private String getResourcePath(final InvocationContext context)
+ {
+ String resourcePath = null;
- String wsdlHost = reqURL.getHost();
+ if (context instanceof ServletRequestContext)
+ {
+ ServletRequestContext reqContext = (ServletRequestContext)context;
+ HttpServletRequest req = reqContext.getHttpServletRequest();
+ resourcePath = (String)req.getParameter("resource");
+ }
+ else if (context.getProperty(Constants.NETTY_REQUEST_HEADERS) != null)
+ {
+ Map<String, Object> requestHeaders = (Map<String,
Object>)context.getProperty(Constants.NETTY_REQUEST_HEADERS);
+ resourcePath = (String)requestHeaders.get("resource");
+ }
+
+ return resourcePath;
+ }
- if (ServerConfig.UNDEFINED_HOSTNAME.equals(serverConfig.getWebServiceHost()) ==
false)
- wsdlHost = serverConfig.getWebServiceHost();
+ private boolean validInvocationContext(InvocationContext context)
+ {
+ if (context == null)
+ return false;
+
+ final boolean servletInvocationContext = context instanceof ServletRequestContext;
+ final boolean nettyInvocationContext =
context.getProperty(Constants.NETTY_REQUEST_HEADERS) != null;
- 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());
+ return servletInvocationContext || nettyInvocationContext;
}
- private void handleWSDLRequestFromInvocationContext(Endpoint endpoint, OutputStream
outputStream, InvocationContext context) throws MalformedURLException, IOException
+ private void handleWSDLRequest(Endpoint endpoint, OutputStream outputStream, String
resPath, URL reqURL) 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)