Companion is a docker image you can install to your Windows/Mac/Linux that will give you tools like "Flow Diff", "Credentials Where-used", "Flow Image".
EDI Segment Counter
EDIFACT messages require total segment count in the segment UNT
. X12 messages require the same information in segment SE
data element 96
.
In SAP Process Integration/Orchestration(PI/PO) this requirement was handled by mapping the constant $B2B_SEG_COUNTER
to the relevant field. SAP Cloud Integration doesn't have this feature yet, but we can create a Groovy script that replicates the same behavior.
- You can put this script just before
XML to EDI converter
step. It is flexible and it can be used when the message body has the XML root element starting with M_
, or the root element is Interchange
.
- You can map
$B2B_SEG_COUNTER
to any field. You can use the constant function in Integration Advisor.
Note that groovy.util.Node
returns String
in Groovy IDE and a QName
object in Cloud Integration. This behavior is flexible in the Groovy spec. getLocalName
function handles this difference.
Script
Try it on
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
String magicKeyword = '$B2B_SEG_COUNTER'
def body = message.getBody(java.io.Reader)
def parser = new XmlParser()
def ediXmlDoc = parser.parse(body)
Integer segmentCount = 0
//find message and count segments inside
ediXmlDoc.breadthFirst().findAll { possibleMessageNode ->
// GroovyIDE returns String, Cloud Integration returns QName here.
// println possibleMessageNode.name().getClass()
// The implementation is flexible in the Class spec. .name() function returns java.lang.Object.
// It is possible that since this input has no namespace, it returns string.
// it is a message node
if ( getLocalName(possibleMessageNode).startsWith("M_") ){
possibleMessageNode.breadthFirst().findAll { possibleSegmentNode ->
// it is a segment node
if ( getLocalName(possibleSegmentNode).startsWith("S_") ){
// println possibleSegmentNode.name()
segmentCount ++
}
}
}
}
// find nodes to be filled
ediXmlDoc.breadthFirst().findAll { node ->
if (node.localText().size() > 0 && node.localText().first() == magicKeyword ){
node.value = segmentCount
}
}
// Write document to body
def sw = new StringWriter()
def xmlNodePrinter = new XmlNodePrinter(new PrintWriter(sw))
xmlNodePrinter.with {
preserveWhitespace = true
}
xmlNodePrinter.print(ediXmlDoc)
String result = sw.toString()
message.setBody(result)
return message;
}
def String getLocalName( groovy.util.Node node ){
def name = node.name() // can be java.lang.String or groovy.xml.QName or another object!
String localName = ""
if (name instanceof groovy.xml.QName) {
groovy.xml.QName qname = (groovy.xml.QName) name
localName = qname.getLocalPart()
}
else {
localName = name.toString()
}
return localName
}