Reference Guide - Mediation and Configuration

This document describes the UltraESB public API for mediating messages, and the configuration of the various transports, WS-Security and AS2 options

Overview

The UltraESB public API has been separated into its own JAR file, and published as a Maven 2 artifact at the AdroitLogic Maven 2 repository:

http://downloads.adroitlogic.org/maven2

Additionally, Javadocs for the public API is published at : http://api.adroitlogic.com

Mediating Messages within a Sequence

The UltraESB mediation is based around two simple classes - Mediation, and Message. While the Mediation class exposes the built-in support for common actions, the Message class exposes the various aspects of a message, so that user could develop own utilities, extensions, methods of custom logic for mediating messages as required. The payload of a Message belongs to an Object implementing the MessageFormat interface - which exposes the raw message payload where required. The MessageFormat is determined by the transport accepting a message, and maybe converted during mediation. For example, an HTTP/S request is held as a RawFileMessage - but maybe converted to and from a DOMMessage etc. A JMS Text Message will default to a StringMessage, while a Map Message will default to a MapMessage etc. In future other MessageFormats may be introduced with additional transports.

Variables exposed to Java and JSR-223 Script fragments

Every sequence is passed three variables as follows:

  • msg - Represents the current message, and is defined by the interface Message
  • mediation - Allows easy access to a rich and powerful set of mediation utility methods and defined by the interface Mediation
  • logger - a logger category that maybe used for logging from within user code during mediation

Mediation utilities

The following common utility methods are exposed by the Mediation instance. In future, new methods may be made available in addition to these.

Refer to http://api.adroitlogic.org/org/adroitlogic/ultraesb/api/Mediation.html for the latest version

void addPreemptiveBasicAuthentication(Message msg, java.lang.String username, java.lang.String password)
Adds an HTTP transport header for pre-emptive basic authentication for this message.
void addPreemptiveBasicAuthentication(Message msg, java.lang.String username, java.lang.String password, java.lang.String charset, boolean proxy)
Adds an HTTP transport header for pre-emptive basic authentication for this message.
void convertFromFI(Message m)
Convert the payload of the current message from a FastInfoset binary to an XML message (Note the XML payload is still kept as a RawFileMessage by default and maybe converted into a DOM message if required)
void convertToDOM(Message m)
Convert the current message into a DOMMessage
void convertToFI(Message m)
Convert the XML message into a FastInfoset binary message
void dropMessage(Message m)
Mark this message as a 'Dropped' message.
org.w3c.dom.NodeList extractAsNodeListUsingXPath(Message m, java.lang.String exprn, java.lang.String[][] ns)
Evaluate the given XPath expression against the XML payload, and return result as a NodeList This method converts the current payload into a DOMMessage
java.lang.String extractAsStringUsingXPath(Message m, java.lang.String exprn, java.lang.String[][] ns)
Evaluate the given XPath expression against the XML payload, and return result as a String This method converts the current payload into a DOMMessage
boolean filter(Message m, java.lang.String exprn, java.lang.String[][] ns)
Evaluate the given boolean XPath expression over the XML payload
boolean filter(Message m, java.lang.String exprn, java.lang.String[][] ns, java.lang.String regex)
Evaluate the given XPath expression over the XML payload and compare the resulting String value with the regular expression for a match.
AS2Manager getAS2Manager()
Get the AS2Manager from the bean with the id "as2Manager"
java.sql.Connection getConnection(java.lang.String dataSource)
Get a database connection from the datasource defined in the [Spring] configuration with the given id
java.lang.String getCookie(Message msg, java.lang.String name)
Return the value of the cookie with the given name
javax.sql.DataSource getDataSource(java.lang.String dataSource)
Get the DataSource with the specified id from the [Spring] configuration
java.lang.String getJvmRoute(Message msg)
Return the jvmRoute from the JSESSIONID cookie or jsessionid URL parameter of an HTTP/S request
java.lang.String getSoapAddressingAction(Message msg)
Get the WSA Action header
java.lang.String getSoapAddressingFaultTo(Message msg)
Get the WSA FaultTo header
java.lang.String getSoapAddressingFrom(Message msg)
Get the WSA From header
java.lang.String getSoapAddressingMessageID(Message msg)
Get the WSA MessageID header
java.lang.String getSoapAddressingReplyTo(Message msg)
Get the WSA ReplyTo header
java.lang.String getSoapAddressingTo(Message msg)
Get the WSA To header
java.lang.String getSoapFaultCode(Message msg)
Extract the SOAP 1.1 Fault/faultcode or SOAP 1.2 Fault/Code/Value if exists
java.lang.String getSoapFaultDetail(Message msg)
Extract the SOAP 1.1 detail or SOAP 1.2 Detail if exists
java.lang.String getSoapFaultString(Message msg)
Extract the SOAP 1.1 Fault/faultstring or SOAP 1.2 Reason/Text if exists
java.lang.String getSoapHeaderAsString(Message msg, java.lang.String namespace, java.lang.String name)
Extract the SOAP 1.1/1.2 header value as a String
java.util.Map getSoapHeadersAsStrings(Message m)
Extract the SOAP 1.1/1.2 header values as a Strings
java.lang.Object getSpringBean(java.lang.String id)
Get the Spring bean with the given ID from the [Spring] configuration
java.lang.Object getSpringBean(java.lang.String id, java.lang.Class clazz)
Get the Spring bean with the given ID from the [Spring] configuration
WSSecurityManager getWSSecurityManager()
Get the WS-Security Manager defined with the id "wssecMgr"
boolean isHessian(Message msg)
Check the message content type to see if it indicates a Hessian message
boolean isSoap(Message msg)
Check the message content type to see if it indicates a SOAP 1.1 or 1.2 message serialized as XML
void mergeXMLAttachmentsUnderElement(Message msg, java.lang.String rootElemName)
Replace the current XML payload with a top level element as specified, and merge the payloads from the current body, and attachments underneath that
void mergeXMLAttachmentsUnderElement(Message msg, java.lang.String rootElemName, java.lang.String rootNS)
Replace the current XML payload with a top level element as specified, and merge the payloads from the current body, and attachments underneath that
java.lang.String readPayloadAsString(Message m)
Return the current message payload as a String limited to 8K
boolean remove(Message m, java.lang.String exprn, java.lang.String[][] ns)
Remove the XPath expression specified node from the XML payload.
void retainElementAsPayload(Message m, java.lang.String exprn, java.lang.String[][] ns)
Replace the current XML payload with the resulting element from the XPath expression result
void savePayloadToFile(Message m, java.lang.String filePath)
Save the current message payload into the specified file
void sendPart(Message msg, int code, int part, int size)
Send the current payload as one single part of the complete payload.
void sendResponse(Message msg, int code)
Trigger off sending the current payload as a synchronous response message for the currently processing message
void sendResponseAndDrop(Message m, int code)
Trigger off sending the current payload as a synchronous response message for the currently processing message, and stop processing this message thereafter.
void sendToEndpoint(Message m, java.lang.String endpointName)
Send the current message to the endpoint with the given name.
void setCookie(Message msg, java.lang.String name, java.lang.String value)
Set a HTTP cookie on the message
void setCookie(Message msg, java.lang.String name, java.lang.String value, java.lang.String path, int age)
Set a HTTP cookie on the message
void setCookie(Message msg, java.lang.String name, java.lang.String value, java.lang.String path, java.lang.String domain, int age, boolean secure)
Set a HTTP cookie on the message
void setPayloadFromByteArray(Message m, byte[] bytes)
Set the payload of the current message to the byte array passed
void setPayloadFromFile(Message m, java.lang.String filePath)
Set the current payload of the message as the content of the given file
void setPayloadFromString(Message m, java.lang.String text)
Set the payload of the current message to the given String
void setPayloadToSOAP11Fault(Message m, java.lang.String code, java.lang.String faultString, java.lang.String detail)
Set the payload of the current message to a SOAP 1.1 fault message with the given code, faultString and detail
void setPayloadToSOAP12Fault(Message m, java.lang.String code, java.lang.String reason, java.lang.String detail)
Set the payload of the current message to a SOAP 1.2 fault message with the given code, reason and detail
void transform(Message msg, java.lang.String xsltFilename)
Transform the message payload by XSLT (without any parameters), assuming a non DOM result and assuming that the complete message payload will be used as the source of the transformation, and the result will replace the complete message payload
void transform(Message msg, java.lang.String xsltFilename, java.lang.String exprn, java.lang.String[][] ns)
Transform the message payload by XSLT (without any parameters), assuming a non DOM result
void transform(Message msg, java.lang.String xsltFilename, java.lang.String exprn, java.lang.String[][] ns, boolean domResult, java.util.Map parameters)
Transform the message payload by XSLT
void validate(Message m, java.lang.String schema)
Validate the current message against one single schema
void validate(Message m, java.lang.String[] schemas)
Validate the current message against one or more schemas
void validate(Message m, java.lang.String[] schemas, java.lang.String exprn, java.lang.String[][] ns)
Validate the current message - or an element of it selected via an XPath expression - against one or more schemas

The Message object

The Message class exposes the following methods as its public API. In future, more methods maybe made available

Refer to http://api.adroitlogic.org/org/adroitlogic/ultraesb/api/Message.html for the latest version

void addAttachment(java.lang.String key, MessageFormat att)
Add an attachment to the message identified by the specified key
void addException(ErrorInfo e)
Attach an error that this message encountered
void addException(java.lang.Exception e)
Attach an Exception that this message encountered
void addMessageFileForRelease(MessageFile mf)
Associate a MessageFile (a temporary file) for release back to the FileCache, once this message completes.
void addMessageFormatForRelease(MessageFormat mf)
Link a MessageFormat (i.e.
void addMessageForRelease(Message m)
Link a Message for GC along with this message
void addMessageProperty(java.lang.String key, java.lang.Object value)
Add a message property - i.e.
void addResponseCorrelation(java.lang.String key, java.lang.Object value)
Add an entry for correlation into the response message for this message.
void addTransportHeader(java.lang.String key, java.lang.String value)
Add a transport header to this message
void beginTransaction()
Begin a new Spring transaction and associate its context with this message
Message cloneMessage()
Clone the current message - without transport headers, properties or payload.
void commitTransaction()
Invoked to request a commit of the current transaction
boolean containsAttachments()
Does this message contain attachments?
Message createDefaultResponseMessage()
Create the default response message to this message
MessageFormat detachPayload()
Detach the current payload from this message.
MessageFormat getAttachment(java.lang.String key)
Get the attachment with the given key
java.util.Map getAttachments()
Return the Map of attachments keyed with the identifying string
java.lang.String getContentType()
Get the content type of the message if set.
java.util.UUID getCorrelatedRequestUUID()
The request message UUID for a response message
MessageFormat getCurrentPayload()
Get the current payload of the message
java.lang.String getDestinationURL()
Get the current destination URL for this message.
java.util.Map getDuplicateTransportHeaders()
Get the map of current transport header duplicate values
java.util.List getExceptions()
Get a list of errors this message encountered
java.lang.String getFirstTransportHeader(java.lang.String key)
Get the first transport header with the given key
java.lang.String getFirstTransportHeaderIgnoreCase(java.lang.String key)
This will perform a case insensitive lookup for the first occurrence of the given transport header
ErrorInfo getLastException()
Get the last error encountered and linked to this message
Mediation getMediation()
Return a reference to Mediation utilities
java.lang.Object getMessageProperty(java.lang.String key)
Get the message property associated with the specified key
java.util.UUID getMessageUUID()
Get the UUID of the message
MessageFormat getOriginalPayload()
The original payload of the message - as received from the transport, unless modified
java.util.UUID getParentMessageUUID()
The parent message UUID
java.lang.String getProxyServiceID()
Get the id of the proxy service to which this message belongs
java.util.Map getTransportHeaders()
Get the map of current transport header values ignoring duplicates
java.util.List getTransportHeaders(java.lang.String key)
Get a List of transport header values for the given key
org.springframework.transaction.TransactionStatus getTxnStatus()
Get the Spring TransactionStatus for this message
void holdCompletion()
Used to hold execution of the message completion handlers when the current sequence completes.
boolean isHoldCompletionTask()
Is this message currently marked to hold completion tasks on at the end of the execution thread (e.g.
boolean isMarkedAsFailed()
Is this message currently marked as failed?
boolean isRequest()
Is this message a request message?
boolean isResponse()
Is this message a response message?
void removeTransportHeader(java.lang.String key)
Remove all occurrences of the specified transport header
void replaceTransportHeader(java.lang.String key, java.lang.String value)
Replace the first occurrence of the transport header with the given value
void resumeAndCommitTransaction()
Invoked typically in a async-response flow to re-energize the suspended transaction, and then commit
void resumeAndRollbackTransaction()
Invoked typically in a async-response flow to re-energize the suspended transaction, and then roll it back
void rollbackTransaction()
Invoked to request a rollback of the current transaction
void setContentType(java.lang.String contentType)
Set the content type of the message
void setCurrentPayload(MessageFormat currentPayload)
Set the current payload of the message
void setDestinationURL(java.lang.String destinationURL)
Set the destination URL for this message
void setMarkedAsFailed(boolean markedAsFailed)
Mark this message as failed, by passing true.
void suspendTransaction()
Invoked typically in a request flow to suspend the active transaction, and to save its state into the response correlation map

Message Formats (i.e. Payload formats)

Refer to the full API documentation for the MessageFormats listed below

AS2 Manager

The use of the AS2 support requires the definition of the AS2Manager to the configuration. This configures the local AS2 identifier, email address and keystore information - through the KeystoreManager. The AS2 support will be further improved in the subsequent releases, with end-user feedback received. Currently the AS2Manager exposes the following methods

void notifyReceiptOfMDN(Message msg, java.util.Map headers, java.io.InputStream in)
Receive notification about the receipt of an asynchronous MDN
void notifySendStatusFromTransport(int httpStatusCode, java.lang.String originalMessageID)
Receive notification from transport level send operation
void processIncomingAS2Message(Message msg)
Routine to process a new AS2 message received over HTTP/S, and parse it and take necessary AS2 protocol level action on it, and populate the current message with the attachments for subsequent processing
AS2SendMessageProcessingResult sendNewAS2Message(Message msg, Partner partner)
Create an AS2 message using the current Message and its attachments, and send it to the specified Partner

The core components in the use of AS2 is as per the following diagram. The AS2 support uses two proxy services "AS2Receiver" and "AS2Sender" through the HTTP/S transport, which interacts with the AS2Manager instance. An external partner thus may send a new AS2 message, or an asynchronous MDN to the AS2Receiver Proxy service URL, and it will pass it to the AS2Manager via the processIncomingAS2Message() method. After the AS2Manager processes a new AS2 message or MDN, it will issue the corresponding transport level closure or issuance of the synchronous MDN automatically, and then the control is returned to the AS2Receiver sequence with the current message set to the AS2 message payload received and its attachments if any. (See sample # 351)

To send a new AS2 message to a trading partner, one may typically use a Proxy service - such as a File transport proxy that will poll for messages to be sent to AS2 partners - and then invoke the AS2Manager.sendNewAS2Message() passing the Partner information and the message. It is perfectly possible for this process to be triggered by another Java bean/logic defined in the main Spring configuration, by calling directly to the AS2Manager. On a successful send with a MDN receipt, the notifyReceiptOfMDN() is called back, while on a transport level ack or error, the notifySendStatusFromTransport() is called back, and the message flagged as failed.

WS-Security Support

The WSSecurityManager configures the WS-Security support of the UltraESB. Configuration requires the specification of the identity/trust keystores and passwords, and the credentials against required certificates or aliases. There are two variations of the constructor to be used when the identity and trust stores are the same and different.

e.g. The definition of the WSSecurityManager to the configuration when the trust and identity keystores are the one and the same. The Map passed to the constructor specifies the alias and the password for the credentials to be used. Note that the passwords used in the configuration can be easily protected / encrypted using as per this article.

    <bean id="wssecMgr" class="org.adroitlogic.soapbox.WSSecurityManager">
<constructor-arg value="samples/conf/keys/ws-sec-keystore.jks"/>
<constructor-arg value="password"/>
<constructor-arg>
<map>
<entry key="alice" value="password"/>
<entry key="bob" value="password"/>
</map>
</constructor-arg>
</bean>

Once the WSSecurityManager is configured, it could be used to verify security of incoming messages, and issue custom error messages - possibly hiding the original cause of the security failure as in the example given below. Refer to the sample configuration # 204 for more details.

        <u:inSequence>
<u:java import="org.adroitlogic.soapbox.*;"><![CDATA[
try {
WSSecurityManager wssecMgr = (WSSecurityManager) mediation.getSpringBean("wssecMgr");
wssecMgr.verifyUsernameTokenAuthentication(msg);
wssecMgr.verifyTimestampedEncryptedAndSignedMessage(msg, true);
System.out.println("Validated User : " + msg.getMessageProperty(MessageSecurityContext.USER_NAME));
System.out.println("Validated Roles : " + msg.getMessageProperty(MessageSecurityContext.USER_ROLES));
} catch (Exception e) {
mediation.setPayloadToSOAP11Fault(msg, null, "Security validation failed", null);
mediation.sendResponse(msg, 500);
}
]]></u:java>
</u:inSequence>

The full sample # 204 configuration lists examples of how WS-Security is validated and used - including the use of Timestamps, Signatures and Encryption. Additionally, the same example shows how UsernameToken authentication maybe added to a message being sent via the UltraESB.

The WSSecurityManager exposes the following methods for mediation

void addDigestUsernameTokenAuthentication(Message msg, java.lang.String username, java.lang.String password)
Add a WS-Security Username Token authentication element to the request, with a nonce, created and hashed password
void addDigestUsernameTokenAuthenticationWithTimestamp(Message msg, java.lang.String username, java.lang.String password)
Add a WS-Security Username Token authentication element and a Timestamp element to the request, with a nonce, created and hashed password
void addPlainUsernameTokenAuthenticationWithTimestamp(Message msg, java.lang.String username, java.lang.String password)
Add a WS-Security Username Token authentication element and a Timestamp elemtn to the request, with a nonce, created and hashed password
void addUsernameTokenAuthentication(Message msg, java.lang.String username, java.lang.String password, boolean hashed, boolean addNonceAndCreated, boolean includeTimestamp)
Add a WS-Security Username Token authentication element to the request
void removeSecurityHeader(Message msg)
Remove the WS-Security header from a message
void timestampAndEncryptMessage(Message msg, java.lang.String encryptionAlias)
Secure message with a timestamp and encrypt - using default timestamp TTL of 5 minutes and key size of 256
void timestampAndEncryptMessage(Message msg, java.lang.String encryptionAlias, long millis, java.lang.String algo)
Secure message with a timestamp and encrypt - using specified timestamp TTL
void timestampAndSignMessage(Message msg, java.lang.String signatureAlias)
Secure message with a timestamp and signature - using default timestamp TTL of 5 minutes
void timestampAndSignMessage(Message msg, java.lang.String signatureAlias, long millis)
Secure message with a timestamp and signature - using specified timestamp TTL
void timestampMessage(Message msg)
Secure message with a timestamp - using default timestamp TTL of 5 minutes
void timestampMessage(Message msg, long millis)
Secure message with a timestamp - using specified timestamp TTL
void timestampSignAndEncryptMessage(Message msg, java.lang.String encryptionAlias, java.lang.String signatureAlias)
Secure message with a timestamp, signature and encrypt body - using default timestamp TTL of 5 minutes and keysize of 256
void timestampSignAndEncryptMessage(Message msg, java.lang.String encryptionAlias, java.lang.String signatureAlias, long millis, java.lang.String algo)
Secure message with a timestamp, signature and encrypt body - using specified timestamp TTL
void verifyTimestampedAndEncryptedMessage(Message msg, boolean remove)
Verify that the message is timestamped and encrypted
void verifyTimestampedAndSignedMessage(Message msg, boolean remove)
Verify that the message is timestamped and signed
void verifyTimestampedEncryptedAndSignedMessage(Message msg, boolean remove)
Verify that the message is timestamped, encrypted and signed
void verifyTimestampedMessage(Message msg, boolean remove)
Verify that the message is timestamped and the timestamp valid
void verifyUsernameTokenAuthentication(Message msg)
Verify that the message contains UsernameToken authentication information, and that its valid
void verifyUsernameTokenAuthentication(Message msg, boolean remove)
Verify that the message contains UsernameToken authentication information, and that its valid

Transports Configuration

The various transports allows many configuration options. These are well described in the links reachable from the following

HTTP/S Transport

JMS Transport

File Transport (i.e. file, sftp, ftp, ftps)

Email Transport (POP3, IMAP, SMTP)