This blog is created to throw some lights on SAP CPI concepts, which experienced in my journey. Trying to explore more about HCI/Cloud platform integration/SCPI and sharing the contents to help you. Thanks for all Users your support. Please give your comments below ...
Monday, 21 August 2023
Sap cpi new adapter error
Error: {"message":"EXCEPTION","parameters":["java.util.concurrent.TimeoutException"]},{"message":"UNRESOLVED","parameters":["(&(component=aws)(objectClass=org.apache.camel.spi.ComponentResolver))"]}]}
Solution: After adding the adapter to the artifact you have to deploy the adapter manually.
Tuesday, 8 August 2023
Pick all the values from XML and check for the condition using groovy script in SAP CI
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.joda.time.*;
import groovy.json.*
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def scs = new XmlSlurper().parseText(body)
def accno = scs.InvTransDoc.InventoryTransaction.'**'.find {it.name() == 'AccountNumber'}?.text()
def fromLocCode = scs.InvTransDoc.InventoryTransaction.'**'.find {it.name() == 'fromLocationCode'}?.text()
def toLocCode = scs.InvTransDoc.InventoryTransaction.'**'.find {it.name() == 'toLocationCode'}?.text()
if(fromLocCode == "FSLHOLD" | fromLocCode == "FSLDAMAGED" | fromLocCode == "FSLMISSING")
{
message.setHeader("LocationCode",toLocCode);
}
else
{
message.setHeader("LocationCode",fromLocCode);
}
message.setHeader("StorLoc",accno);
return message;
}
Get the dynamic date's and return using groovy script in SAP CI
Based on the input day from the value mapping this returns, incase if the date's are changing later then it is config change only.
Groovy Script:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.JsonSlurper
import groovy.json.JsonException
import groovy.json.JsonOutput
import javax.xml.*;
import groovy.xml.*
def Message processData(Message message)
{
import java.util.HashMap;
import groovy.json.JsonSlurper
import groovy.json.JsonException
import groovy.json.JsonOutput
import javax.xml.*;
import groovy.xml.*
def Message processData(Message message)
{
def propertyMap = message.getProperties()
String date2 = propertyMap.get("ExectutionDate");
String date3 = propertyMap.get("ExectutionDate1");
String date4 = propertyMap.get("ExectutionDate2");
def date1 = new Date()
String day = date1.getDate()
if (day == date2 || day == date3 || day == date4 )
{
String date2 = propertyMap.get("ExectutionDate");
String date3 = propertyMap.get("ExectutionDate1");
String date4 = propertyMap.get("ExectutionDate2");
def date1 = new Date()
String day = date1.getDate()
if (day == date2 || day == date3 || day == date4 )
{
Flag = "true";
}
else {
else {
Flag = "false"
}
message.setProperty("Flag1", Flag)
message.setProperty("day1", day)
return message;
message.setProperty("Flag1", Flag)
message.setProperty("day1", day)
return message;
}
Pick the certain date's of the month as output in mapping in SAP CI
There is a requirement where the report should run on certain date on every month, so this below logic is implement in mapping to achieve this.
Groovy script:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.JsonSlurper
import groovy.json.JsonException
import groovy.json.JsonOutput
import javax.xml.*;
import groovy.xml.*
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def date = new Date()
def day = date.getDate()
def Flag = ""
if(day == 20 || day == 21 || day == 22 || day == 23){
Flag = "true"
}
else {
Flag = "false"
}
message.setProperty("Flag",Flag)
return message;
}
Remove XML hierarchy (multiple levels)nodes from the xml
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
import groovy.util.*;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def xml = new XmlSlurper().parseText(body)
xml.Lines.SerialNumber.Sub_Component.children().findAll { it.name() == 'SubCompDescription' }.replaceNode {}
xml.Lines.SerialNumber.children().findAll { it.name() == 'ItemDescription' }.replaceNode {}
body = XmlUtil.serialize(xml)
message.setBody(body);
return message;
}
Find all the messages from the unformatted xml and place in newline
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.xml.XmlUtil;
import groovy.util.*;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def xml = new XmlSlurper().parseText(body)
def error = xml.'**'.findAll { it.name() == 'message' }*.text().join('\n')
message.setBody(error);
return message;
}
CSV file to be prepared with multiple header with multiple line item using groovy script
On receiver side CSV file generation, CSV file to be prepared with multiple header with multiple line item using groovy script:
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.xml.*;
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def ag = new xml2csv()
message.setBody(ag.execute(body))
return message
}
class xml2csv {
def execute(ins) {
//define writer
def writer = new StringWriter()
//parse input
def parsedXml = new XmlParser().parseText(ins)
def content = new XmlSlurper().parseText(ins)
def header = content.Header.children().collect().join(',')
def csv = content.Item.inject(header){ result, row ->
[result, row.children().collect().join(',')].join("\n")
}
println csv.toString()
return csv.toString()
}
}
Remove the lines inbetween the header and item after csv conversion
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message)
{
def content= message.getBody(java.lang.String); // Read Body
def newcontent=content.replaceAll('\n\n', '\n');
message.setBody(newcontent); // Set message body
return message;
}
Remove multimap XSLT mapping
<xsl:template match="//ns1:SupplierInformation">
<xsl:copy-of select="."/>
</xsl:template>
Pick last 10 digit of phone number in Groovy script
Groovy Script:
def removeString = '+91 9999944444'
removeString = removeString[-10..-1]
Output:
9999944444
9999944444
To pick the Attribute value where id =4 pick that value
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.joda.time.*;
import groovy.json.*
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String;
def data = new XmlSlurper().parseText(body)
def ReferenceField = data.'**'.find {it.name() == 'ReferenceField' && it.@id == '4'}?.text()
message.setProperty("RefField",ReferenceField);
return message;
}
Pick the json field and replace the existing property value in the payload using the script
import com.sap.gateway.ip.core.customdev.util.Message; import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import org.joda.time.*;
import groovy.json.*
def Message processData(Message message)
{
def ExtId1 = message.getProperty("ExternalId").toString().trim();
def body = message.getBody(java.lang.String) as String;
def jsonSlurper = new JsonSlurper();
def jsonDataObject = jsonSlurper.parseText(body);
jsonDataObject.header.externalid = ExtId1
message.setBody(new JsonBuilder(jsonDataObject).toPrettyString()) return message
}
Remove some extra nodes from json format using groovy script
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def Message processData(Message message) {
def body = message.getBody(java.lang.String) as String
def jsonParser = new JsonSlurper()
def jsonObject = jsonParser.parseText(body)
message.setBody(JsonOutput.toJson(jsonObject["rows"]))
return message;
}
Remove namespace using the content modifier for certain node levels
${in.body.replaceAll("ns0:","").replaceAll(":ns0","").replaceAll("ns1:","").replaceAll(":ns1","").replaceAll("ns3:","").replaceAll(":ns3","")}
Mapping- Add the context values with some delimiter or separator in message mapping
Add the context values with some delimiter or separator in message mapping
import com.sap.it.api.mapping.*;
//Add Output parameter to assign the output value.
def void custFunc2(String[] is, Output output, MappingContext context)
{
/* def outputVal="";
for ( int i=0;i<is.length;i++)
{
outputVal= outputVal + is [i]
}*/
output.addValue(is.join("|"))
}
Pull the stored security artifact /credentials in SAP CI using groovy script
Pull the stored security artifact /credentials in SAP CI using groovy script
import com.sap.it.api.ITApi
import com.sap.it.api.ITApiFactory
import com.sap.it.api.securestore.*;
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
//Body
def body = message.getBody();
String password;
String _output="";
def pMap = message.getProperties();
String CREDENTIAL_NAME=pMap.get("ARC_CRED").toString();
def service = ITApiFactory.getApi(SecureStoreService.class, null);
def credential = service.getUserCredential(CREDENTIAL_NAME);
if (credential == null)
{
throw new IllegalStateException("No credential found for alias 'CREDENTIAL_NAME'");
}
else
{
password= new String(credential.getPassword());
}
message.setProperty("P_Password", password);
return message;
}
import com.sap.it.api.ITApi
import com.sap.it.api.ITApiFactory
import com.sap.it.api.securestore.*;
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
//Body
def body = message.getBody();
String password;
String _output="";
def pMap = message.getProperties();
String CREDENTIAL_NAME=pMap.get("ARC_CRED").toString();
def service = ITApiFactory.getApi(SecureStoreService.class, null);
def credential = service.getUserCredential(CREDENTIAL_NAME);
if (credential == null)
{
throw new IllegalStateException("No credential found for alias 'CREDENTIAL_NAME'");
}
else
{
password= new String(credential.getPassword());
}
message.setProperty("P_Password", password);
return message;
}
Remove the Root element from the JSON
Groovy script to remove the root node:
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def Message processData(Message message){
def body = message.getBody(java.lang.String) as String
def jsonParser = new JsonSlurper()
def jsonObject = jsonParser.parseText(body)
message.setBody(JsonOutput.toJson(jsonObject["Root"]))
return message;
}
Eg:
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def Message processData(Message message){
def body = message.getBody(java.lang.String) as String
def jsonParser = new JsonSlurper()
def jsonObject = jsonParser.parseText(body)
message.setBody(JsonOutput.toJson(jsonObject["Root"]))
return message;
}
Eg:
Input
"Root": {
"Name": "Logu"
}
Output:
{
"Name": "Logu"
}
"Root": {
"Name": "Logu"
}
Output:
{
"Name": "Logu"
}
Wednesday, 2 August 2023
Create JWT token on receiver side
JWT token script:
import com.sap.gateway.ip.core.customdev.util.Message;
import io.jsonwebtoken.Claims
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.Header
import io.jsonwebtoken.JwtBuilder
import io.jsonwebtoken.SignatureAlgorithm
import io.jsonwebtoken.impl.DefaultClaims
import java.security.KeyFactory
import java.security.PrivateKey
import java.security.spec.EncodedKeySpec
import java.security.spec.PKCS8EncodedKeySpec
import java.time.LocalDateTime;
import java.time.ZoneId
def Message processData(Message message) {
def mProp = message.getProperties();
String keyString = mProp.get("privateKey"); // Provided by the receiver.
LocalDateTime now = LocalDateTime.now();
Date nowDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
Date expDate = Date.from(now.plusMinutes(60).atZone(ZoneId.systemDefault()).toInstant());
Map<String, Object> header = new HashMap<String, Object>();
header.put("alg", "PS256");
header.put("typ", "JWT");
String kid = mProp.get("kid");
header.put("kid", kid);
message.setProperty("JWT Token Header",header)
Claims claims = new DefaultClaims();
String iss = mProp.get("clientID");
claims.put("iss", iss);
claims.put("scope", "restlets,rest_webservices");
String aud = mProp.get("Audience");
claims.put("aud", aud);
//claims.put("region","dummy");
message.setProperty("JWT Token Payload",claims);
/* Create JWT json with JwtBuilder */
JwtBuilder jwtBuilder = Jwts.builder()
.setClaims(claims)
.setIssuedAt(nowDate)
.setExpiration(expDate)
.setHeader((Map<String, Object>) header);
byte[] keyBytes = Base64.getDecoder().decode(keyString);
KeyFactory kf = KeyFactory.getInstance("RSA");
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
PrivateKey privateKey = kf.generatePrivate(keySpec);
String jwtToken = (jwtBuilder.signWith(SignatureAlgorithm.PS256, kf.generatePrivate(keySpec)).compact());
message.setBody(jwtToken)
return message;
}
After that need to get the assertion and set signed jwt with below script.
Set Signed JWT:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {
def assertion = message.getBody(java.lang.String) as String;
body = "grant_type=client_credentials" + "&client_assertion_type="+"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"+"&client_assertion="+assertion;
message.setHeader("Content-Type", "application/x-www-form-urlencoded");
message.setBody(body);
return message;
}
Subscribe to:
Posts (Atom)