Version: 17.07
Supported Since: 17.01
The Umbriel Travels Ltd. is a travel agency which arranges accommodations for tourists in South Asia region. The Umbriel Travels exposes an online portal for their customers to book hotels and these booking details are sent to a backend JMS queue from the online portal in a JSON format.
The actual legacy booking services in the backend only accepts XML format messages and emits confirmation messages in XML format as well. Umbriel Travels wants to convert the received JSON messages into XML and vice versa without loosing any messages in between.
Further, they want to send the original JSON message to a another JMS queue for auditing purpose.
Umbriel Travels has decided to integrate the backend booking server through an ESB and delegate the message transformation logic to the ESB. Following diagram depicts the overall architecture of the design. In-order to guarantee that there is no message loss, due to errors in message transformation, JMS transactions have been used. For this implementation, they have decided to use ActiveMQ as the JMS provider.
UltraStudio Configuration
UltraESB-X Configuration
In order to implement above use case you must first select following dependencies when you are creating a new Ultra project.
Spring JMS Connector from the connector list
Message Transformer, Flow Control, XML Operations, Logging from the processor list
If you have already created a project, you can add above dependencies via Component Registry. From Tools menu, select Ultra Studio → Component Registry and from the Connectors list and Processors list, select above dependencies. |
For this sample let’s use ActiveMQ and if you have not already installed ActiveMQ please follow the installation guide.
First open the project.xpml file of the project and right click on it (on the XML content of the file). From the context menu, select Resource Template as shown in below figure
After that from the shown dialog box, select ActiveMQ JMS template.
Next you need to specify the required parameters as shown below. It is mandatory to specify a bean prefix and for that you can specify any value. The only other mandatory field is the ActiveMQ Broker URL.
You need to add activemq-all
jar into the lib directory of the project. Further, when deploying the project in the UltraESB-X, you need to add the
activemq-all jar into the
lib/custom directory as well.
|
To implement above use case, first create an integration flow named “jms-transaction-flow”, and then add required components by going through following steps in order.
Add a JMS Ingress Connector to obtain the request messages in the JMS Format from the source queue. For the connection factory select activeMq-SpringCachingConnectionFactory. Under Transaction tab, select activeMq-ultraTxnmanager as the transaction manager.
Insert a Transaction Scope Start Element to transactionally process the obtained message
Add a Clone Message Processor to clone the received message. For the Exchange pattern specify Keep Original, completion procedure should be On completion of both and specify With full message as the clone type.
In the original Message Path, add a JSON to XML Transformer and under root element name specify AddBookingRequest
Next, add a XSD Validator to validate the transformed XML message and select the
addBooking.xsd
file (in src/main/resources
directory) as the
XSD file path
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="AddBookingRequest">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="Currency"/>
<xs:element type="xs:string" name="BookingReference"/>
<xs:element type="xs:date" name="BookingDepartureDate"/>
<xs:element type="xs:string" name="ItemCity"/>
<xs:element type="xs:string" name="Item"/>
<xs:element type="xs:date" name="CheckInDate"/>
<xs:element type="xs:date" name="CheckOutDate"/>
<xs:element type="xs:byte" name="hotelRooms"/>
<xs:element type="xs:string" name="ID"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
After that send the validated message to destination JMS queue using a JMS Egress Connector. Specify ActiveMq-jmsTemplate as the JMS template and the destination queue name as well.
In the cloned message path add another JMS Egress Connector to send the JSON message to audit destination
Add a Logger Processing Element to log the XSD validation failure and specify its properties as below.
After that add an Exception Flow End element to exceptionally complete the flow
The completed integration flow should look like below.
Configuration for each element is as below. The numbering corresponds to the numbers shown in above diagram.
Design View
Text View
1. JMS Ingress Connector (Basic Tab)
1. JMS Ingress Connector (Transaction Tab)
2. Transaction Scope Start Element
3. Clone Message
4. JSON to XML Transformer
5. JMS Egress Connector
6. XSD Validator
7. Message Logger
8. JMS Egress Connector
9. Exceptional Flow End
1. JMS Ingress Connector (Basic Tab)
|
requestQueue |
|
activeMq-activeMQ-SpringCachingConnectionFactory |
1. JMS Ingress Connector (Transaction Tab)
|
activeMq-activeMQ-ultraTxnManager |
2. Transaction Scope Start Element
|
activeMq-activeMQ-ultraTxnManager |
3. Clone Message
|
Keep Original |
|
With full message |
|
On result of both |
4. JSON to XML Transformer
|
AddBookingRequest |
5. JMS Egress Connector
|
activeMq-activeMQ-jmsTemplate |
|
auditQueue |
6. XSD Validator
|
addBooking.xsd |
7. Message Logger
|
XSD Validation Failed for message @{message.current-payload} |
|
WARN |
8. JMS Egress Connector
|
activeMq-activeMQ-jmsTemplate |
|
bookingDestQueue |
9. Exceptional Flow End
|
Flow completed with validation failure |
Now you can run the Ultra Project and check the functionality of the integration flow. Create an UltraESB Server run configuration and start it.
When running the sample in the UltraESB-X distribution, you need to override the following properties in-order for the sample to work. The properties file is located at $ULTRA_HOME/conf/projects/jms-transactions/default.properties
Refer to Managing Project Properties documentation on how to override properties. |
jms-transaction-flow.jms-in.queueName |
The name of the source queue (Default value requestQueue) |
jms-transaction-flow.springSender.destination |
The name of the destination queue (Default value bookingDestQueue) |
jms-transaction-flow.auditSender.destination.destination |
The name of the audit queue (Default value auditQueue) |
activeMq.brokerURL |
Active MQ broker URL (Default value tcp://localhost:61616) |
After that navigate to $ULTRA_HOME/bin directory. Next you can run the UltraESB-X distribution with following command to start the engine with this sample project deployed.
./ultraesbx.sh -sample jms-transactions
Now after running the project, send the sample message to the source queue and it will be sent to the both destination queue.
{
"Currency" : "LKR",
"BookingReference" : "bkp-23-er",
"BookingDepartureDate" : "2017-02-23",
"ItemCity" : "BER",
"Item" : "GER",
"CheckInDate" : "2017-02-25",
"CheckOutDate" : "2017-03-12",
"hotelRooms" : 3,
"ID" : "002:BER:GER:123:456:234"
}
If you remove or change any field, then the XSD validation will fail and message will be rolled back to the original queue without sending it to either of destination queues.