Technical Articles
EIPinCPI – Command Message
Previous – Message | Index | Next – Document Message
This week, we’re going to study a variation of Message pattern known as Command Message.
When do I use this pattern?
As the name suggests, this pattern applies when the functionality of the receiver system is invoked. For example, invoking a SOAP operation, invoking an OData function import, invoking a BAPI, and so on.
Command Message in CPI
In this section, I’ll go through the three examples of Command Message mentioned above.
Invoking a SOAP operation
The first example of Command Message pattern is invoking a SOAP operation. I’ll use temperature conversion web service provided by W3Schools. The service lets you convert temperature value from Fahrenheit to Celsius and vice versa. I’m curious what 37 ℉ is in Celsius.
Integration Flow
The integration flow starts as soon as it is deployed. Then, the input is set as the message body. Then, FahrenheitToCelsius operation is invoked. Finally, the response is logged.
Basically, I am “command”ing W3 Schools to convert the given temperature from Fahrenheit to Celsius. Therefore, the pattern is the Command Message pattern.
Steps
Start Immediately
I used Timer Start with the schedule of Run Once to trigger the flow as soon as it is deployed.
Prepare Command Message
Next, we prepare the input message. So, I set the body using a Content Modifier. You can change the value of Fahrenheit element from 37 to any temperature you like.
<FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/">
<Fahrenheit>37</Fahrenheit>
</FahrenheitToCelsius>
Convert Fahrenheit to Celsius
In this step, I used a Request-Reply component to send the command to W3 Schools using the SOAP adapter. To configure the adapter, I downloaded the WSDL from W3 Schools, configured the WSDL under the Connection configuration for the adapter, and set the address to https://www.w3schools.com/xml/tempconvert.asmx.
Log
The final step is to monitor the response. I’ll use the script below to attach the response body to message log.
import com.sap.gateway.ip.core.customdev.util.Message
def Message processData(Message message) {
def messageLog = messageLogFactory.getMessageLog(message)
messageLog.addAttachmentAsString('Temperature in Celsius', message.getBody(String), 'application/xml')
return message
}
Output
When the integration flow is deployed, it executes the steps immediately and the response from W3 Schools can be monitored. 37 ℉ is 2.77777777777778 ℃.
<FahrenheitToCelsiusResponse xmlns="https://www.w3schools.com/xml/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FahrenheitToCelsiusResult>2.77777777777778</FahrenheitToCelsiusResult>
</FahrenheitToCelsiusResponse>
Invoking a function import of an OData service
The second example is invoking a function import of an OData service. I’ll use the SAP Gateway Demo System. You can read more about the system and how to get a user in Andre‘s blog New SAP Gateway Demo System Available. I’ll be using the Manage Products API for my example. Specifically, I’ll be copying the product with Id ‘HT-1091’.
Integration Flow
Similar to the previous example, this integration flow starts as soon as it is deployed. Then, CopyProduct function import is invoked. Finally, the response is logged.
Once again, I am “command”ing ES5 to copy the product. Therefore, the pattern is the Command Message pattern.
Steps
I’ll only include the OData adapter step here as other steps have been explained above.
Copy Product
Once again, I am using the Request-Reply component to send the command to ES5. However, the ES5 system speaks in OData. Here’s the OData adapter configuration:
Tab | Parameter | Value |
Connection | Address | https://sapes5.sapdevcenter.com/sap/opu/odata/sap/EPM_REF_APPS_PROD_MAN_SRV |
Credential Name | ES5 Credentials | |
Processing | Operation Details | Function Import |
Resource Path | Click ‘Select’ and follow the wizard. |
Output
When this integration flow is deployed, product ‘HT-1091’ is copied and the created product draft ‘EPM-033190’ is returned.
<ProductDrafts>
<ProductDraft>
<Description>PC multimedia speakers - 10 Watt (Total) - 2-way</Description>
<CreatedAt>2019-12-22T10:02:07.446</CreatedAt>
<WeightUnit>KGM</WeightUnit>
<ProductId>EPM-033190</ProductId>
<DimensionUnit>CMT</DimensionUnit>
<Name>Blaster Extreme</Name>
<LastModified>2019-12-22T10:02:07.446</LastModified>
<CurrencyCode>USD</CurrencyCode>
<DimensionWidth>13.000</DimensionWidth>
<WeightMeasure>1.400</WeightMeasure>
<MainCategoryName>Computer Components</MainCategoryName>
<CreatedBy>P1941728552</CreatedBy>
<MainCategoryId>Computer Components</MainCategoryId>
<SubCategoryId>Speakers</SubCategoryId>
<ImageUrl>/sap/public/bc/NWDEMO_MODEL/IMAGES/HT-1091.jpg</ImageUrl>
<DimensionHeight>17.500</DimensionHeight>
<IsNewProduct>true</IsNewProduct>
<SubCategoryName>Speakers</SubCategoryName>
<SupplierId>100000000</SupplierId>
<Price>26.00</Price>
<SupplierName>SAP</SupplierName>
<Id>EPM-033190</Id>
<IsDirty>false</IsDirty>
<ExpiresAt>2019-12-22T10:32:07.446</ExpiresAt>
<DimensionDepth>11.000</DimensionDepth>
<QuantityUnit>EA</QuantityUnit>
</ProductDraft>
</ProductDrafts>
Invoking a BAPI in ECC
Integration Flow
Similar to the previous examples, this integration flow starts as soon as it is deployed. Then, the input is set as the message body. Then, BAPI_CURRENCY_GETDECIMALS BAPI is invoked. Finally, the response is logged.
And once again, I am “command”ing ECC to get currency decimals. Therefore, the pattern is the Command Message pattern.
Steps
Here, the RFC Adapter is used to invoke BAPI in an ECC system. The configurations for RFC adapter require a lot of steps, so, I refer you to Meenakshi‘s blog on how to use RFC adapter in SAP Cloud Platform Integration to execute remote function module on the ABAP system.
Input and Output
I wonder how many decimals does ECC use for the Great British Pound. Let’s “command” ECC to get that information.
Here’s the input:
<rfc:BAPI_CURRENCY_GETDECIMALS xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<CURRENCY>GBP</CURRENCY>
</rfc:BAPI_CURRENCY_GETDECIMALS>
And the answer is 2 decimals are used for Great British Pound. That makes sense. As one pound can be divided into 100 pence, 2 decimals should cover it.
<rfc:BAPI_CURRENCY_GETDECIMALS.Response xmlns:rfc="urn:sap-com:document:sap:rfc:functions">
<CURRENCY_DECIMALS>
<CURRENCY>GBP</CURRENCY>
<CURDECIMALS>2</CURDECIMALS>
<CURRENCY_ISO>GBP</CURRENCY_ISO>
</CURRENCY_DECIMALS>
<RETURN>
<TYPE/>
<CODE/>
<MESSAGE/>
<LOG_NO/>
<LOG_MSG_NO>000000</LOG_MSG_NO>
<MESSAGE_V1/>
<MESSAGE_V2/>
<MESSAGE_V3/>
<MESSAGE_V4/>
</RETURN>
</rfc:BAPI_CURRENCY_GETDECIMALS.Response>
Integration Recipe
The code is available as Integration Recipe on SAP’s official repository: EIP-MessageConstruction-CommandMessage
Conclusion
Command Message pattern is a variation of Message pattern. It should be used when invoking functionality in the receiver system.
References/Further Readings
- Command Message Pattern in Enterprise Integration Patterns
- Andre‘s blog New SAP Gateway Demo System Available
- Meenakshi‘s blog on how to use RFC adapter in SAP Cloud Platform Integration to execute remote function module on the ABAP system
- CPI Components
Hope this helps,
Bala