Skip to Content
Technical Articles

Mail Package deprecated – ASMA and parameterized Java map to the rescue

Motivation and introduction

I had a requirement to send messages to different mail receivers. Depending on a value
in the XML payload being sent, two different email receivers should receive the messages.

I was used to set different email receivers in the message mapping (XSLT mapping).
Depending on flags/different values in payloads, I would set different receiver addresses.
Now I had a look at Eng Swee Yeoh blog about the deprecated mail package
https://blogs.sap.com/2016/03/10/stop-using-mail-package-simplify-your-mail-receiver-adapter-scenarios/
explaining that mail package is not an option anymore.

Also in Eng Swee’s blog he hard codes the receiver email addresses in the java mapping. That is a valid option but knowing in our environment these could possibly change over time and every time I would have to touch the java mapping which I do not want to do.

In my scenario there is a mapping involved that creates an HTML table in the body of the email. I did not test this with a “pass through” scenario but it should work very similarly.

(Possible) Solution

So I came up with a combination of a parameterized java map and ASMA (Adapter Specific Message Attributes) making use of the operation mapping parameters in the iFlow/Integrated configuration to hold the actual email addresses. Any time there is a change to the receiving email addresses I can modify these easily without having to change the java map.

  • Operation mapping

In my operation mapping I set parameters for the 2 different mail receivers and the XML element name I use from the payload to set the receivers:

  • iFlow – mapping parameters

In my iFlow I am setting “SalesOrg” as the XML element I will read from the payload and I fill the different email receiver addresses:

 

  • Java map

In the Java map I use DOM to parse the payload, I write into the message log (https://blogs.sap.com/2013/09/30/writing-log-entries-to-audit-log-of-the-message-from-custom-java-mapping-program/) and read parameters from the operation mapping:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.DynamicConfiguration;
import com.sap.aii.mapping.api.DynamicConfigurationKey;
import com.sap.aii.mapping.api.StreamTransformationConstants;
import com.sap.aii.mapping.api.StreamTransformationException;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;

public class SetMailReceivers extends AbstractTransformation {

	String tagValue;
	//let's create the dynamic configuration key for the recipients
	//we only want to set the email receivers:
	private static final DynamicConfigurationKey KEY_RECIPIENTS = DynamicConfigurationKey
			.create("http://sap.com/xi/XI/System/Mail", "THeaderTO");
	
	@Override
	public void transform(TransformationInput transformationInput, TransformationOutput transformationOutput) throws StreamTransformationException {

		Map mapParameters = (Map) transformationInput.getInputHeader().getAll();

		//get the dynamic configuration
		DynamicConfiguration conf = (DynamicConfiguration) mapParameters
				.get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
		try {

			InputStream inputstream = transformationInput.getInputPayload().getInputStream();
			OutputStream outputstream = transformationOutput.getOutputPayload().getOutputStream();
			
			//get the message ID, we need it to add a message to the monitoring message
			String messageID = transformationInput.getInputHeader().getMessageId();
			
			//create an input stream to read the payload using DOM
			InputStream inputstreamDOM = transformationInput.getInputPayload().getInputStream();
			
			//start reading XML with DOM
            Document document = createDocument(inputstreamDOM);
            
            //in the operation mapping we set the tag name that we want to read from
            //the payload to determine our email receivers:
            String elementToReadFromPayload = transformationInput.getInputParameters().getString("elementToReadFromPayload");
            AddAuditLogs.execute("elementToReadFromPayload contains: " + elementToReadFromPayload, messageID, "success");
            
            //get specific nodes with tag name contained in "elementToReadFromPayload"
            NodeList nl = document.getElementsByTagName(elementToReadFromPayload);

            //instead of "i < nl.getLength()" we just do "i < 1" - we only look at the first occurrence
            //of our element with tag name "elementToReadFromPayload"
            for(int i=0;i<1;i++){
                Node messageNode = nl.item(i);
                String nodename = messageNode.getNodeName();

                if(nodename.equals(elementToReadFromPayload)){
                	tagValue = messageNode.getFirstChild().getNodeValue();
                	//add to message monitoring log what tag we read and what it contains
                	AddAuditLogs.execute("found Element " + nodename + " contains: " + tagValue, messageID, "success");
                }
            }
            
			//now get the other parameters we set in the Operation mapping which will contain the 
            //two sets of email receivers:
			String receivers1 = transformationInput.getInputParameters().getString("mail1");
			String receivers2 = transformationInput.getInputParameters().getString("mail2");
			//add to monitoring log what parameters we read and what they contain:
			AddAuditLogs.execute("mail1 contains: " + receivers1, messageID, "success");
			AddAuditLogs.execute("mail2 contains: " + receivers2, messageID, "success");   
			
		    //now put the recipients into the dynamic configuration and we are done :-)
			//depending on the value in the XML element we read (elementToReadFromPayload)
			//we now set the receivers:			
			if (tagValue.contains("1710")) {
				conf.put(KEY_RECIPIENTS, receivers2);
			}else {
				conf.put(KEY_RECIPIENTS, receivers1);
			}
				
			// b) Just copy Input file content to Output file content
			byte[] b = new byte[inputstream.available()];
			inputstream.read(b);
			outputstream.write(b);
			
		} catch(Exception exception) {
			getTrace().addDebugMessage(exception.getMessage());
			throw new StreamTransformationException(exception.toString());
		}
		
	}

	//create the DOM Document
    public static Document createDocument(InputStream inputstreamDOM) throws ParserConfigurationException, IOException, SAXException {
    	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = factory.newDocumentBuilder();

        Document document = db.parse(inputstreamDOM);

        document.getDocumentElement().normalize();
        return document;
    }
}

 

  • Mail receiver channel

I set ASMA in the Mail receiver channel. All possible ASMA attributes for mail receiver adapters can be found here: https://help.sap.com/viewer/5cf7d2de571a45cc81f91261668b7361/7.3.20/en-US/6b4493404f673028e10000000a1550b0.html

 

Under tab “General” I just set an underscore in the “To” field and hardcoded the CC: values:

 

Testing the scenario

Once starting the scenario and triggering a message to the mail receiver channel, we are able to see audit entries in the message log:

Checking the Dynamic Configuration we can see the respective mail receiver addresses were set

and an email was received successfully:

 

I hope this blog helps one or the other colleague “out there” implementing mail-to scenarios.

Best regards,
Peter

References:

https://blogs.sap.com/2016/03/10/stop-using-mail-package-simplify-your-mail-receiver-adapter-scenarios/

https://help.sap.com/viewer/5cf7d2de571a45cc81f91261668b7361/7.3.20/en-US/6b4493404f673028e10000000a1550b0.html

 

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.