Technical Articles
EIPinCPI – Return Address
Previous – Request-Reply | Index | Next – Correlation Identifier
This week, we’re going to study complementary pattern to Request-Reply known as Return Address.
When do I use this pattern?
This pattern is applied whenever the asynchronous Request-Reply pattern is used. In Messaging, a message flows from one participant to another. This applies to both Request message and Reply message. When a request message is sent to a participant, how would the receiving participant know where to send the reply?
Imagine receiving emails from NoReply type of email addresses. You wouldn’t know whom to respond. In Emails, a Reply-To header can be set to inform receiver whom to respond. For example, when a meeting in Google Calendar is changed, a notification email is received from calendar-notification@google.com, however, a Reply-To field contains the email of the person who changed the event.
Similarly, a reply-to header can be specified in a JMS message to let the processor of the message know where to send the response.
Return Address in CPI
In CPI, we’ll use AMQP adapter to implement Return Address pattern. For getting started with AMQP Adapter, read Mandy‘s blog on Connecting to Messaging Systems using the AMQP Adapter. First, customer information is enqueued in the ‘customers’ queue. The receiver processes the message in the ‘customers’ queue and puts the response in the queue specified by the ‘JMSReplyTo’ header. Finally, CPI processes responses from ‘customerresponses’ queue.
Step 1: Enqueueing Customer
Integration Flow
This integration flow starts immediately after deployment, prepares the input message, and enqueues it using AMQP Adapter.
Steps
Start Immediately
This is a Timer Start step with the schedule of Run Once.
Prepare Input Message
This Content Modifier step sets the body as follows:
<Customer>
<Id>1</Id>
<Name>SAP</Name>
</Customer>
This step also sets the Return Address by using ‘JMSReplyTo’ header. The ‘JMSReplyTo’ header is set to ‘customerresponses’.
Enqueueing
This step enqueues the customer in a Microsoft Service Bus queue using AMQP Receiver Adapter.
Here’s the configuration for AMQP Adapter:
Tab | Parameter | Value |
Connection | Host | returnaddress.servicebus.windows.net |
Connection | Port | 5671 |
Connection | Credential Name | Azure Credentials |
Processing | Destination Type | Queue |
Processing | Destination Name | customers |
Step 2: Processing Customer
I have coded this step in CPI. Generally, this step will be performed by the receiver system.
Integration Flow
This integration flow dequeues customer from ‘customers’ queue and replaces the body with the response and enqueues the response in queue specified by ‘JMSReplyTo’ header.
Dequeueing Customer
This step reads from ‘customers’ queue for processing using AMQP Sender Adapter.
Here’s the configuration of AMQP Adapter:
Tab | Parameter | Value |
Connection | Host | returnaddress.servicebus.windows.net |
Connection | Port | 5671 |
Connection | Credential Name | Azure Credentials |
Processing | Queue Name | customers |
Enqueueing Response
This step enqueues the response in the queue specified by ‘JMSReplyTo’ header.
Here’s the configuration of AMQP Adapter:
Tab | Parameter | Value |
Connection | Host | returnaddress.servicebus.windows.net |
Connection | Port | 5671 |
Connection | Credential Name | Azure Credentials |
Processing | Destination Type | Queue |
Processing | Destination Name | ${header.JMSReplyTo} |
Step 3: Processing Response
Integration Flow
This integration flow reads from response queue ‘customerresponses’ and logs the response for monitoring.
Dequeueing Response
This step reads responses from ‘customerresponses’ queue.
Here’s the configuration of AMQP Adapter:
Tab | Parameter | Value |
Connection | Host | returnaddress.servicebus.windows.net |
Connection | Port | 5671 |
Connection | Credential Name | Azure Credentials |
Processing | Queue Name | customerresponses |
Log
This Groovy Script step logs the response for monitoring.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def messageLog = messageLogFactory.getMessageLog(message)
messageLog.addAttachmentAsString('Response', message.getBody(String), null)
return message
}
Output
The response message is logged for monitoring:
<Response>
<Result>SUCCESS</Result>
</Response>
Conclusion
Return Address pattern applies when the reply is needed asynchronously. The sender must specify where it wants to receive the response in a predetermined header in the request message.
The Missing Piece of The Puzzle
Here, the responses are being read from ‘customerresponses’ queue, however, it is unknown for which request they are for. This can be achieved using the Correlation Identifier which is the pattern for next week.
References/Further Readings
- Return Address Pattern in Enterprise Integration Patterns
- Mandy‘s blog on Connecting to Messaging Systems using the AMQP Adapter
- CPI Components
Hope this helps,
Bala
P.S.: All three flows should soon be available as Integration Recipes when my pull request is approved and merged. In the meantime, you can download the iFlow zips from my fork on GitHub.
Previous – Request-Reply | Index | Next – Correlation Identifier