Wednesday, April 22, 2015

Send email via WSO2 ESB with several attachments

WSO2 ESB Mail transport allows you to send a email only with 1 attachment. If you want to send number of attachments here's the solution.

Scenario: Here I want to extract some content from the input message and attach to the email as two different attachment.

Solution: You can achieve this requirement using Gmail connector.

Steps: 

  1. Add the Gmail connector to the ESB and enable it.

  1. Setup the scenario: split the input message and send it with an email using two different attachments.
    1. Input message I used
<email>
       <username>sender@gmail.com</username>
       <password>password</password>
       <subject>This is the subject of the mail</subject>
       <toRecipients>receiver@gmail.com</toRecipients>   
       <textContent>This is the text content of the mail</textContent>      
       <part1>Content of the Part 1</part1>
       <part2>Content of the Part 2</part2>      
</email>

  1. proxy configuration
<proxy xmlns="http://ws.apache.org/ns/synapse"
      name="gmailProxy"
      transports="https,http"
      statistics="disable"
      trace="disable"
      startOnLoad="true">
  <target>
     <inSequence>
        <property name="username" expression="//username/text()"/>
        <property name="password" expression="//password/text()"/>
        <property name="subject" expression="//subject/text()"/>
        <property name="toRecipients" expression="//toRecipients/text()"/>
        <property name="textContent" expression="//textContent/text()"/>
        <class name="org.test.mediator.SimpleClassMediator"/>
        <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
        <gmail.passwordLogin>
           <username>{$ctx:username}</username>
           <password>{$ctx:password}</password>
        </gmail.passwordLogin>
        <log level="custom">
           <property name="login" value="success"/>
        </log>
        <gmail.sendMail>
           <subject>{$ctx:subject}</subject>
           <toRecipients>{$ctx:toRecipients}</toRecipients>
           <textContent>{$ctx:textContent}</textContent>
           <attachmentIDs>part1.txt,part2.txt</attachmentIDs>
        </gmail.sendMail>
     </inSequence>
  </target>
  <description/>
</proxy>

  1. Develop a custom class mediator to split the message parts and add it to the synapse MessageContext as attachments. 
          Refer https://docs.wso2.com/display/ESB481/Writing+a+WSO2+ESB+Mediator
          Here is the custom class mediator I wrote for this scenario 

package org.test.mediator;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.xpath.AXIOMXPath;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.jaxen.JaxenException;

import javax.activation.DataHandler;
import javax.mail.util.ByteArrayDataSource;

public class SimpleClassMediator extends AbstractMediator {

  private static final Log log = LogFactory.getLog(SimpleClassMediator.class);

  @Override public boolean mediate(MessageContext messageContext) {
      OMElement bodyContent = messageContext.getEnvelope().getBody().getFirstElement();
      try {
          AXIOMXPath xPathPart1 = new AXIOMXPath("//part1");
          String part1 = ((OMElement) xPathPart1.selectSingleNode(bodyContent)).getText();

          AXIOMXPath xPathPart2 = new AXIOMXPath("//part2");
          String part2 = ((OMElement) xPathPart2.selectSingleNode(bodyContent)).getText();

          org.apache.axis2.context.MessageContext axis2MsgCtx =
              ((Axis2MessageContext) messageContext).getAxis2MessageContext();

          javax.activation.DataHandler handler1 = new DataHandler(new ByteArrayDataSource(part1.getBytes(), "text/plain"));
          axis2MsgCtx.addAttachment("part1.txt", handler1 );

          javax.activation.DataHandler handler2 = new DataHandler(new ByteArrayDataSource(part2.getBytes(), "text/plain"));
          axis2MsgCtx.addAttachment("part2.txt", handler2);

      } catch (JaxenException e) {
          log.error("Error while adding attachments...", e);
      }

      return true;
  }

Now the setup is done, restart the ESB and send the request.
(Versions: ESB 4.8.1, Gmail Connector 1.0.0)

More reading: http://wso2.com/library/1148/

1 comment:

sajhak said...

Thanks for the post. This was useful! :)