Skip to Content
Technical Articles

SAP PI re-usable connectivity suite for Salesforce

Title:

SAP PI re-usable connectivity suite for Salesforce

 

Pre-Requisites:

  • Fairly good knowledge in SAP PI (Single Stack).
  • Knowledge of NW BPM
  • Value mappings

 

Introduction:

This is a solution that I implemented in a time crunch situation which provided good value and cost savings for my company in reducing the number of API connections made my SAP PI to Salesforce per hour. I designed and implemented this solution with my prior knowledge of NW BPM’s, Value Mappings, Java Mappings, UDF and PI REST adapter configurations. I believe this will be helpful in cost reductions of your Salesforce subscriptions by keeping your API connections in check.

To begin with, I did an analysis on the number of API connections we were doing with Salesforce and the numbers were staggering. I got to know that the API connections were exceeding 10,000 per hour at times. In order to avoid the connections being dropped or paying additional subscription for increasing the API limits, I had to come up with a solution and this blog post is a result of that implementation.

Benefits:

  • I was able to manage the no. of connections PI makes in an hour/day irrespective of the no. of transactions.
  • Was able to save Cost premiums for exceeded API connections
  • No additional adapter required
  • Can be used for both SOAP based connections and REST connections

Solution Overview:

This solution uses a NW BPM to save away the Token and the Connection URL on to the runtime cache to be used during the actual connection.

 

Flow Diagram

Image 1: Pictorial Representation of the implementation

Implementation Steps

Step 1:

Use a trigger file to start your BPM at regular intervals.

Setup an ICO/iFlow to trigger the BPM at 30 mins / 1 hr intervals

ID Config:

Sender Channel:

ICO to BPM:

 

Step 2:

BPM Process

Image 2: BPM Workflow & Steps. Courtesy: NWDS

Tip: Salesforce token is over 100 characters. The limit of the cache variable is 100 characters. Hence we have to save it as 2 parts.

2.1 Login to SFDC

  • Create ICO/iFlow to login to SFDC
  • Capture the following from Login Response
    • Token (2 Parts) as mentioned
    • URL

2.2 Value Mapping Interface

Create a Re-Usable ICO/iFlow for value Mapping Interface

  • ValueMapping interface used: ValueMappingAbsSync (standard)
  • Sample Input Values:
    • Agency: “Token1”
    • Grp_id: <GUID>
    • Grp_name: <GroupName>
    • Operation: Insert
    • Scheme: ID1
    • Text: Token1(first 90 chars)

 

Tip: You can create a Value Mapping interface in the Directory (not shown here) and use its reference for updating all 3 Value mappings from the BPM

 

Repeat the Value mapping for the next 2 steps, Token2, URL

 

2.3: Operation mapping for the Value Mapping update interface

Image 4: Mapping for VM interface. Courtesy: SAP PI ESR

The Operation mapping needs a Delete Operation followed by Insert Operation. This will replace existing values with new values.

 

Step 3: Using the Token and URL from Cache

3.1 Retrieving the Token ID and URL from cache

Image 5: Header Mapping to export token. Courtesy: SAP PI ESR

REST

3.2: Sample UDF code for Token Export:

{
String Url = "";

Url = SFDCserverUrl.substring(SFDCserverUrl.indexOf("https"), (SFDCserverUrl.indexOf("/Soap/")));

DynamicConfiguration conf1 = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);

DynamicConfigurationKey key1 = DynamicConfigurationKey.create("http:/"+"/sap.com/xi/XI/System/REST","access_token");
	
conf1.put(key1, token);
								
DynamicConfiguration conf2 = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
								
DynamicConfigurationKey key2 = DynamicConfigurationKey.create("http:/"+"/sap.com/xi/XI/System/REST","serverUrl");
								
conf2.put(key2, Url);

DynamicConfiguration conf3 = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
							  
DynamicConfigurationKey key3 = DynamicConfigurationKey.create("http:/"+"/sap.com/xi/XI/System/REST","Param1");
								conf3.put(key3,Param1);

DynamicConfiguration conf4 = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION);
								
DynamicConfigurationKey key4 = DynamicConfigurationKey.create("http:/"+"/sap.com/xi/XI/System/REST","Param2");
								conf4.put(key4,Param2);				
return"";
}

Salesforce REST Receiver:

Image 6: Receiver REST Channel. Courtesy: SAP PI ID

Note: See SAP Note 2174651 for security risks

 

SOAP Adapter:

3.3: Sample Java mapping code for SOAPĀ 

Use Dynamic Configuration to retrieve the values from cache to prepare the SOAP Envelope. Sample Method is provided.

	private void getSessionIdFromVM() throws ValueMappingException {
		
		String context = "http://sap.com/xi/XI";
		// get Token ID1
		String senderAgency = "SenderAgencyForToken";
		String senderScheme = "SenderSchemeForToken";
		String receiverAgency = "Token";
		String receiverScheme = "Token1";		
		String token1 = "";		
		String token2 = "";		
		String url = "";

		IFIdentifier src = XIVMFactory.newIdentifier(context, senderAgency, senderScheme);
		IFIdentifier dst = XIVMFactory.newIdentifier(context, receiverAgency , receiverScheme);
		try {
			token1 = XIVMService.executeMapping(src, dst, "Token1");
		} catch (ValueMappingException e) {
		// message the following if not found:
	//		return  ("no ValueMapping found for [" + "Token1" + "]");
		}
		// get Token ID2
		senderAgency = "SenderAgencyForToken";
		senderScheme = "senderSchemeForToken";
		receiverAgency = "Token";
		receiverScheme = "Token2";				
		src = XIVMFactory.newIdentifier(context, senderAgency, senderScheme);
		dst = XIVMFactory.newIdentifier(context, receiverAgency , receiverScheme); 
		try {
			token2 = XIVMService.executeMapping(src, dst, "Token2");
		} catch (ValueMappingException e) {
		// message the following if not found:
	//		return  ("no ValueMapping found for [" + "Token2" + "]");
		}
		// get URL
		senderAgency = "SenderAgencyForURL";
		senderScheme = "SenderSchemeForURL";
		receiverAgency = "URLValue";
		receiverScheme = "URL";		
		src = XIVMFactory.newIdentifier(context, senderAgency, senderScheme);
		dst = XIVMFactory.newIdentifier(context, receiverAgency , receiverScheme);
		try {
			url = XIVMService.executeMapping(src, dst, "URL");
	//	return res;
		} catch (ValueMappingException e) {
		// message the following if not found:
	//		return  ("no ValueMapping found for [" + "URL" + "]");		
	}
		sessionId = token1 + token2;
		SFDCserverUrl = url;		
	}

Conclusion:

I used re-usable ICO/iFlows to update the Value Mappings for each token that is needed for API connectivity. Once the setup for capturing the Token information is completed, the Java mappings and UDF’s are re-usable for your REST and SOAP connections.

 

Please leave your comments, feedback which are very much appreciated.

 

Best Regards,

Paul.

Note: All images/code is my own development

 

 

 

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.