What is SAP Event Mesh?
SAP Event Mesh allows applications to communicate through asynchronous events. Experience greter agility and scalability when you create responsive applications that work independently and participate in event-driven business processes across your business ecosystem. Events are associated with a topic to achieve the publish-subscribe model. Topics are managed through queue subscriptions. SAP or non-SAP applications can subscribe to the topic via queue subscriptions to access messages from the event source. SAP Event Mesh enables a sending application to publish messages to a topic that directly sends the message to the queue to which it is bound.
Event Mesh Use Cases
Microservices Integrations, E-commerce, Customer Support, Financial Services, IoT Connectivity.
Business Benefits Of Event Mesh
Event Mesh Flow Chart
Event Mesh Setup
Required:
1- On SAP BTP Cockpit, we must search and select Event Mesh from Service Marketplace.
Service Marketplace
2-Later, create subscriptions of the Event Mesh.
Subscriptions
3-After creating subscription, we need to define the roles of Event Mesh to our user.
Security–> Role Collections
Role Collections
4-Now, we will go to : Security–> Entitlements
Entitlements
5-Create Instance of Event Mesh
Instance
{
"emname": "S4S",
"namespace": "sap/S4HANAPB/S4S",
"options": {
"management": true,
"messaging": true,
"messagingrest": true
},
"resources": {
"units": "10"
},
"rules": {
"queueRules": {
"publishFilter": [
"${namespace}/*"
],
"subscribeFilter": [
"${namespace}/*"
]
},
"topicRules": {
"publishFilter": [
"${namespace}/*"
],
"subscribeFilter": [
"${namespace}/*"
]
}
},
"version": "1.1.0"
}
Instance View
Instance of Event Mesh
6-Now, we click on the Event Mesh under Subscriptions.
Click on Go To Application
7-You will access the as name of S4S that we created on a new page.
Message Clients
8-From here, we will take steps to ensure that the Event Mesh can send requests to CPI. First we need to create a queue.
Create Queues step 1
Create Queues Step 2
Create Queues step 3
9- I indicated that the interaction between Event Mesh and the CPI can be facilitated using either HTTP or AMQP. We will proceed with HTTP. To enable this, CPI will also establish Event Mesh communication over a designated CPI link. This CPI link must also be specified within the Communication Scenarios of S/4 Hana(module-side). This is because it will gain access to the established queues through Event Mesh Communication Scenarios.
Create Webhook Step 1
Create Webhook Step 2
Once the webhook is created, the event Mesh process is completed. What’s important after that is integration development. After triggering Event Mesh from S/4 Hana, how the structure will reach CPI should be observed. We will proceed with an example scenario.
You can take a look at this blog for detailed information about Webhook and Queue parameters.
Certainly, let’s create a scenario for sending information from S/4 HANA to a 3rd-party system via CPI when a new product is created or modified.
Scenario: Sending Product Updates from S/4 HANA to a 3rd-Party System via CPI
This scenario outlines the flow of information from S/4 HANA to a 3rd-party system through CPI when a new product is created or modified. It’s crucial to configure S/4 HANA, Event Mesh, and CPI appropriately and ensure that data mappings and error handling are well-defined for a successful integration process.
S/4Hana-Event Mesh-CPI relations
First, I mentioned the need to generate a link in CPI for S/4 HANA to be able to trigger it. You can start by creating an empty flow in CPI solely for the purpose of generating the link. Then, you can observe what structure is received when S/4 HANA triggers it. In our scenario, the material number is the information sent from S/4 HANA. Based on this information, an OData link is expected to be provided to the CPI, where CPI will make a GET request to S/4 HANA based on the received material number through the Products service.
Example Structure:
{
"type": "sap.s4.beh.billofmaterial.v1.BillOfMaterial.Created.v1",
"specversion": "1.0",
"source": "/default/sap.s4.beh/--",
"id": "--",
"time": "2023-10-02T14:19:35Z",
"datacontenttype": "application/json",
"data": {
"BillOfMaterial": "00000034",
"BillOfMaterialCategory": "M",
"BillOfMaterialVariant": "1",
"BillOfMaterialVersion": "",
"EngineeringChangeDocument": "",
"Material": "1001008",
"Plant": "",
"BillOfMaterialHeaderUUID": "194ead30-cb27-1ede"
}
}
Based on the data received from S/4 HANA, a call will be made to S/4 HANA via OData using the material number. This call will retrieve information related to that specific material. From the retrieved information, the necessary data will be forwarded to the 3rd-party system.The information retrieved via the GET method will be sent to the 3rd-party system using the PATCH method, facilitated by a REST link. It’s important to ensure that proper data mapping is performed if needed. It should be noted that the key focus here is to ensure that when a product is created or modified, this information is instantly sent to the 3rd-party system for real-time updates.
For example, let’s assume the 3rd-party fields are as follows:
3rdParty fields
Note: In the mentioned scenario, the 3rd-party service (receiver service) authenticates using a bearer token. Therefore, a separate flow for the token service has been developed, and this service uses the token as a global variable
CPI Flow
Firstly, in order to capture the ‘Material’ field from the request coming from Event Mesh, we use ‘JSON to XML’ conversion. The reason for holding this field as an XPath is to dynamically extract the value of ‘Material’ when making a GET request to S/4 HANA.
Content Modifier_Headers
OData-Get Method
Considering the structure of the 3rd-party system, not all fields from the response are needed when making a GET call. Therefore, fields should be selected based on the 3rd-party system’s requirements. As ‘Material’ is a dynamic value, it should be provided as a property.
Processing Parameters
In this example scenario, a Filter has been used. The reason for this is that after making a GET call, some unwanted fields are present in the response. These unwanted fields were causing a 400 error when accessing the 3rd-party service. Therefore, the issue has been resolved using a Filter.
Filter
Subsequently, mapping was performed with the sample structure of the 3rd-party service to match the fields. After mapping, as the structure was still held in XML, an XML to JSON converter was used since the service expected the data in JSON format.
The final step involved storing the response headers from the GET in the GetResponseBody Content Modifier.
Content Modifier GetResponseBody
Content Modifier GetResponseBody- Message Body
Patch Method to 3rdParty Service
The Groovy script for Error Handling:
import com.sap.gateway.ip.core.customdev.util.Message;
def Message processData(Message message) {
// get a map of iflow properties
def map = message.getProperties();
// get an exception java class instance
def ex = map.get("CamelExceptionCaught");
if (ex!=null) {
// an http adapter throws an instance of org.apache.camel.component.ahc.AhcOperationFailedException
if (ex.getClass().getCanonicalName().equals("org.apache.camel.component.ahc.AhcOperationFailedException")) {
// save the http error response as a message attachment
def messageLog = messageLogFactory.getMessageLog(message);
messageLog.addAttachmentAsString("http.ResponseBody", ex.getResponseBody(), "text/plain");
// copy the http error response to an iflow's property
message.setProperty("http.ResponseBody",ex.getResponseBody());
// copy the http error response to the message body
message.setBody(ex.getResponseBody());
// copy the value of http error code (i.e. 500) to a property
message.setProperty("http.StatusCode",ex.getStatusCode());
// copy the value of http error text (i.e. "Internal Server Error") to a property
message.setProperty("http.StatusText",ex.getStatusText());
}
}
return message;
}
Through Error Handling, we can catch any error returned from the service.
Now we can test the service. We can request the SAP consultant to trigger it from the module, or we can trigger it ourselves using the request we have in Postman.
Trace
Exchange Properties
Header