Skip to Content
Technical Articles

Getting clear with SAP Integration Suite Content Modifier

Introduction

In this blog post we will take a look at SAP Integration Suite Content Modifier and try to describe one of the way, where it can be used.

During the test case we will use SAP Integration Suite and SoapUI.

In general, Content Modifier allows you to change the content of incoming message.

Building an Integration Flow

In the 1st step let´s create a new package. This could be done in Design view of SAP Integration Suite. You have to provide package name, technical name and description.Create%20Package

Fill%20necessary%20fields

Fill necessary fields

Now we will navigate to Artifacts tab and add Integration Flow to the created package. Maintain Integration Flow related information.

Add%20Integration%20Flow

Add Integration Flow

Maintain%20Name%20and%20ID

Maintain Name

Open your Integration Flow and go to the Edit mode.

Open%20IFlow%20and%20go%20to%20Edit%20mode

Open IFlow and go to Edit mode

Select the Sender box, click the connector icon and drag the cursor to the target shape – Start. Then release the mouse button.

After this operation you have to choose the connection type between the Sender and SAP  Integration Suite server. Let´s pick SOAP protocol.

Select%20SOAP%20protocol

Select SOAP protocol

Then choose the arrow between Sender and Start blocks. Now it is in orange and beneath the process model you can see the properties of the connection.

Here we will maintain the SOAP adapter address parameter in Connection tab. Give any name to the address.

Leave the other parameters as it is.

Maintain SOAP parameter

Now we can move to adding Content Modifier in our Integration Flow. Select if from the Palette and move your mouse pointer to the Integration Process box. Then click again to position the Content Modifier.

Select%20content%20modifier%20from%20the%20palette

Select Content Modifier from the palette

Add%202%20Content%20Modifiers

Add second Content Modifiers

Setting up Content Modifiers

The idea of the use case is to put data via the 1st Content Modifier into the header of the message and into the properties area of the exchange. Then, via the 2nd Content Modifier we retrieve the stored data and create a resulting message. It means, that with the help of Content Modifiers we can store data in different locations and operate with them later.

To provide content enricher parameters, firstly we need to have example message. Let´s take it from this web page.

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <m:GetEndorsingBoarder xmlns:m="http://namespaces.snowboard-info.com">
      <manufacturer>K2</manufacturer>
      <model>Fatbob</model>
    </m:GetEndorsingBoarder>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

We will also need WSDL description to know the structure of the incoming message.

<?xml version="1.0"?>

<!-- root element wsdl:definitions defines set of related services -->
<wsdl:definitions name="EndorsementSearch"
  targetNamespace="http://namespaces.snowboard-info.com"
  xmlns:es="http://www.snowboard-info.com/EndorsementSearch.wsdl"
  xmlns:esxsd="http://schemas.snowboard-info.com/EndorsementSearch.xsd"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  <!-- wsdl:types encapsulates schema definitions of communication types; here using xsd -->
  <wsdl:types>

    <!-- all type declarations are in a chunk of xsd -->
    <xsd:schema targetNamespace="http://namespaces.snowboard-info.com"
      xmlns:xsd="http://www.w3.org/1999/XMLSchema">

      <!-- xsd definition: GetEndorsingBoarder [manufacturer string, model string] -->
      <xsd:element name="GetEndorsingBoarder">
	<xsd:complexType>
	  <xsd:sequence>
	    <xsd:element name="manufacturer" type="string"/>
            <xsd:element name="model" type="string"/>
	  </xsd:sequence>
	</xsd:complexType>
      </xsd:element>

      <!-- xsd definition: GetEndorsingBoarderResponse [... endorsingBoarder string ...] -->
      <xsd:element name="GetEndorsingBoarderResponse">
	<xsd:complexType>
	  <xsd:all>
	    <xsd:element name="endorsingBoarder" type="string"/>
	  </xsd:all>
	</xsd:complexType>
      </xsd:element>

      <!-- xsd definition: GetEndorsingBoarderFault [... errorMessage string ...] -->
      <xsd:element name="GetEndorsingBoarderFault">
	<xsd:complexType>
	  <xsd:all>
	    <xsd:element name="errorMessage" type="string"/>
	  </xsd:all>
	</xsd:complexType>
      </xsd:element>

    </xsd:schema>
  </wsdl:types>

  <!-- wsdl:message elements describe potential transactions -->

  <!-- request GetEndorsingBoarderRequest is of type GetEndorsingBoarder -->
  <wsdl:message name="GetEndorsingBoarderRequest">
    <wsdl:part name="body" element="esxsd:GetEndorsingBoarder"/>
  </wsdl:message>

  <!-- response GetEndorsingBoarderResponse is of type GetEndorsingBoarderResponse -->
  <wsdl:message name="GetEndorsingBoarderResponse">
    <wsdl:part name="body" element="esxsd:GetEndorsingBoarderResponse"/>
  </wsdl:message>

  <!-- wsdl:portType describes messages in an operation -->
  <wsdl:portType name="GetEndorsingBoarderPortType">

    <!-- the value of wsdl:operation eludes me -->
    <wsdl:operation name="GetEndorsingBoarder">
      <wsdl:input message="es:GetEndorsingBoarderRequest"/>
      <wsdl:output message="es:GetEndorsingBoarderResponse"/>
      <wsdl:fault message="es:GetEndorsingBoarderFault"/>
    </wsdl:operation>
  </wsdl:portType>

  <!-- wsdl:binding states a serialization protocol for this service -->
  <wsdl:binding name="EndorsementSearchSoapBinding"
                type="es:GetEndorsingBoarderPortType">

    <!-- leverage off soap:binding document style @@@(no wsdl:foo pointing at the soap binding) -->
    <soap:binding style="document"
                  transport="http://schemas.xmlsoap.org/soap/http"/>

    <!-- semi-opaque container of network transport details classed by soap:binding above @@@ -->
    <wsdl:operation name="GetEndorsingBoarder">

      <!-- again bind to SOAP? @@@ -->
      <soap:operation soapAction="http://www.snowboard-info.com/EndorsementSearch"/>

      <!-- furthur specify that the messages in the wsdl:operation "GetEndorsingBoarder" use SOAP? @@@ -->
      <wsdl:input>
        <soap:body use="literal"
		   namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"
		   namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </wsdl:output>
      <wsdl:fault>
        <soap:body use="literal"
		   namespace="http://schemas.snowboard-info.com/EndorsementSearch.xsd"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>

  <!-- wsdl:service names a new service "EndorsementSearchService" -->
  <wsdl:service name="EndorsementSearchService">
    <wsdl:documentation>snowboarding-info.com Endorsement Service</wsdl:documentation> 

    <!-- connect it to the binding "EndorsementSearchSoapBinding" above -->
    <wsdl:port name="GetEndorsingBoarderPort"
               binding="es:EndorsementSearchSoapBinding">

      <!-- give the binding an network address -->
      <soap:address location="http://www.snowboard-info.com/EndorsementSearch"/>
    </wsdl:port>
  </wsdl:service>

 </wsdl:definitions>

The 1st Content Modifier will retrieve Manufacturer from the message and store it in the header of the message. It will also take the complete message body and store this text in the properties area. In such a manner we, on the one hand, access single field and, on the other, retrieve and store as property the complete complex structure.

So, let´s select the 1st Content Modifier – it uses the Message Header and the Exchange Property areas to write the data. Therefore let´s go to Message Header tab in the top row and add new line of actions. Here we define the name, under which the data would be stored in the message header – “Manufacturer”.

In the next step we define, how to access the value in the message and the type of data to extract. Select XPath from dropdown list – it is the way to retrieve data from XML document. The expression in our case would be //manufacturer, type – java.lang.String. With these settings we store manufacturer name in the message´s header.

First%20Content%20Modifier%20customizing

First Content Modifier customizing

Further we need to add settings, which will allow writing the complete body of a message into a property area of the exchange. We can do it on Exchange Property tab by adding a new row and setting the name, by which the message will be stored in the exchange property area – msg. As we need to store the complete message, let´s edit Value field with ${in.body} expression. This is Apache Camel syntax. The last step we need to do here is to change Type to Expression:

Content%20Modifier%20Customizing

First Content Modifier Customizing

Now let´s go to the customizing of the 2nd Content Modifier. We use it for creating the body of the final message.

Let´s select the 2nd Content Modifier and go to Message Body tab.

  1. Set Type to Expression;
  2. Define open and closing tags “result“.
  3. Then we place content of two variables “manufacturer” and “msg” between opening and closing “result” tags. We access the properties in the exchange area via variable property. And the data data, which are stored in header via variable header. Both of them are predefined in Apache Camel.

2nd%20Content%20Modifier%20Configuration

2nd Content Modifier Configuration

Deploy the Integration Flow

With these steps we finish configuration of the Integration Flow. Let´s save it and deploy:

Save%20and%20deploy

Save and deploy

Then we need to go to Operations view:

Operations%20View

Operations View

Select All in Manage Integration Content:

And make sure that the integration flow is successfully deployed:

From the window above we will also need the URL and WSDL, which you can download.

Test via SoapUI

On the next step we will need SoapUI. Open the program and create new SOAP Project:

SoapUi

SoapUi

Enter a Project Name and select WSDL file you saved earlier. Click OK.

Select the request, which was automatically created in newly opened window:

Replace the default code with our example request:

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <m:GetEndorsingBoarder xmlns:m="http://namespaces.snowboard-info.com">
      <manufacturer>K2</manufacturer>
    </m:GetEndorsingBoarder>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Make sure, that correct URL of the Integration Flow was entered via WSDL file:

Check%20URL

Check URL

And finally you can send the request. On the right-hand side you should get following result:

Response

Response

Conclusion

As you can see, now we have “manufacturer” value also outside the tags. This is the result of placing the response in the Message Body via the Content Modifier.

Clicking by Headers you can also see, that “manufacturer” value is also available there:

Headers

Headers

 

With this exercise you should have better understanding on the role of Content Enricher module and could start using it for more complicated scenarios.

 

2 Comments
You must be Logged on to comment or reply to a post.