This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, go to https://wso2.com/documentation/.

Dead Letter Channel

This section explains, through an example scenario, how the Dead Letter Channel EIP can be implemented using WSO2 ESB. The following topics are covered:

Introduction to Dead Letter Channel

The Dead Letter Channel (DLC) EIP outlines how messaging systems can handle messages that cannot be delivered to the recipient. Due to system/network failures or failures at the recipient's end, messages sometimes do not get delivered to the target. In such cases, the messaging system can deliver the message to a DLC. Different mechanisms implemented in the DLC take care of delivering the dead message to the target. One method is periodically retrying to send the message to the recipient over a defined period of time. Persistence of the dead message is another option, which ensures that the dead messages are delivered to the receivers once the system is rebooted, even if the messaging system fails.

For more information, see http://www.eaipatterns.com/DeadLetterChannel.html.

Figure 1: Dead Letter Channel EIP

Example scenario

This example takes a proxy service called StockQuoteProxy, which fronts a service by the name SimpleStockQuoteService. As long as the SimpleStockQuoteService is running, the clients calling StockQuoteProxy service get responses. But if the SimpleStockQuoteService is down or a failure occurs while trying to send the message to the SimpleStockQuoteService, the faultSequence of the StockQuoteProxy will get invoked, and the message will be forwarded to the dead letter channel.

The diagram below depicts how to simulate the example scenario using WSO2 ESB.

Figure 2: Example scenario of the Dead Letter Channel EIP

Before digging into implementation details, let's take a look at the relationship between the example scenario and the Dead Letter Channel EIP by comparing their core components. We use three constructs of WSO2 ESB to implement the Dead Letter Channel EIP.

Dead Letter Channel EIP (Figure 1)Dead Letter Channel Example Scenario (Figure 2)
SenderStock Quote Client
Dead Letter ChannelStore mediator, Message stores, Message processors
Intended ReceiverSimple Stock Quote service

The diagram below depicts the DLC architecture in the ESB.

Figure 3: DLC architecture in the WSO2 ESB

The store mediator stores the dead message in the specified message store. The message processor retrieves stored messages from its associated message store and tries to resend those messages to the target receiver. The message store and message processor combination act as the dead letter channel.

Environment setup

The WSO2 ESB provides two message store types: In memory and JMS. Users can also define their own custom message store implementations.

  1. Start the ESB server and log into its management console UI (https://localhost:9443/carbon). I
  2. In the management console, navigate to the Main menu and select the Message Stores sub menu in the Service Bus section.
  3. Create a new message store. In this example, we create test-msg-store.


  4. Define a message processor called test-msg-processor as follows:

       
  5. Define an endpoint called SimpleStockQuoteService, and set it as the target.endpoint property. The store mediator uses it when storing the message into the message store.

ESB configuration

Navigate to Main Menu, click Service Bus and then Source View. Next, copy and paste the following configuration, which helps you explore the example scenario, to the source view. 

<proxy xmlns="http://ws.apache.org/ns/synapse" name="StockeQuoteProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">  
   <target>  
      <inSequence>  
         <log level="full" />  
      </inSequence>  
      <outSequence>  
         <log level="full">  
            <property name="MSG" value="Response...." />  
         </log>  
         <send />  
      </outSequence>  
      <faultSequence>  
         <log level="full">  
            <property name="MSG" value="++++++++++FAULT---------...." />  
         </log>  
         <property name="target.endpoint" value="SimpleStockQuoteService" />  
         <store messageStore="test-msg-store" />  
      </faultSequence>  
      <endpoint>  
         <address uri="http://localhost:9000/services/SimpleStockQuoteService" />  
      </endpoint>  
   </target>  
   <publishWSDL uri="http://localhost:9000/services/SimpleStockQuoteService?wsdl" />  
   <description></description>  
</proxy>  

The full WSO2 ESB configuration for this example is as follows.

<definitions xmlns="http://ws.apache.org/ns/synapse">  
    <registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">  
        <parameter name="cachableDuration">15000</parameter>  
    </registry>  
    <proxy name="StockQuoteProxy" transports="https http" startOnLoad="true" trace="disable">  
        <description/>  
        <target>  
            <endpoint>  
                <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
            </endpoint>  
            <inSequence>  
                <log level="full"/>  
            </inSequence>  
            <outSequence>  
                <log level="full">  
                    <property name="MSG" value="Response...."/>  
                </log>  
                <send/>  
            </outSequence>  
            <faultSequence>  
                <log level="full">  
                    <property name="MSG" value="++++++++++FAULT---------...."/>  
                </log>  
                <property name="target.endpoint" value="SimpleStockQuoteService"/>  
                <store messageStore="test-msg-store"/>  
            </faultSequence>  
        </target>  
        <publishWSDL uri="http://localhost:9000/services/SimpleStockQuoteService?wsdl"/>  
    </proxy>  
    <endpoint name="SimpleStockQuoteService">  
        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>  
    </endpoint>  
    <sequence name="fault">  
        <log level="full">  
            <property name="MESSAGE" value="Executing default 'fault' sequence"/>  
            <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>  
            <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>  
        </log>  
        <drop/>  
    </sequence>  
    <sequence name="main">  
        <in>  
            <log level="full"/>  
            <filter source="get-property('To')" regex="http://localhost:9000.*">  
                <send/>  
            </filter>  
        </in>  
        <out>  
            <send/>  
        </out>  
        <description>The main sequence for the message mediation</description>  
    </sequence>  
    <messageStore name="test-msg-store"/>  
    <messageProcessor class="org.apache.synapse.message.processors.forward.ScheduledMessageForwardingProcessor" name="test-msg-processor" messageStore="test-msg-store">  
        <parameter name="interval">1000</parameter>  
        <parameter name="max.deliver.attempts">100</parameter>  
    </messageProcessor>  
</definitions>  

How the implementation works

Let's investigate the elements of the ESB configuration in detail. The line numbers below are mapped to the ESB configuration shown above.

  • faultSequence - The fault sequence. The proxy service StockQuoteProxy runs in the event of a fault or error.

  • store - The store mediator loads the message store defined in line 53.

  • messageStore - Defines the message store to use, which we created using the ESB management console in step 2 above.

  • messageProcessor - The messageProcessor defines the processing algorithm, the period of time to retry sending messages in case of a failure, and the maximum number of retry attempts. 

Simulating the sample scenario

Now, let's try out the example scenario explained above.

Setting up the environment

You need to set up the ESB, and the back-end service:

  1. Download the Dead-Letter-Channel.zip, which includes the ESB configuration described above. 
  2. See Setting up the Environment for instructions on setting up the ESB and the back-end service.

    When you set up the environment, note that you only need to start one instance of the back-end service (Stock Quote Service) to simulate this example.

Executing the sample

  1. Start the sample Axis2 server with SimpleStockQuoteService deployed. For instructions, refer to the section Setting Up the ESB Samples - Starting the Axis2 server in the WSO2 ESB documentation.
  2. Use SoapUI or WSO2 ESB's Try It tool to send the following request to the getSimpleQuote function of StockQuoteProxy service. For information about the Stock Quote client, refer to the section Sample Clients in the WSO2 ESB documentation. 

    the

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.samples">
       <soapenv:Header/>
       <soapenv:Body>
          <ser:getSimpleQuote>
             <!--Optional:-->
             <ser:symbol>IBM</ser:symbol>
          </ser:getSimpleQuote>
       </soapenv:Body>
    </soapenv:Envelope>
  3. A message similar to the one below appears in the simple Axis server.

  4. Stop the Axis server, and resend the same request. Note that the message sending fails, and the message processor tries to resend the message every few seconds.
  5. Restart the Axis server, and note that the message will be delivered to SimpleStockQuoteService once the server is running.