Monday 11 November 2019

ODATA - unknown internal server error occured in SAP CPI


When access the ODATA service to the target system, it might give the error as below

Error in CPI response from receiver system:

<?xml version="1.0" encoding="utf-8"?><error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><code>00145E5B1CC71EE0AB8B273DA099C30F</code><message xml:lang="en">In the context of Data Services an unknown internal server error occured</message></error>


Solution:

Try accessing the same link from POSTMAN tool directly to receiver system, if it gives expected response, then in CPI, delete the receiver channel and do the configuration again to resolve this issue



Monday 21 October 2019

Date timeZone format conversion using Groovy script

There is a requirement to convert the current date to the Europe time Zone. Standard time format is UTC.

Script:

import java.util.TimeZone;

def curDateTime1 = "";
def tz = TimeZone.getTimeZone("Europe/Berlin")
def ts = new Date() 
curDateTime1 = (ts.format("yyyy-MM-dd'T'HH:mm:ss", timezone=tz))

println curDateTime1

Output:

2019-10-21T16:25:04







Tuesday 17 September 2019

Allowed Header in Runtime Configurations in iflow SAP CPI


Allowed Header in the integration flow in Runtime Configurations


SapAuthenticatedUserName - To identify the Username that calls the integration flow

Note: If the sender channel is configured to use client certificate authentication, no such header is set (as it is not available in this case). Only for User Role it can be used.

CamelHttpUrl - Refers to the complete URL called, without query parameters

 For Example: CamelHttpUrl:https://XXXX-iflmap.hcisbp.XXX.hana.ondemand.com/http/dev/SF/c4c/fileupload

CamelHttpQuery - Refers to the query string that is contained in the request URL.

CamelHttpMethod - Refers to the incoming method names used to make the request. These methods are GET, POST, PUT, DELETE, and so on.

 For Example: CamelHttpMethod:POST

CamelServletContextPath - Refers to the path specified in the address field of the channel.

 For Example: CamelServletContextPath:/dev/SF/c4c/fileupload

Script used to read the header values:

def headers = message.getHeaders()
def userName = headers.get("SapAuthenticatedUserName")

Result of the above script:

SapAuthenticatedUserName:S0020XXXXXXX  (in header)

------------------------------------------------------------------------------------

Cheers!!!



Monday 2 September 2019

Logging Cookie for session handling Csrf Token - SAP CPI

There is a required step which need to used, when using the CSRF-Token mechanism. To fetch the CSRF- token, the external system will be called and retrieves the token. Session need to be enabled at header to maintain the token to push the actual data to external system.

To Log the Cookie, use the below code after the Get CSRF token request step.

Groovy Script:


import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.xml.*;
import java.io.*;

def Message processData(Message message)
{
def headers = message.getHeaders();

// read cookies to send with next request, especially yMkt Session ID
def cookie = headers.get("Set-Cookie");

StringBuffer bufferedCookie = new StringBuffer();

// bring cookies in right format

for (item in cookie)
{
bufferedCookie.append("\"" + item + "\"" + "; ")
}

message.setHeader("Cookie", bufferedCookie.toString());

def messageLog = messageLogFactory.getMessageLog(message);

if(messageLog != null)
{
messageLog.setStringProperty("Logging_Cookie", bufferedCookie.toString());
}

return message;
}

Hope this helps.



Monday 26 August 2019

Past 3 Hours based filter in Groovy script in SCPI/HCI

We could follow the below code for the different logic covered.

1. Timer is 15 mins in the iflow and if hours = 00,09,12,15,18 only then the router triggers the message.
2. HTTP query formed in the iflow.
3. Current date time - one hour and Current date time - one day.


Groovy Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
def Message processData(Message message) {


def cal = Calendar.instance;
def date = cal.time;
def dateFormat1 = 'yyyy-MM-dd\'T\'HH:mm:ss';

def datemin = '14';
def dateFormat = '00';

def dayFormat = 'dd';


def curhour =Integer.parseInt(date.format(dateFormat));

// Current datetime hour - 3 hours

def hour =Integer.parseInt(date.format(dateFormat)) -03;

//Current date - 1 day (previous day)
def pastday=Integer.parseInt(date.format(dayFormat)) -1;

def min=Integer.parseInt(date.format(datemin));

def flag;

def curDateTime = "";

curDateTime ='' + date.format(dateFormat1)+'';



def curDatePastOneHour = curDateTime.substring(0,11)+hour+curDateTime.substring(13,curDateTime.length());

def curDatePastOneDay = curDateTime.substring(0,8)+pastday+curDateTime.substring(10,curDateTime.length());

// Need a validation in my logic to send in router, if hours equals 00, only once the flow should run
if (dateFormat=='00' && datemin<='14')

{

flag = '00'

message.setProperty("flag",flag);

// HTTP Query formation to filter the data from current datetime - previous one hour and status Failed

def datequery = "((LogStart ge datetime"+"'"+curDatePastOneHour+"'"+") and (LogEnd le datetime"+"'"+curDateTime+"'"+"))"+" and CustomStatus eq 'FAILED'"

//Set property for the query
message.setProperty("datequery",datequery);

}

else{

flag = '11'

message.setProperty("flag",flag);

}

// Interface runs every 15 mins(Timer) - Logic should run only once at the hours equals 00,09,12,15,18. every hour has 4 times - i.e HH:mm - 00:00, 00:15, 00:30, 00:45

if((dateFormat=='00' && datemin<='14') || (dateFormat=='09' && datemin<='14') || (dateFormat=='12' && datemin<='14') || (dateFormat=='15' && datemin<='14') || (dateFormat=='18' || dateFormat=='21'))

{

flag = '22'

// HTTP Query formation to filter the data from current datetime - previous one day and status is completed

def datequerycount = "((LogStart ge datetime"+"'"+curDatePastOneDay+"'"+") and (LogEnd le datetime"+"'"+curDateTime+"'"+"))"+" and Status eq 'COMPLETED'"

message.setProperty("datequerycount",datequerycount);

}else{

flag = '33'

message.setProperty("flag",flag);

}



message.setProperty("hour",hour);

message.setProperty("curhour",curhour);

message.setProperty("min",min);



return message;

}



Monday 29 July 2019

Excel Macro to split large files into multiple small files

If there is a scenario of migrating the data from one system to other system, the data load will be huge and while loading the huge record in CPI will lead to timeout issue/performance issue. So we would need to split up the files into several small files and then load into the system.

For this scenario, splitting the files, we use excel macro for splitting the file.

1.Open the huge data excel and save it.
2.Then Alt+F11 key - Microsoft Visual Basic Application screen opens
3. Go to Insert menu - Module, then paste the below code in the pop up screen.

Script:

Sub Test()

Dim wb As Workbook
Dim ThisSheet As Worksheet
Dim NumOfColumns As Integer
Dim RangeToCopy As Range
Dim WorkbookCounter As Integer
Dim RowsInFile
Dim Prefix As String
Application.ScreenUpdating = False


'Initialize data
Set ThisSheet = ThisWorkbook.ActiveSheet
NumOfColumns = ThisSheet.UsedRange.Columns.Count
WorkbookCounter = 1
RowsInFile = 10000 'how many rows (incl. header) in new files?
Prefix = "SCI_user_deletion_input_QA" 'prefix of the file name


For p = 1 To ThisSheet.UsedRange.Rows.Count Step RowsInFile
Set wb = Workbooks.Add


'Paste the chunk of rows for this file
Set RangeToCopy = ThisSheet.Range(ThisSheet.Cells(p, 1), ThisSheet.Cells(p + RowsInFile - 1, NumOfColumns))
RangeToCopy.Copy wb.Sheets(1).Range("A1")


'Save the new workbook, and close it

wb.SaveAs ThisWorkbook.Path & "\" & Prefix & "_" & WorkbookCounter &".csv",FileFormat:=xlCSV
wb.Close


'Increment file counter
WorkbookCounter = WorkbookCounter + 1
Next p


Application.ScreenUpdating = True
Set wb = Nothing
End Sub

---------------------------------------------------------------------------

4. Save and close it.
5. Again back to excel sheet -then press Alt+F8.

Now you can find the files in the folder. where you save the (huge data) excel.


--- If really helpful, just give some feedback ---




Tuesday 23 July 2019

SAP Maintenance window / downtime of all Cloud application

Refer the below link to check the system distribution/ downtime of cloud application / maintenance window of

1. SAP CPI/HCI,
2. SAP C4C(Cloud for Customer)
3. SAP Ariba
4. SAP Concur
5. SAP Fieldglass
6. SAP Marketing Cloud( Hybris marketing)
7. SAP S/4 Hana Cloud
8. SAP Service Cloud
9. SAP SuccessFactors
10. SAP Integrated Busniess Planning (SAP IBP)

Check on the below link:

Click Here for SAP Cloud applications server status


Happy Learning!!!





HTTP Sender CSRF token Handling in SAP CPI

We would like to add some more authentication on the passing the message from the Sender system to CPI, so HTTP adapter is capable of handling the CSRF token at the sender side.

As this feature is not enabled for the HTTP receiver, so we can go ahead with the ODATA adapter to use this feature.

In this post, will read about fetching the CSRF token and post the data to CPI from sender system.

For the demonstration, we use POSTMAN tool as a sender system.

Step 1: Get the CSRF token by calling the CPI system

                                                       (Click to Zoom if not visible)


Step 2: POST the actual data with the CSRF token as mentioned in the below screenshot:



CPI Flow design for simple testingSimple connectivity cal made to CPI and posted the data successfully.


Happy Learning!!!





Tuesday 9 July 2019

java.io.IOException: Remotely closed - SAP CPI

When you are facing this issue on the development phase, then it could be the minor mistake in URL as mentioned below.

If you encounter this same issue at the live scenario, then it could be the connection to the respective system is broken..Eg: No able to connect to the target system.

https://test/sap/opu/odata//SAP/test_SRV/MarketingPermissions

FYI.. Some occasions minor mistakes can happen. 



Friday 14 June 2019

Routing Condition formation in SAP CPI

Based on certain routing conditions the messages are directed to different receivers. Store the condition in any header or property values and call them in router dynamically. Different acceptable formats are below:

In Router configuration, mention the Expression Type: Non-XML


Usage of Operators in Non-XML Conditions


OperatorExample
=${header.SenderId} = '1'
!=${header.SenderId} != '1'
>${header.SenderId} > '1'
>=${header.SenderId} >= '1'
<${header.SenderId} < '1'
<=${header.SenderId} <= '1'
and${header.SenderId}= '1' and ${header.ReceiverId} = '2'
or${header.SenderId}= '1' or ${header.ReceiverId}= '2'
contains${header.SenderId} contains '1'
not contains${header.SenderId} not contains '1'
in${header.SenderId} in '1,2'
not in${header.SenderId} not in '1,2'
regex${header.SenderId} regex '1.*'
not regex${header.SenderId} not regex '1.*'



Friday 7 June 2019

Accessing value mapping in groovy script

For some scenarios, we would need to access the deployed Value mapping table in the iflow, there is a possible way to access the values using the below script:


Groovy Script:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import com.sap.it.api.ITApiFactory;
import com.sap.it.api.mapping.ValueMappingApi;

def Message processData(Message message)
{
def a = ITApiFactory.getApi(ValueMappingApi.class, null);

//format sourceAgency, sourceIdentifier, sourceValue, targetAgency, targetIdentifier

def mappedValue = a.getMappedValue("C4C", "Country", "yMKT", "Country", "Austria");

def messageLog = messageLogFactory.getMessageLog(message);

messageLog.setStringProperty("Mapped Value", mappedValue);

return message;
}


Hope this Helps!!!



Wednesday 5 June 2019

Converting the File from field fixed length file to XML Success-factor Simplified


There is no standard way of converting the flat file into XML format using the fixed field length in CPI, as we have in PI using FCC parameters. To solve this problem, you can implement the below code.


GroovyScript:

import com.sap.gateway.ip.core.customdev.util.Message;

import java.util.HashMap;

    def Message processData(Message message) {

//Body

    def body = message.getBody(java.lang.String) as String;
    def lines = body.split("\n");

//root node
    def body1 ="<Files>";

//looping to read the lines and form a XML
    for(i=0;i<lines.length;i++)

     {

         body1 += "<EmpDetails>";
         body1 += "<Name>"+lines[i].substring(0,4)+"</Name>";
         body1 += "<Age>"+lines[i].substring(4,6)+"</Age>";
         body1 += "<DOB>"+lines[i].substring(6,26)+"</DOB>";
         body1 += "<JobTitle>"+lines[i].substring(14,26)+"</JobTitle>";
         body1 += "<Country>"+lines[i].substring(26,31)+"</Country>";
         body1 += "</EmpDetails>";
    }

//closing root note
    body1 +="</Files>";

//storing the converted XML to body
    message.setBody(body1);

    return message;

   }


Input File(Flat):

Rama2123051990SrConsultantIndia
Ravi3322021994 ConsultantIndia
Siva3322021994SrConsultantIndia

Output File(XML):

<Files>
<EmpDetails>
<Name>Rama</Name>
<Age>21</Age>
<DOB>23051990SrConsultant</DOB>
<JobTitle>SrConsultant</JobTitle>
<Country>India</Country>
</EmpDetails>
<EmpDetails>
<Name>Ravi</Name>
<Age>33</Age>
<DOB>22021994 Consultant</DOB>
<JobTitle> Consultant</JobTitle>
<Country>India</Country>
</EmpDetails>
<EmpDetails>
<Name>Siva</Name>
<Age>33</Age>
<DOB>22021994SrConsultant</DOB>
<JobTitle>SrConsultant</JobTitle>
<Country>India</Country>
</EmpDetails>
</Files>

Hope this helps!!!





Thursday 16 May 2019

Setting HTTP header for API Key in SAP CPI


Add the Header in the HTTP POST request for appending the API Key and Content Type

Groovy Script:

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

def Message processData(Message message) {

message.setHeader("Content-Type", "text/xml" + "; charset=utf-8" );
message.setHeader("Authorization", "api_key 2R3jWC1s3GKF1qzV2FdWOm" );

return message;

}



Tuesday 14 May 2019

SAP CPI releases 2019



The remaining takt increments of 2018 are scheduled (if all quality checks are passed timely) to reach your customer systems at the following dates:

            
Increment
Delivery Date
1901
17-Mar-19
1902
14-Apr-19
1903
12-May-19
1904
09-Jun-19
1905
07-Jul-19
1906
04-Aug-19
1907
01-Sep-19
1908
29-Sep-19
1909
27-Oct-19
1910
24-Nov-19
1911
22-Dec-2019 (tbc)
1912
20-Jan-20
1913
16-Feb-20



Wednesday 8 May 2019

SAP CPI Authorization Roles for different usage


Dear Colleagues,

Please find the below roles and usage for better understanding on the authorizations.

Area
Task
Role
Authorization groups
Design
View packages and package artifacts
WebToolingWorkspace.Read   
AuthGroup.IntegrationDeveloper
AuthGroup.BusinessExpert
AuthGroup.SystemDeveloper
AuthGroup.Administrator
Design
Create, edit, import, export, delete package with its artifacts
WebToolingWorkspace.Read
AuthGroup.IntegrationDeveloper
WebToolingWorkspace.Write
Design
Update package
WebToolingWorkspace.Read
AuthGroup.IntegrationDeveloper
WebToolingWorkspace.Write
Design
Configure artifacts (integration flows and value mappings)
WebToolingWorkspace.Read
AuthGroup.IntegrationDeveloper
WebTooling.IntegrationFlowConfigure
Design
Deploy/undeploy artifacts
WebToolingWorkspace.Read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.Administrator
GenerationAndBuild.generationandbuildcontent

NodeManager.deploycontent

Design
Export Package for transport
WebToolingWorkspace.Read
n.a.
TransportModule.read
TransportModule.write
NoteThe role IntegrationContent.Transport is deprecated.
Design
Import package from transport
WebToolingWorkspace.Read
n.a.
TransportModule.read
TransportModule.write
NoteThe role IntegrationContent.Transport is deprecated.
Design
Update Package from transport
WebToolingWorkspace.Read
n.a.
TransportModule.read
TransportModule.write
NoteThe role IntegrationContent.Transport is deprecated.
Discover
View packages
WebToolingCatalog.OverviewRead
AuthGroup.IntegrationDeveloper
AuthGroup.BusinessExpert
AuthGroup.SystemDeveloper
AuthGroup.Administrator
Discover
View package artifacts
WebToolingCatalog.OverviewRead
AuthGroup.IntegrationDeveloper
WebToolingCatalog.DetailsRead
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Discover
Copy package to workspace
WebToolingCatalog.OverviewRead
AuthGroup.IntegrationDeveloper
WebToolingWorkspace.Write
Monitor
View Monitor Overview
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View message processing logs
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
AuthGroup.BusinessExpert
AuthGroup.SystemDeveloper
AuthGroup.Administrator
Monitor
View payload of stored messages from message storage (also trace and message processing log attachments)
esbmessagestorage.read
AuthGroup.BusinessExpert
Monitor
View tasks
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View tail log
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View deployed artifact list
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View deployed integration flow in graphical editor
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Download deployed integration flow
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View deployed security material
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Add credentials
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.deploycredentials
AuthGroup.Administrator
NodeManager.deploycontent

Monitor
Add known host, keystore, PGP keyring artifacts
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.deploysecuritycontent
NodeManager.deploycontent
Monitor
Edit credentials
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.deploycredentials
AuthGroup.Administrator
NodeManager.readcredentials

NodeManager.deploycontent

Monitor
Undeploy credentials
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.deploycontent
NodeManager.deploycredentials
Monitor
Undeploy known host, keystore, PGP keyring artifacts
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.deploycontent
NodeManager.deploysecuritycontent
Monitor
Download keystore, public/prviate keyring, known host, .. artifact
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.read
NodeManager.readsecuritycontent
Monitor
View certificate-to-user mappings
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Create/edit/delete certificate-to-user mappings
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.deploysecuritycontent
NodeManager.read
Monitor
View keystore entries
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Download public keystore entries
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Add/replace/delete keystore entries
IntegrationOperationServer.read
AuthGroup.Administrator
NodeManager.deploysecuritycontent
Monitor
View data store entries/variables
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
ESBDataStore.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View data store entries - message payload/variables-content
IntegrationOperationServer.read
AuthGroup.BusinessExpert
ESBDataStore.readPayload
Monitor
Delete data store entries/variables
IntegrationOperationServer.read
AuthGroup.Administrator
ESBDataStore.read
ESBDataStore.delete
Monitor
View payload of stored messages from message store
esbmessagestorage.read
AuthGroup.BusinessExpert
Monitor
View trace configuration
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.read
AuthGroup.BusinessExpert
ConfigurationService.RuntimeBusinessParameterRead
AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Edit trace configuration
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
(enable/disable trace)
NodeManager.read
AuthGroup.BusinessExpert

ConfigurationService.RuntimeBusinessParameterRead
AuthGroup.Administrator

ConfigurationService.RuntimeBusinessParameterWrite

Monitor
Add/Edit/undeploy number ranges
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.deploycontent
AuthGroup.Administrator
Monitor
View number ranges
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
AuthGroup.BusinessExpert
AuthGroup.SystemDeveloper
AuthGroup.Administrator
Monitor
Retry queues
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
ESBDataStore.read
AuthGroup.Administrator
ESBDataStore.retry

Monitor
Delete queues
IntegrationOperationServer.read
AuthGroup.Administrator
ESBDataStore.read
ESBDataStore.delete
Monitor
View queues
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
ESBDataStore.read
AuthGroup.BusinessExpert

AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
View runtime processing locks
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper


MessageProcessingLocks.Read
AuthGroup.SystemDeveloper

AuthGroup.Administrator
Monitor
Delete runtime processing locks
IntegrationOperationServer.read
AuthGroup.Administrator
MessageProcessingLocks.Delete
Monitor
Test connectivity
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
NodeManager.deploycredentials
AuthGroup.Administrator
Monitor
Change log level
IntegrationOperationServer.read
AuthGroup.IntegrationDeveloper
ConfigurationService.RuntimeBusinessParameterWrite
AuthGroup.BusinessExpert
NodeManager.read
AuthGroup.Administrator
Monitor
View audit log entries
IntegrationOperationServer.read
AuthGroup.Administrator
AuditLog.Read
Settings
View/change product profile
WebToolingSettingsProductProfiles.savetenantconfiguration
AuthGroup.Administrator
Settings
Set ntransport system
WebToolingSettingsProductProfiles.savetenantconfiguration
AuthGroup.Administrator