You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by ru...@apache.org on 2010/04/26 12:57:23 UTC

svn commit: r937997 - in /synapse/trunk/java/modules: core/src/main/java/org/apache/synapse/core/axis2/ transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/

Author: ruwan
Date: Mon Apr 26 10:57:23 2010
New Revision: 937997

URL: http://svn.apache.org/viewvc?rev=937997&view=rev
Log:
REST fixes - Thanks Indika for the help

Modified:
    synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java
    synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java
    synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java
    synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java

Modified: synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java?rev=937997&r1=937996&r2=937997&view=diff
==============================================================================
--- synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java (original)
+++ synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/core/axis2/Axis2FlexibleMEPClient.java Mon Apr 26 10:57:23 2010
@@ -36,6 +36,7 @@ import org.apache.axis2.context.ServiceG
 import org.apache.axis2.description.*;
 import org.apache.axis2.engine.AxisConfiguration;
 import org.apache.axis2.transport.http.HTTPConstants;
+import org.apache.axis2.transport.http.HTTPTransportUtils;
 import org.apache.axis2.wsdl.WSDLConstants;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -173,7 +174,7 @@ public class Axis2FlexibleMEPClient {
                 axisOutMsgCtx.removeProperty(org.apache.axis2.Constants.Configuration.MESSAGE_TYPE);
                 axisOutMsgCtx.setDoingREST(true);
             } else {
-                processHttpGetMethod(originalInMsgCtx, axisOutMsgCtx);
+                processWSDL2RESTRequestMessageType(originalInMsgCtx, axisOutMsgCtx);
             }
 
             if (endpoint.isUseMTOM()) {
@@ -197,17 +198,25 @@ public class Axis2FlexibleMEPClient {
                 axisOutMsgCtx.setProperty(Constants.Configuration.CHARACTER_SET_ENCODING,
                         endpoint.getCharSetEncoding());
             }
-            
+
             if (endpoint.getAddress() != null) {
-                if (SynapseConstants.FORMAT_REST.equals(endpoint.getFormat()) &&
-                    axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX) != null) {
+                // add rest request' suffix URI
+                Object restSuffix =
+                        axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX);
+                boolean isRest = SynapseConstants.FORMAT_REST.equals(endpoint.getFormat());
+
+                if (!isRest) {
+                    isRest = isRequestRest(originalInMsgCtx);
+                }
+
+                if (isRest && restSuffix != null && !"".equals(restSuffix)) {
                     axisOutMsgCtx.setTo(
-                        new EndpointReference(endpoint.getAddress() +
-                        axisOutMsgCtx.getProperty(NhttpConstants.REST_URL_POSTFIX)
-                    ));
+                            new EndpointReference(endpoint.getAddress() + restSuffix));
+
                 } else {
                     axisOutMsgCtx.setTo(new EndpointReference(endpoint.getAddress()));
                 }
+
                 axisOutMsgCtx.setProperty(NhttpConstants.ENDPOINT_PREFIX, endpoint.getAddress());
             }
 
@@ -215,7 +224,7 @@ public class Axis2FlexibleMEPClient {
                 axisOutMsgCtx.getOptions().setUseSeparateListener(true);
             }
         } else {
-            processHttpGetMethod(originalInMsgCtx, axisOutMsgCtx);
+            processWSDL2RESTRequestMessageType(originalInMsgCtx, axisOutMsgCtx);
         }
 
         // only put whttp:location for the REST (GET) requests, otherwise causes issues for POX messages
@@ -393,21 +402,62 @@ public class Axis2FlexibleMEPClient {
         }
     }
 
-    private static void processHttpGetMethod(MessageContext originalInMsgCtx,
-                                             MessageContext axisOutMsgCtx) {
+    /**
+     * This is is a workaround for axis2 RestUtils behaviour
+     * Based on an internal property and the http method, we set the message type
+     * @param originalInMsgCtx IN message
+     * @param axisOutMsgCtx Out message
+     */
+    private static void processWSDL2RESTRequestMessageType(MessageContext originalInMsgCtx,
+                                                           MessageContext axisOutMsgCtx) {
+
+        // TODO - this is a workaround for axis2 RestUtils behaviour
+        Object restContentType =
+                originalInMsgCtx.getProperty(NhttpConstants.REST_REQUEST_CONTENT_TYPE);
+
+        if (restContentType == null) {
+
+            String httpMethod = (String) originalInMsgCtx.getProperty(
+                    Constants.Configuration.HTTP_METHOD);
+            if (Constants.Configuration.HTTP_METHOD_GET.equals(httpMethod)) {
+                restContentType = HTTPConstants.MEDIA_TYPE_X_WWW_FORM;
+            }
+        }
+
+        if (restContentType instanceof String) {
 
-        String httpMethod = (String) originalInMsgCtx.getProperty(
-                Constants.Configuration.HTTP_METHOD);
-        if (Constants.Configuration.HTTP_METHOD_GET.equals(httpMethod)) {
             axisOutMsgCtx.setProperty(
                     org.apache.axis2.Constants.Configuration.MESSAGE_TYPE,
-                    HTTPConstants.MEDIA_TYPE_X_WWW_FORM);
-            if (axisOutMsgCtx.getProperty(WSDL2Constants.ATTR_WHTTP_LOCATION) == null
-                    && axisOutMsgCtx.getEnvelope().getBody().getFirstElement() != null) {
-                axisOutMsgCtx.setProperty(WSDL2Constants.ATTR_WHTTP_LOCATION,
-                        axisOutMsgCtx.getEnvelope().getBody().getFirstElement()
-                                .getQName().getLocalPart());
+                    restContentType);
+        }
+    }
+
+    /**
+     * Whether the original request received by the synapse is REST
+     *
+     * @param originalInMsgCtx request message
+     * @return <code>true</code> if the request was a REST request
+     */
+    private static boolean isRequestRest(MessageContext originalInMsgCtx) {
+
+        boolean isRestRequest =
+                originalInMsgCtx.getProperty(NhttpConstants.REST_REQUEST_CONTENT_TYPE) != null;
+
+        if (!isRestRequest) {
+
+            String httpMethod = (String) originalInMsgCtx.getProperty(
+                    Constants.Configuration.HTTP_METHOD);
+
+            isRestRequest = Constants.Configuration.HTTP_METHOD_GET.equals(httpMethod);
+
+            if (!isRestRequest) {
+
+                isRestRequest = Constants.Configuration.HTTP_METHOD_POST.equals(httpMethod)
+                        && HTTPTransportUtils.isRESTRequest(
+                        String.valueOf(originalInMsgCtx.getProperty(
+                                Constants.Configuration.MESSAGE_TYPE)));
             }
         }
+        return isRestRequest;
     }
 }

Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java?rev=937997&r1=937996&r2=937997&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/NhttpConstants.java Mon Apr 26 10:57:23 2010
@@ -87,4 +87,6 @@ public class NhttpConstants {
     public static final String NO_ENTITY_BODY = "NO_ENTITY_BODY";
     public static final String ENDPOINT_PREFIX = "ENDPOINT_PREFIX";
     protected static final String PRIORITY_CONFIG_FILE_NAME = "priorityConfigFile";
+    /* This is a workaround  for  axis2 RestUtils behaviour */
+    public static final String REST_REQUEST_CONTENT_TYPE = "synapse.internal.rest.contentType";
 }

Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java?rev=937997&r1=937996&r2=937997&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/ServerWorker.java Mon Apr 26 10:57:23 2010
@@ -398,14 +398,21 @@ public class ServerWorker implements Run
             msgContext.setProperty(
                     Constants.Configuration.CHARACTER_SET_ENCODING, charSetEncoding);
 
-            Header soapAction  = request.getFirstHeader(SOAPACTION);
 
-            HTTPTransportUtils.processHTTPPostRequest(
-                msgContext, is,
-                os,
-                contentTypeStr,
-                (soapAction != null  ? soapAction.getValue()  : null),
-                request.getRequestLine().getUri());
+            if (HTTPTransportUtils.isRESTRequest(contentTypeStr)) {
+                RESTUtil.processPOSTRequest(msgContext, is, os,
+                        request.getRequestLine().getUri(), contentType);
+            } else {
+
+                Header soapAction  = request.getFirstHeader(SOAPACTION);
+                HTTPTransportUtils.processHTTPPostRequest(
+                        msgContext, is,
+                        os,
+                        contentTypeStr,
+                        (soapAction != null  ? soapAction.getValue()  : null),
+                        request.getRequestLine().getUri());
+            }
+
         } catch (AxisFault e) {
             handleException("Error processing POST request ", e);
         }
@@ -661,9 +668,9 @@ public class ServerWorker implements Run
      */
     private void processGetAndDelete(String method) {
         try {
-            RESTUtil.processGETRequest(
+            RESTUtil.processGetAndDeleteRequest(
                     msgContext, os, request.getRequestLine().getUri(),
-                    request.getFirstHeader(HTTP.CONTENT_TYPE));
+                    request.getFirstHeader(HTTP.CONTENT_TYPE),method);
             // do not let the output stream close (as by default below) since
             // we are serving this GET/DELETE request through the Synapse engine
         } catch (AxisFault axisFault) {

Modified: synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java
URL: http://svn.apache.org/viewvc/synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java?rev=937997&r1=937996&r2=937997&view=diff
==============================================================================
--- synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java (original)
+++ synapse/trunk/java/modules/transports/core/nhttp/src/main/java/org/apache/synapse/transport/nhttp/util/RESTUtil.java Mon Apr 26 10:57:23 2010
@@ -20,27 +20,26 @@
 package org.apache.synapse.transport.nhttp.util;
 
 import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.OMNamespace;
-import org.apache.axiom.soap.SOAPEnvelope;
-import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.addressing.EndpointReference;
-import org.apache.axis2.context.ConfigurationContext;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.description.AxisService;
 import org.apache.axis2.description.WSDL20DefaultValueHolder;
 import org.apache.axis2.description.WSDL2Constants;
+import org.apache.axis2.dispatchers.RequestURIBasedDispatcher;
 import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.transport.http.HTTPConstants;
 import org.apache.axis2.transport.http.util.URIEncoderDecoder;
-import org.apache.axis2.util.Utils;
-import org.apache.synapse.transport.nhttp.NhttpConstants;
 import org.apache.http.Header;
+import org.apache.synapse.transport.nhttp.NHttpConfiguration;
+import org.apache.synapse.transport.nhttp.NhttpConstants;
 
+import javax.xml.namespace.QName;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.Iterator;
-import java.util.Map;
 
 /**
  * This class provides a set of utility methods to manage the REST invocation calls
@@ -117,37 +116,36 @@ public class RESTUtil {
     }
 
     /**
-     * Processes the HTTP GET request and builds the SOAP info-set of the REST message
+     * Processes the HTTP GET / DELETE request and builds the SOAP info-set of the REST message
      *
-     * @param msgContext The MessageContext of the Request Message
-     * @param out The output stream of the response
-     * @param requestURI The URL that the request came to
+     * @param msgContext        The MessageContext of the Request Message
+     * @param out               The output stream of the response
+     * @param requestURI        The URL that the request came to
      * @param contentTypeHeader The contentType header of the request
+     * @param httpMethod        The http method of the request
      * @throws AxisFault - Thrown in case a fault occurs
      */
-    public static void processGETRequest(MessageContext msgContext, OutputStream out, 
-                                         String requestURI, Header contentTypeHeader)
-            throws AxisFault {
+    public static void processGetAndDeleteRequest(MessageContext msgContext, OutputStream out,
+                                                  String requestURI, Header contentTypeHeader,
+                                                  String httpMethod) throws AxisFault {
+
+        String contentType = getContentType(contentTypeHeader);
+
+        prepareMessageContext(msgContext, requestURI, httpMethod, out, contentType);
 
-        msgContext.setTo(new EndpointReference(requestURI));
-        msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
-        msgContext.setServerSide(true);
-        msgContext.setDoingREST(true);
         msgContext.setProperty(NhttpConstants.NO_ENTITY_BODY, Boolean.TRUE);
+
         org.apache.axis2.transport.http.util.RESTUtil.processURLRequest(msgContext, out,
-                getContentType(contentTypeHeader));
+                contentType);
     }
 
     /**
      * Processes the HTTP GET request and builds the SOAP info-set of the REST message
      *
      * @param msgContext The MessageContext of the Request Message
-     * @param out The output stream of the response
+     * @param out        The output stream of the response
      * @param soapAction SoapAction of the request
      * @param requestURI The URL that the request came to
-     * @param configurationContext The Axis Configuration Context
-     * @param requestParameters The parameters of the request message
-     * @return boolean indication whether the operation was succesfull
      * @throws AxisFault - Thrown in case a fault occurs
      */
     public static void processURLRequest(MessageContext msgContext, OutputStream out,
@@ -168,9 +166,35 @@ public class RESTUtil {
     }
 
     /**
+     * Processes the HTTP POST request and builds the SOAP info-set of the REST message
+     *
+     * @param msgContext        The MessageContext of the Request Message
+     * @param is                The  input stream of the request
+     * @param os                The output stream of the response
+     * @param requestURI        The URL that the request came to
+     * @param contentTypeHeader The contentType header of the request
+     * @throws AxisFault - Thrown in case a fault occurs
+     */
+    public static void processPOSTRequest(MessageContext msgContext, InputStream is,
+                                          OutputStream os, String requestURI,
+                                          Header contentTypeHeader) throws AxisFault {
+
+        String contentType = getContentType(contentTypeHeader);
+
+        prepareMessageContext(msgContext, requestURI, HTTPConstants.HTTP_METHOD_POST, os, contentType);
+
+        org.apache.axis2.transport.http.util.RESTUtil.processXMLRequest(msgContext, is, os,
+                contentType);
+    }
+
+    /**
      * Given the contentType HTTP header it extracts the content-type of the request
+     *
+     * @param contentTypeHeader content type HTTP header
+     * @return content type value
      */
     private static String getContentType(Header contentTypeHeader) {
+
         String contentTypeStr = contentTypeHeader != null ? contentTypeHeader.getValue() : null;
         if (contentTypeStr != null) {
             int index = contentTypeStr.indexOf(';');
@@ -180,4 +204,46 @@ public class RESTUtil {
         }
         return contentTypeStr;
     }
+
+    /**
+     * prepare message context prior to call axis2 RestUtils
+     *
+     * @param msgContext  The MessageContext of the Request Message
+     * @param requestURI  The URL that the request came to
+     * @param httpMethod  The http method of the request
+     * @param out         The output stream of the response
+     * @param contentType The content type of the request
+     * @throws AxisFault Thrown in case a fault occurs
+     */
+    private static void prepareMessageContext(MessageContext msgContext,
+                                              String requestURI,
+                                              String httpMethod,
+                                              OutputStream out,
+                                              String contentType) throws AxisFault {
+
+        msgContext.setTo(new EndpointReference(requestURI));
+        msgContext.setProperty(HTTPConstants.HTTP_METHOD, httpMethod);
+        msgContext.setServerSide(true);
+        msgContext.setDoingREST(true);
+        msgContext.setProperty(MessageContext.TRANSPORT_OUT, out);
+        msgContext.setProperty(NhttpConstants.REST_REQUEST_CONTENT_TYPE, contentType);
+        // workaround to get REST working in the case of
+        //  1) Based on the request URI , it is possible to find a service name and operation.
+        // However, there is no actual service deployed in the synapse ( no  i.e proxy or other)
+        //  e.g  http://localhost:8280/services/StudentService/students where there  is no proxy
+        //  service with name StudentService.This is a senario where StudentService is in an external
+        //  server and it is needed to call it from synapse using the main sequence
+        //  2) request is to be injected into  the main sequence  .i.e. http://localhost:8280
+        // This method does not cause any performance issue ...
+        // Proper fix should be refractoring axis2 RestUtil in a proper way
+        RequestURIBasedDispatcher requestDispatcher = new RequestURIBasedDispatcher();
+        AxisService axisService = requestDispatcher.findService(msgContext);
+        if (axisService == null) {
+            String defaultSvcName = NHttpConfiguration.getInstance().getStringValue(
+                    "nhttp.default.service", "__SynapseService");                 
+            axisService = msgContext.getConfigurationContext()
+                    .getAxisConfiguration().getService(defaultSvcName);
+        }
+        msgContext.setAxisService(axisService);
+    }
 }