Skip to Content
Technical Articles
Author's profile photo Bhalchandra Wadekar

Cloud Platform Integration: Enrich your content with ProcessDirect

In this blog, the limitations of the Content Enricher component are listed. Next, a solution to overcome said limitations is demonstrated with an example.

Content Enricher

Content Enricher is a message transformer that uses an external data source to augment a message with missing information [1].

Content Enricher in SAP Cloud Platform Integration

“The content enricher adds the content of a payload with the original message in the course of an integration process. This converts two separate messages into a single enhanced payload.” [2].

Here are some blogs that demonstrate the use of Content Enricher using SuccessFactors adapter

Limitations

  • Only supports SuccessFactors, Soap1.x, and OData adapters
  • Only supports XML format
  • External data source services requiring a request body (other than the current one in the exchange) are not supported

Scenario

Let us consider a business use case showcasing limitations of Content Enricher component in SAP CPI.

Orders will be transferred from an Order Management System (OMS). The OMS exposes Order data using the OData protocol. The receiver wants the customer’s information for each order in addition to the order data. A Customer Relationship Management System (CRM) maintains customer information and exposes the data as an HTTP service and supports JSON format only.

Note: Northwind Test Service is used to act as OMS and CRM [3].

Implementation

The key to the solution is the ProcessDirect adapter. The ProcessDirect adapter can be used to establish communication between integration processes within the same tenant [4].

External Data Source Integration Process

To overcome Content Enricher’s limitations, we will prepare a separate integration process to

  • Invoke the external data source service using HTTP adapter but expose using ProcessDirect adapter
  • Prepare the response body in XML format

The External Data Source Integration Process expects orders having CustomerID. Then, the CustomerID filter is prepared to make the HTTP request to CRM. Next, service is invoked. Finally, JSON output is converted to XML format.

To Content Enricher, this integration process acts as External Data Source instead of CRM.

Main Integration Process

The main integration process

  1. Gets orders from OMS
  2. Uses Content Enricher with ProcessDirect adapter
  3. Logs the body

Content Enricher is configured as follows:

Example Run

Inside Main Integration Process

The main integration process runs once.

An example output of getting orders is

<Orders>
	<Order>
		...
		<OrderID>10248</OrderID>
		...
		<CustomerID>VINET</CustomerID>
		...
	</Order>
	<Order>
		...
		<OrderID>10249</OrderID>
		...
		<CustomerID>TOMSP</CustomerID>
		...
	</Order>
	...
</Orders>

This will be supplied to the External Data Source Integration Process as input.

Inside External Data Source Integration Process

From the input, CustomerID filter is prepared for $filter parameter:

CustomerID eq ‘VINET’ or CustomerID eq ‘TOMSP’ …

An HTTP GET request is performed

Endpoint https://services.odata.org/V2/Northwind/Northwind.svc/Orders
Query Parameters
$format JSON
$filter CustomerID eq ‘VINET’ or CustomerID eq ‘TOMSP’ …

The output of the HTTP request

{
	"d": {
		"results": [
			{
				...,
				"CustomerID": "TOMSP",
				"CompanyName": "Toms Spezialitäten",
				...
			},
			{
				...,
				"CustomerID": "VINET",
				"CompanyName": "Vins et alcools Chevalier",
				...
			},
			...
		]
	}
}

Finally, the output is converted to XML format ready to be used by Content Enricher

<d>
	<results>
		...
		<CustomerID>TOMSP</CustomerID>
		<CompanyName>Toms Spezialitäten</CompanyName>
		...
	</results>
	<results>
		...
		<CustomerID>VINET</CustomerID>
		<CompanyName>Vins et alcools Chevalier</CompanyName>
		...
	</results>
	...
</d>

Note that further actions could be performed on XML data but are skipped to keep the example simple.

Examples of further actions can be

  • Removing the metadata and deferred links
  • Renaming d tag to Customers and results tag to Customer

Back to Main Integration Process

Order data is enriched with Customer details using Content Enricher and the body is logged.

<Orders>
	<Order>
		...
		<OrderID>10248</OrderID>
		...
		<CustomerID>VINET</CustomerID>
		<results>
			...
			<CustomerID>VINET</CustomerID>
			<CompanyName>Vins et alcools Chevalier</CompanyName>
			...
		</results>
		...
	</Order>
	<Order>
		...
		<OrderID>10249</OrderID>
		...
		<CustomerID>TOMSP</CustomerID>
		<results>
			...
			<CustomerID>TOMSP</CustomerID>
			<CompanyName>Toms Spezialitäten</CompanyName>
			...
		</results>
		...
	</Order>
	...
</Orders>

Conclusion

In summary, using ProcessDirect adapter to develop an integration process to act as External Data Source has several advantages as follows:

  • Preparation of external data in XML format
  • The External Data Source can use any communication protocol and may expect body in the request payload
  • Extra transformations can be performed on data before feeding the data to Content Enricher

References

[1] Enterprise Integration Patterns – Content Enricher. 2018. Enterprise Integration Patterns – Content Enricher. [ONLINE] Available at https://www.enterpriseintegrationpatterns.com/patterns/messaging/DataEnricher.html. [Accessed 22 July 2018].

[2] SAP Help Portal. 2018. Define Content Enricher. [ONLINE] Available at: https://help.sap.com/viewer/fd940ad7e2034505a055f14e457c6d5b/Cloud/en-US/8827f9feb94e4264aaf42ac1c6ce11b7.html. [Accessed 22 July 2018].

[3] https://services.odata.org/V2/Northwind/Northwind.svc

[4] SAP Help Portal. 2018. Configure Communication Channel with ProcessDirect Adapter. [ONLINE] Available at: https://help.sap.com/viewer/149e1c8f944645c79f7989e6ed7f5042/Cloud/en-US/74457187451f431298355fbbf807d086.html. [Accessed 22 July 2018].

 

Authors

Assigned Tags

      8 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Agnieszka Domanska
      Agnieszka Domanska

      Simple! Informative! Thank you. Keep posting, please!

      Author's profile photo Jelle De Bruijn
      Jelle De Bruijn

      Hi Sanjali/Bhalchandra,

      Have you tried to use the content in your sourcemessage after the JSON to XML converter? As far as I know you have to add the 'nodes/subtrees' of the enriched fields manually to your xsd/wsdl sourcemessage, right? Or do you have an other way :)?

      Regards, Jelle

       

       

      Author's profile photo Bhalchandra Wadekar
      Bhalchandra Wadekar
      Blog Post Author

      Hi Jelle,

      In the example scenario, after JSON to XML converter, only response from External Data Source is available. The next step after JSON to XML converter is Content Enricher. After Content Enricher, source message is available enriched with external data. At this time, if you need the XML Schema of enriched message you can:

      1. Get the schema from Target System
      2. Prepare the schema manually

      Kind regards,

      Bala

      Author's profile photo Pavan G
      Pavan G

      Hi Bhalchandra Wadekar ,

      Thanks for the detailed blog.

      I am using the above approach in my requirement.

      Requirement:

      Send invoices to ECC. But, the receiver wants the customer’s information for each invoice.

       

      I need to call the customer from Receiver3 based on the customerID present in the Get_Invoices payload which is dynamic.

      Please let me know, how I can filter customerID and do the get call?

      Regards,

      Pavan

       

      Author's profile photo Bhalchandra Wadekar
      Bhalchandra Wadekar
      Blog Post Author

      Hi Pavan G,

      The Input from the Main Integration Process is:

      <Orders>
      	<Order>
      		...
      		<OrderID>10248</OrderID>
      		...
      		<CustomerID>VINET</CustomerID>
      		...
      	</Order>
      	<Order>
      		...
      		<OrderID>10249</OrderID>
      		...
      		<CustomerID>TOMSP</CustomerID>
      		...
      	</Order>
      	...
      </Orders>

      I used Groovy Script to prepare the request for getting the Customers like so:

      import com.sap.gateway.ip.core.customdev.util.Message
      
      def Message processData(Message message) {
          
          def Orders = new XmlSlurper().parse(message.getBody(Reader))
          
          def customerIdFilter = Orders.Order.collect {
              "CustomerID eq '${ it.CustomerID }'"
          }.join(' or ')
          
          message.setProperty('CustomerIdFilter', customerIdFilter)
          
          return message
      }

      In HTTP Adapter configuration, I set Query as $filter=${property.CustomerIdFilter}&$format=json.

      Hope this helps,

      Bala

      Author's profile photo Pavan G
      Pavan G

      Thanks, Bhalchandra Wadekar

      It worked for me.

      I have also tried another way of doing it.

      I saved the customerID XPath in the exchange property of Content modifier and used in the HTTP address as https:/HOST/v1/invoices/${property.customerID}

      This will fetch the customer which is coming from the Get_invocies XML.

      Regards,

      Pavan

      Author's profile photo T S Shankar Narayanan
      T S Shankar Narayanan

      Hi BhalChandar.

       

      Does it make sense to add the $filter property in the Content Enricher Lookup even when the Key ELement of the Original message is already a unique key like person-id-external instead of say location code or customer id, which need not be unique as multiple orderIDs can have same customer ID in your example?

      In other words,

      my scenario: I get Employee master data using CompoundEmployee SFAPI, and for every employee I have to get additional information from a custom portlet. I am planning to use a Content Enricher to look up SuccessFactors with OData V2, and want to enhance the message with the information from Custom Portlet. So, I will be passing the employee id as the Key Element in the "Original Message" Parameter.

      So, for my scenario, do I still need to pass the $filter parameter with relevant employee ids, as I need the information for all employee id in the XML?

      Author's profile photo Bhalchandra Wadekar
      Bhalchandra Wadekar
      Blog Post Author

      Hi T S Shankar Narayanan,

      The $filter helps in reducing the response payload. This way the Content Enricher performs the enrichment faster.

      In your case, if you need all employee data, no need to use the $filter parameter.

      Hope this helps,
      Bala