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