BpmPatternCollectMultiIf is classical BPM pattern used for n:1 scenario. A classic scenario is to pick multiple files(different format): merge and send single output to receiver. Obviously given its issues one will go for BPM only when no better option seems feasible. I am sure many would have come across same requirement and BPM seems to be the only Option.
In this blog I am discussing an approach with which BPM can be avoided.
btw I myself am guilty of creating BPM for similar requirement... picking 2 files(same folder), merging and posting IDOC to receiver. I now ask myself Why didn't I consider this approach back then!!! :razz:
Note: No message based correlation here. Just pick existing files and process.
- Check Additional Files(s) and provide file name pattern
- Read 2nd file as mandatory(unless both files are available files will not be picked)
AttachmentFile1.optional | NO |
Note: FCC cannot be used for both files. In such case one can use MessageTransformBean and PayloadSwapBean in Sender channel.
- Do Check Read Attachments in Operation mapping
This is how we can merge the two:- MainDocument and ApplicationAttachment.
File1(Main Document) | File2(Attachment) | Result Structure (After Java mapping) |
---|---|---|
<?xml version="1.0" encoding="UTF-8"?> <ns0:MT_Sender xmlns:ns0="http://AttachmentTest"> <MainDoc> <Row> <StudentID>190</StudentID> <StudentName>Lorum</StudentName> <StudentStream>MS</StudentStream> </Row> <Row> <StudentID>191</StudentID> <StudentName>Ipsum</StudentName> <StudentStream>B.Tech</StudentStream> </Row> </MainDoc> </ns0:MT_Sender> | <?xml version="1.0" encoding="UTF-8"?> <ns0:MT_Attachment xmlns:ns0="http://AttachmentTest"> <Attachment1> <Row> <StudentID>190</StudentID> <CourseData> ... ... </CourseData> </Row> <Row> <StudentID>192</StudentID> <CourseData> ... ... </CourseData> </Row> </Attachment1> </ns0:MT_Attachment> | <?xml version="1.0" encoding="UTF-8"?> <ns0:MT_Intermediate xmlns:ns0="http://AttachmentTest/"> <MainDoc> <Row> <StudentID>190</StudentID> <StudentName>Lorum</StudentName> <StudentStream>MS</StudentStream> </Row> <Row> <StudentID>191</StudentID> <StudentName>Ipsum</StudentName> <StudentStream>B.Tech</StudentStream> </Row> </MainDoc> <Attachment1> <Row> <StudentID>190</StudentID> <CourseData> ... ... </CourseData> </Row> <Row> <StudentID>192</StudentID> <CourseData> ... ... </CourseData> </Row> </Attachment1> </ns0:MT_Sender> |
package com.sap.JavaMapping;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import com.sap.aii.mapping.api.*;
public class MergeAttachment extends AbstractTransformation{
public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException
{
InputAttachments inputAttachments = in.getInputAttachments();
InputStream inputstream = in.getInputPayload().getInputStream();
OutputStream outputstream = out.getOutputPayload().getOutputStream();
try {
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dbuilder = dbfactory.newDocumentBuilder();
Document mainDoc = dbuilder.parse(inputstream);
if(inputAttachments!=null)
{
if(inputAttachments.areAttachmentsAvailable())
{
Collection<String> collectionIDs = inputAttachments.getAllContentIds(true);
Object[] arrayObj =collectionIDs.toArray();
for(int i=0;i<arrayObj.length;i++)
{
String attachmentID = (String) arrayObj[i];
Attachment attachment =inputAttachments.getAttachment(attachmentID);
InputStream attachmentInputStream = new ByteArrayInputStream(attachment.getContent());
Document attachmentDoc = dbuilder.parse(attachmentInputStream);
Element element = (Element) attachmentDoc.getElementsByTagName("Attachment1").item(0);
Node copiedNode = mainDoc.importNode(element, true);
mainDoc.getDocumentElement().appendChild(copiedNode);
}
}
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(new DOMSource(mainDoc), new StreamResult(outputstream));
} catch (ParserConfigurationException e) {
this.getTrace().addInfo("ParserConfigurationException caught");
e.printStackTrace();
} catch (SAXException e) {
this.getTrace().addInfo("SAXException caught");
e.printStackTrace();
} catch (IOException e) {
this.getTrace().addInfo("IOException caught");
e.printStackTrace();
} catch (TransformerException e) {
this.getTrace().addInfo("TransformerException caught");
e.printStackTrace();
}
}
}
This code reads 2 xml document and merge attachment recordset below.
Please note following things:
- Read additional files option is only available for NFS not for FTP.
- Also in case Business system/location are different for sender file cannot be read as attachment.
Though using separate interface files can be brought to a common location and then this approach can be followed.
Let me know if this blog helps you.
This approach is also discussed in praveen.gujjeti blog N:1 & N:M mappings not possible without BPM
Subject | Kudos |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
User | Count |
---|---|
11 | |
9 | |
7 | |
6 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |