Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
peter_wallner2
Active Contributor
0 Kudos

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 engswee.yeoh blog about the deprecated mail package
https://blogs.sap.com/2016/03/10/stop-using-mail-package-simplify-your-mail-receiver-adapter-scenari...
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-m... 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/6b4493404f673028e10000000a...



 

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-scenari...

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

 

 
Labels in this area