Did you know? DZone has great portals for Python, Cloud, NoSQL, and HTML5!
Enterprise Integration Zone is brought to you in partnership with:

Asankha Perera is the Founder and CTO of AdroitLogic, that develops the UltraESB - the first and only Open Source ESB to introduce Zero-copy proxying for extreme performance. Asankha is a member of the Apache Software Foundation, and has previously contributed most of the code of the Apache Synapse ESB. Asankha is a DZone MVB and is not an employee of DZone and has posted 13 posts at DZone. You can read more from them at their website. View Full User Profile

Web Service Proxy that emails a copy of the response passing through, using an intermediate JMS Queue

10.11.2010
Email
Views: 3826
  • submit to reddit
The Enterprise Integration Zone is presented by DZone and FuseSource. Check out the EI Zone for real world integration scenarios to help you learn which technology will give you the most elegant solution.  For open source systems based on Apache Camel, ActiveMQ, or ServiceMix, look into FuseSource's training and technology.  

Introduction

This article describes how an ESB Proxy Service for a SOAP service could be deployed on the Free and Open Source UltraESB, to respond back to the client immediately once the response becomes available, but then post a copy of the response via an asynchronous email - without affecting the performance of the main message flow.

Overview

Originated by a proof-of-concept for a large telecom company, this scenario is now distributed as Sample #502 with the UltraESB 1.2.0 or later. A Web Service client makes a request on a Proxy Service hosted on the ESB, which will pass the message to the actual SOAP service implementation. The response received is sent back to the client immediately. A copy of the response is also pushed into a JMS Queue. A second proxy service polls the JMS Queue, and emails the messages asynchronously.

This example uses Apache ActiveMQ  as the JMS Provider, and starts up an embedded instance of Apache ActiveMQ within the UltraESB, using the ActiveMQ Spring configuration mechanism.

The SOAP Proxy Service

The Proxy service exposed to the client is exposed over the HTTP transport, on port 8280 [See 1]. This Proxy service uses the WSDL and Endpoint URL of the 'SimpleStockQuoteService' distributed with the UltraESB for testing. To start this sample service, use the graphical SOA ToolBox [2] utility, and start its sample Jetty server. The proxy service definition is simple and straightforward as shown below.

    <u:proxy id="soap-proxy">
<u:transport id="http-8280">
<u:property name="wsdlURL" value="http://localhost:9000/service/SimpleStockQuoteService?wsdl"/>
</u:transport>
<u:target>
<u:inDestination>
<u:address>http://localhost:9000/service/SimpleStockQuoteService</u:address>
</u:inDestination>
<u:outSequence>
<u:java><![CDATA[
mediation.sendToEndpoint(msg, "response");
mediation.sendToEndpoint(msg, "jmsQueue");
]]></u:java>
</u:outSequence>
</u:target>
</u:proxy>

<u:endpoint id="response">
<u:address type="response"/>
</u:endpoint>

<u:endpoint id="jmsQueue">
<u:address>jms:/Q.jmsPending</u:address>
</u:endpoint>

 

A message received by the 'soap-proxy' is targeted at the inDestination - which will forward it to the address

http://localhost:9000/service/SimpleStockQuoteService

Although not shown in this example, an optional inSequence could perform any function on the received message (e.g. transform, route, log, save to a database etc or anything else) if desired. A response received from the remote SOAP service is now handled by the outSequence. This specifies two lines of Java code specified as part of the configuration - to send this response message back to the original client, as well as the endpoint 'jmsQueue' - which is a JMS destination for the Queue with JNDI name 'Q.jmsPending'.

The UltraESB allows mediation logic to be specified in Java, Javascript, Ruby, Groovy or any other JSR 223 scripting language supported by JDK 6, and transparently compiles it into native Java bytecode for optimal execution. This allows a developer to use his most preffered and powerful programming language as the language of mediation, without learning any new - vendor/product  specific XML configuration language. A side effect of this is the ability to use try-catch-finally blocks, Object Oriented mediation coding with inheritance etc, or the preferred Java IDE for debugging and JUnit for unit testing to be seamlessly integrated. The public API exposed by the UltraESB is documented at http://api.adroitlogic.org/

Starting up an embedded ActiveMQ JMS Provider

As the UltraESB configuration is a Spring configuration file, we can easily start an embedded ActiveMQ JMS provider instance by including the following configuration snippet.

    <amq:broker useJmx="false" persistent="false">
<amq:transportConnectors>
<amq:transportConnector uri="tcp://localhost:0"/>
</amq:transportConnectors>
</amq:broker>

The JMS Listener and SMTP sender

 Now we define the second proxy service which will poll the JMS destination Queue, and send these messags via SMTP using Gmail.

    <u:proxy id="jmsToEmail">
<u:transport id="jms-lsnr">
<u:property name="destinationName" value="Q.jmsPending"/>
</u:transport>
<u:target>
<u:inSequence>
<u:java><![CDATA[
logger.info("Processing queued message from JMS and sending email..");
msg.addMessageProperty("subject", "Custom Subject for Response");
msg.setDestinationURL("mailto:mail.maildemo.demo@gmail.com"); // <-- REPLACE THIS
mediation.sendToEndpoint(msg, "smtp-gmail");
]]></u:java>
</u:inSequence>
</u:target>
</u:proxy>

<!--Sends email using the SMTP configuration defined as 'smtp-email', to the 'default' destination of the message-->
<u:endpoint id="smtp-gmail">
<u:address type="default"/>
</u:endpoint>

 

Again, the configuration is concise and simple to understand. The 'jmsToEmail' Proxy service polls the JMS destination 'Q.jmsPending', and the received messages are processed with the Java code snippet specified in the inSequence. The sample demonstrates how a custom 'Subject' is set for the email, but uses a hard coded destination address in this example, although it could easily be picked up by other means in a real world scenario. The message is set the destination address as a 'mailto:' address, and the UltraESB sends this message out using the SMTP transport sender configuration configured [See 1]

 

Trying out the sample

1. Configure the SMTP credentials as necessary in the file samples/conf/ultra-sample-502.xml. The sample configuration has been written to use the Gmail SMTP Server. Check lines commented as "REPLACE THIS"

2. Start the UltraESB sample #502 as follows: ultraesb-1.2.0/bin$ ./ultraesb.sh -sample 502

3. Start the SOA ToolBox as : ultraesb-1.2.0/bin$ ./toolbox.sh and start the sample Jetty Server

 Sample jetty server on ToolBox

4. Start the HTTP/S client from the ToolBox. Select message from Preset "1", and set URL as "http://localhost:8280/service/soap-proxy" and send the request. You will immediately see the response from the ToolBox.

5. You should see the line "INFO sequence Processing queued message from JMS and sending email.." as the JMS destination is polled and the email is being sent, and the response would be received via the specified email account as shown below.

Load Testing the scenario

The ToolBox includes a HTTP/S load test client that could be used to simulate thousands of concurrent users making thousands of requests in iteration. Using the 'JavaBench' load testing module of the UltraESB you can test this scenario with your desired load levels - as long as your JMS provider and Email server tolerates.

Check http://esbperformance.org for information on load testing ESB use cases

 

References

[1] UltraESB Sample #502

[2] The AdroitLogic ToolBox 

Published at DZone with permission of Asankha Perera, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Enterprise Integration is a huge problem space for developers, and with so many different technologies to choose from, finding the most elegant solution can be tricky.  The Enterprise Integration Zone is a place for enterprise developers of all backgrounds to share design patterns and technology solutions that make integration easier for various scenarios.  FuseSource proudly supports the EI Zone and provides its own gamut of training, services, and tools based on Apache Camel, ActiveMQ, CXF, and ServiceMix.