Tuesday, 5 March 2019

SFTP sender channel Error: com.jcraft.jsch.sftpexception: no such file

Sender SFTP Connectivity Error in SAP CPI:

Error: com.jcraft.jsch.sftpexception: no such file

This error occurs due to the folder path selection issue. Remove the home directory path as shown below:

Path in FileZilla:  home/SRCFTP/outbound/C4C

In CPI: use this path: /outbound/C4C

Hope this resolves the issue.



Wednesday, 13 February 2019

Find node from XML using Groovy Script


Find the particular node from the xml data by the below script.

GroovyScript:

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 x = xml.'**'.findAll { it.name() == 'claimNumber' }

body = XmlUtil.serialize(xml)

message.setProperty("claimNum",x);

message.setBody(body);

return message;

}

Call this ${property.claimNum} whereever required to retrieve the field value of ClaimNumber.


Thanks. Happy Learning!!!



Friday, 8 February 2019

JSON to XML convertor nodes adding script

When converting the JSON data to XML using standard JSON to XML converter, the Root node and the other sub node will not be added, if there are multiple messages in the payload. This will be an issue while sending converted XML to any HTTP receivers.

So use the below script to make this work before the JSON to XML convertor

Groovy Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.*

def Message processData(Message message) {

def jsonOP = message.getBody(String.class);

jsonOP=jsonOP.toString()

def json_to_str=jsonOP.substring(1, jsonOP.length()- 1);

json_to_str="{\"Root\": [{\"EmpRoot\":["+json_to_str+"]}]}"

message.setBody(json_to_str);

return message;
}


Input:

[
{

"EmpID": 5656,

"EmpName": "Ram Kumar",

"Grade": 5

},

{

"EmpID": 5659,

"EmpName": "Ram Kumar",

"Grade": 2
}
]

Output:

<?xml version="1.0" encoding="UTF-8" ?>

<Root>
<EmpRoot>
<EmpID>5656</EmpID>
<EmpName>Ram Kumar</EmpName>
<Grade>5</Grade>
</EmpRoot>

<EmpRoot>
<EmpID>5659</EmpID>
<EmpName>Ram Kumar</EmpName>
<Grade>2</Grade>
</EmpRoot>
<Root>



Remove all the namespace from XML using XSLT mapping

There will be an issue in XPATH handling in content modifier/Router/Filter when there is namspace (like ns2:) for all the fields.

To remove all the namespace in the XML payload, use the below XSLT mapping code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" version="1.0" encoding="UTF-8" />
        <xsl:template match="*">
                <xsl:element name="{local-name()}" >
                        <xsl:apply-templates select="@* | node()"/>
                </xsl:element>
        </xsl:template>
</xsl:stylesheet>

(or)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes" method="xml" encoding="utf-8" omit-xml-declaration="yes"/>

    <!-- Stylesheet to remove all namespaces from a document -->
    <!-- NOTE: this will lead to attribute name clash, if an element contains
        two attributes with same local name but different namespace prefix -->
    <!-- Nodes that cannot have a namespace are copied as such -->

    <!-- template to copy elements -->
    <xsl:template match="*">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>


    <!-- template to copy attributes -->
    <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>


    <!-- template to copy the rest of the nodes -->
    <xsl:template match="comment() | text() | processing-instruction()">
        <xsl:copy/>
    </xsl:template>

</xsl:stylesheet>

Input:

<?xml version="1.0" encoding="UTF-8"?>
<ns2:MT_TOnlineBookResponseDetails xmlns:ns2="urn:electrolux.com">
  <BookSuccessfully>true</BookSuccessfully>
  <ErrorCode>0</ErrorCode>
</ns2:MT_TOnlineBookResponseDetails>

Output:

<?xml version="1.0" encoding="UTF-8"?>
<MT_TOnlineBookResponseDetails>
  <BookSuccessfully>true</BookSuccessfully>
  <ErrorCode>0</ErrorCode>
</MT_TOnlineBookResponseDetails>



Monday, 21 January 2019

HTTP PATCH for batch method in JSON

For updating IndividualCustomer in C4C using ODATA standard service for IndividualCustomerCollection

If required to test directly C4C system then add CSRF token.

Note: Need to maintain proper spacing as below, which will also cause an issue while triggering it.

POSTMAN Testing: POSTMAN - CPI -C4C 

--batch_1

Content-Type: multipart/mixed; boundary=changeset_guid_01


--changeset_guid_01

Content-Type: application/http

Content-Transfer-Encoding: binary


PATCH IndividualCustomerCollection('OBJECT ID') HTTP/1.1

Content-Length: 5000

Accept: application/json

Content-Type: application/json


{ "Phone": "+1 188-888-23", "Fax": "+1 0012346032324" }


--changeset_guid_01--

--batch_1--




HTTP POST using batch mode

For creating IndividualCustomer in C4C using ODATA standard service for IndividualCustomerCollection

If required to test directly C4C system then add CSRF token.

POSTMAN Testing: POSTMAN - CPI -C4C 


POST /http/dev/c4c/fixzone/individualcustomercollection_http HTTP/1.1
Host: Tenant URL
Content-Type: multipart/mixed;boundary=batch_1
Authorization: Basic UzAwMjAwMDQ0Nzk6QisxflhSLy0=
cache-control: no-cache
Postman-Token: 1188e0bb-7c63-4b46-920a-811da6c6ca79

--batch_1
Content-Type: multipart/mixed; boundary=changeset_guid_01
  
--changeset_guid_01
Content-Type: application/http
Content-Transfer-Encoding: binary

POST IndividualCustomerCollection HTTP/1.1
Content-Length: 5000
Accept: application/json
Content-Type: application/json

{
      "RoleCode": "CRM000",
      "LifeCycleStatusCode": "2",
      "TitleCode": "0001",
      "FirstName": "Ravi",
      "LastName": "Kumar",
      "LanguageCode": "EN",
      "CountryCode": "GB",
      "StateCode": "AN",
      "AddressLine1": "Ram Nagar",
      "Street": "Ram Nagar",
      "City": "US",
      "StreetPostalCode": "11214",
      "Phone": "+1 888-888-88",
      "Fax": "+1 0012346001234",
      "Email": "ravi.kumar1@gmail.com"
}

--changeset_guid_01--
--batch_1--





Remove XML node in XML using groovy script

Groovy script for removing the xml tag from the XML.

Below code is working:

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) {
    //Body
       //def body = message.getBody();
       def body = message.getBody(java.lang.String) as String;
        def xml = new XmlSlurper().parseText(body)
 xml.children().findAll { it.name() == 'CustomerID' }.replaceNode {}
   
   body = XmlUtil.serialize(xml)
   message.setBody(body);
       return message;
}

Input:
<?xml version="1.0" encoding="UTF-8"?>
<IndividualCustomerCollection>
        <IndividualCustomer>
                               <CustomerID>343565</CustomerID>
                               <RoleCode>CRM000</RoleCode>
                               <TitleCode>0001</TitleCode>
        </IndividualCustomer>
</IndividualCustomerCollection>

Output:
<?xml version="1.0" encoding="UTF-8"?>
<IndividualCustomerCollection>
        <IndividualCustomer>
                               <RoleCode>CRM000</RoleCode>
                               <TitleCode>0001</TitleCode>
        </IndividualCustomer>
</IndividualCustomerCollection>