Author: ruwan
Date: Mon Mar  9 03:28:48 2009
New Revision: 751579

URL: http://svn.apache.org/viewvc?rev=751579&view=rev
Log:
Applying Eric's patch for the hessian message builder on SYNAPSE-514

Added:
    
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/
    
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/HessianMessageBuilderTest.java
    synapse/trunk/java/modules/extensions/src/test/resources/org/
    synapse/trunk/java/modules/extensions/src/test/resources/org/apache/
    synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/
    
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/
    
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/
    
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyFaultResponse_V1.bin
   (with props)
    
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyRequest.bin
   (with props)
    
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianIncomplete.bin
Modified:
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianConstants.java
    
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianMessageBuilder.java

Modified: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianConstants.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianConstants.java?rev=751579&r1=751578&r2=751579&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianConstants.java
 (original)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianConstants.java
 Mon Mar  9 03:28:48 2009
@@ -38,4 +38,10 @@
 
     /** Hessian content type */
     public static final String HESSIAN_CONTENT_TYPE = "x-application/hessian";
+    
+    /** Hessian fault marker for protocol version 1.0 */
+    public static final char HESSIAN_V1_FAULT_IDENTIFIER = 'f';
+    
+    /** Hessian fault marker for protocol version 2.0 */
+    public static final char HESSIAN_V2_FAULT_IDENTIFIER = 'F';
 }

Modified: 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianMessageBuilder.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianMessageBuilder.java?rev=751579&r1=751578&r2=751579&view=diff
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianMessageBuilder.java
 (original)
+++ 
synapse/trunk/java/modules/extensions/src/main/java/org/apache/synapse/format/hessian/HessianMessageBuilder.java
 Mon Mar  9 03:28:48 2009
@@ -19,20 +19,27 @@
 
 package org.apache.synapse.format.hessian;
 
-import org.apache.axiom.om.*;
+import org.apache.axiom.om.OMAbstractFactory;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMText;
 import org.apache.axis2.AxisFault;
 import org.apache.axis2.builder.Builder;
 import org.apache.axis2.context.MessageContext;
 import org.apache.axis2.description.Parameter;
+import org.apache.axis2.transport.base.BaseConstants;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.synapse.SynapseConstants;
 import org.apache.synapse.core.SynapseEnvironment;
 import org.apache.synapse.util.SynapseBinaryDataSource;
 
-import javax.activation.DataHandler;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PushbackInputStream;
+
+import javax.activation.DataHandler;
 
 /**
  * Enables a message encoded using the Hessian binary protocol to be received 
by axis2/synapse
@@ -43,22 +50,22 @@
  */
 public class HessianMessageBuilder implements Builder {
 
-       private static final Log log = 
LogFactory.getLog(HessianMessageBuilder.class);
+    private static final Log log = 
LogFactory.getLog(HessianMessageBuilder.class);
 
-       /**
-        * Returns an OMElement from a Hessian encoded message
-        *
-        * @param inputStream stream containg the hessian message to be built
-        * @param contentType content type of the message
-        * @param messageContext message to which the hessian message has to be 
attached
-        * @return OMElement containing Hessian data handler keeping the message
-        * @throws AxisFault in case of a failure in building the hessian 
message
+    /**
+     * Returns an OMElement from a Hessian encoded message
+     *
+     * @param inputStream stream containing the Hessian message to be built
+     * @param contentType content type of the message
+     * @param messageContext message to which the hessian message has to be 
attached
+     * @return OMElement containing Hessian data handler keeping the message
+     * @throws AxisFault in case of a failure in building the hessian message
      *
      * @see 
org.apache.axis2.builder.Builder#processDocument(java.io.InputStream,
      * String, org.apache.axis2.context.MessageContext)
-        */
-       public OMElement processDocument(InputStream inputStream, String 
contentType,
-        MessageContext messageContext) throws AxisFault {
+     */
+    public OMElement processDocument(final InputStream inputStream, final 
String contentType,
+            final MessageContext messageContext) throws AxisFault {
 
         if (log.isDebugEnabled()) {
             log.debug("Start building the hessian message in to a 
HessianDataSource");
@@ -72,17 +79,18 @@
 
         try {
 
-            Parameter synEnv = messageContext.getConfigurationContext()
-                    
.getAxisConfiguration().getParameter(SynapseConstants.SYNAPSE_ENV);
+            Parameter synEnv = 
messageContext.getConfigurationContext().getAxisConfiguration()
+                    .getParameter(SynapseConstants.SYNAPSE_ENV);
+
+            PushbackInputStream pis = 
detectAndMarkMessageFault(messageContext, inputStream);
 
             DataHandler dataHandler;
             if (synEnv != null && synEnv.getValue() != null) {
-                dataHandler = new DataHandler(new SynapseBinaryDataSource(
-                        inputStream, contentType, (SynapseEnvironment) 
synEnv.getValue()));
+                dataHandler = new DataHandler(new SynapseBinaryDataSource(pis, 
contentType,
+                        (SynapseEnvironment) synEnv.getValue()));
             } else {
                 // add Hessian data inside a data handler
-                dataHandler = new DataHandler(
-                        new SynapseBinaryDataSource(inputStream,contentType));
+                dataHandler = new DataHandler(new SynapseBinaryDataSource(pis, 
contentType));
             }
             OMText textData = factory.createOMText(dataHandler, true);
             element.addChild(textData);
@@ -100,4 +108,42 @@
         return element;
     }
 
-}
+    /**
+     * Reads the first four bytes of the inputstream to detect whether the 
message represents a
+     * fault message. Once a fault message has been detected, a property used 
to mark fault messages
+     * is stored in the Axis2 message context. The implementaton uses a 
PushbackInputStream to be
+     * able to put those four bytes back at the end of processing.
+     *
+     * @param   messageContext  the Axis2 message context
+     * @param   inputStream     the inputstream to read the Hessian message
+     *
+     * @return  the wrapped (pushback) input stream
+     *
+     * @throws  IOException  if an I/O error occurs
+     */
+    private PushbackInputStream detectAndMarkMessageFault(final MessageContext 
messageContext,
+            final InputStream inputStream) throws IOException {
+
+        int bytesToRead = 4;
+        PushbackInputStream pis = new PushbackInputStream(inputStream, 
bytesToRead);
+        byte[] headerBytes = new byte[bytesToRead];
+        int n = pis.read(headerBytes);
+
+        // checking fourth byte for fault marker
+        if (n == bytesToRead) {
+            if (headerBytes[bytesToRead - 1] == 
HessianConstants.HESSIAN_V1_FAULT_IDENTIFIER
+                    || headerBytes[bytesToRead - 1] == 
HessianConstants.HESSIAN_V2_FAULT_IDENTIFIER) {
+                messageContext.setProperty(BaseConstants.FAULT_MESSAGE, 
SynapseConstants.TRUE);
+                if (log.isDebugEnabled()) {
+                    log.debug("Hessian fault detected, marking in Axis2 
message context");
+                }
+            }
+            pis.unread(headerBytes);
+        } else if (n > 0) {
+                byte[] bytesRead = new byte[n];
+                System.arraycopy(headerBytes, 0, bytesRead, 0, n);
+                pis.unread(bytesRead);
+        }
+        return pis;
+    }
+}
\ No newline at end of file

Added: 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/HessianMessageBuilderTest.java
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/HessianMessageBuilderTest.java?rev=751579&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/HessianMessageBuilderTest.java
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/test/java/org/apache/synapse/format/hessian/HessianMessageBuilderTest.java
 Mon Mar  9 03:28:48 2009
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.synapse.format.hessian;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import javax.activation.DataHandler;
+
+import junit.framework.TestCase;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.OMText;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.transport.base.BaseConstants;
+import org.apache.commons.io.IOUtils;
+import org.apache.synapse.SynapseConstants;
+import org.apache.synapse.config.SynapseConfiguration;
+import org.apache.synapse.core.SynapseEnvironment;
+import org.apache.synapse.core.axis2.Axis2SynapseEnvironment;
+import org.apache.synapse.util.SynapseBinaryDataSource;
+
+/**
+ * Test the HessianMessageBuilder using several Hessian example
+ * messages (including normal and fault messages) provided as 
+ * test resources.
+ */
+public class HessianMessageBuilderTest extends TestCase {
+
+    private static final String HESSIAN_DUMMY_FAULT_V1_RESPONSE = 
"hessianDummyFaultResponse_V1.bin";
+
+    private static final String HESSIAN_DUMMY_REQUEST = 
"hessianDummyRequest.bin";
+
+    private static final String HESSIAN_INCOMPLETE = "hessianIncomplete.bin";
+    
+    public void testProcessDocumentFaultWithSynEnv() throws IOException {
+        SynapseEnvironment synEnv = new Axis2SynapseEnvironment(new 
ConfigurationContext(
+                new AxisConfiguration()), new SynapseConfiguration());
+        testProcessDocumentFault(synEnv);
+    }
+
+    public void testProcessDocumentFaultWithoutSynEnv() throws IOException {
+        testProcessDocumentFault(null);
+    }
+
+    public void testProcessDocumentWithSynEnv() throws IOException {
+        SynapseEnvironment synEnv = new Axis2SynapseEnvironment(new 
ConfigurationContext(
+                new AxisConfiguration()), new SynapseConfiguration());
+        testProcessDocument(synEnv);
+    }
+
+    public void testProcessDocumentWithoutSynEnv() throws IOException {
+        testProcessDocument(null);
+    }
+    
+    public void testIncompleteHessianMessage() throws IOException {
+        test(HESSIAN_INCOMPLETE, null);
+    }
+    
+    private MessageContext test(String testMessageName, SynapseEnvironment 
synEnv)
+            throws IOException {
+
+        // create mock message context
+        MessageContext msgContext = new MessageContext();
+        AxisConfiguration axisConfig = new AxisConfiguration();
+        ConfigurationContext configContext = new 
ConfigurationContext(axisConfig);
+        axisConfig.addParameter(SynapseConstants.SYNAPSE_ENV, synEnv);
+        msgContext.setConfigurationContext(configContext);
+
+        HessianMessageBuilder messageBuilder = new HessianMessageBuilder();
+        InputStream is = getClass().getResourceAsStream(testMessageName);
+        OMElement element = messageBuilder.processDocument(is,
+                HessianConstants.HESSIAN_CONTENT_TYPE, msgContext);
+        OMNode hessianNode = element.getFirstOMChild();
+        OMText hessianTextNode = (OMText) hessianNode;
+        SynapseBinaryDataSource synapseBinaryDataSource = 
(SynapseBinaryDataSource) ((DataHandler) hessianTextNode
+                .getDataHandler()).getDataSource();
+        InputStream inputStream = synapseBinaryDataSource.getInputStream();
+        byte[] originalByteArray = 
IOUtils.toByteArray(getClass().getResourceAsStream(
+                testMessageName));
+        byte[] builderByteArray = IOUtils.toByteArray(inputStream);
+        assertTrue(Arrays.equals(originalByteArray, builderByteArray));
+
+        return msgContext;
+    }
+
+    private void testProcessDocumentFault(SynapseEnvironment synEnv) throws 
IOException {
+
+        MessageContext axis2MessageContext = 
test(HESSIAN_DUMMY_FAULT_V1_RESPONSE, synEnv);
+        assertEquals(SynapseConstants.TRUE, axis2MessageContext
+                .getProperty(BaseConstants.FAULT_MESSAGE));
+    }
+
+    private void testProcessDocument(SynapseEnvironment synEnv) throws 
IOException {
+
+        MessageContext axis2MessageContext = test(HESSIAN_DUMMY_REQUEST, 
synEnv);
+        
assertNull(axis2MessageContext.getProperty(BaseConstants.FAULT_MESSAGE));
+    }
+
+}

Added: 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyFaultResponse_V1.bin
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyFaultResponse_V1.bin?rev=751579&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyFaultResponse_V1.bin
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyRequest.bin
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyRequest.bin?rev=751579&view=auto
==============================================================================
Binary file - no diff available.

Propchange: 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianDummyRequest.bin
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianIncomplete.bin
URL: 
http://svn.apache.org/viewvc/synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianIncomplete.bin?rev=751579&view=auto
==============================================================================
--- 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianIncomplete.bin
 (added)
+++ 
synapse/trunk/java/modules/extensions/src/test/resources/org/apache/synapse/format/hessian/hessianIncomplete.bin
 Mon Mar  9 03:28:48 2009
@@ -0,0 +1 @@
+c\ No newline at end of file


Reply via email to