Skip to Content
Technical Articles
Author's profile photo Martin Pankraz

Hey SAP, where is my Xbox? An insight into capitalizing on event-driven architectures

Fig. 1 illustration of supply chain challenge (left img src: BBC, right image src: futurezone.de)

Dear community,

Anyone out there still waiting for their next-gen console too? Due to supply-chain and sometimes even raw-material-availability challenges, many companies cannot drive sales as they would like to. To be fair, the Xbox is just one example of a product that is high in demand but short in supply. However, it makes a good headline 😉.

What if you could create a premium service that allows you to source that increased willingness to pay a higher price by notifying your VIP customer base early? When new stock arrives, you broadcast push notifications directly to their smartphones. How about enabling “early” purchase before the rest of the market right away?

Fancy some more motivating factors? We see services and aggregators for aspects of this use case going live a lot lately. Often, they have a fiddly and crowded website. Just search Xbox stock tracker/checker, locator, and the likes to get an idea. By the way, have you heard about Scalpers?They employ software like bots to discover and buy off newly arriving stock in almost real-time to re-sell it at a hefty premium on platforms like eBay. So, such a gated premium service (human registration required and not publicly searchable) would not only enhance business but also empower humans to beat the bots and their undesirable price inflation.

Leveraging the supply chain integration and data insight that SAP’s ERP has, we can implement a solution to address real buyers directly. By adding an event-based approach we add the real-time component to the mix that allows us to execute on that idea.

There are multiple ways to implement event-driven architectures with SAP sources. Some variations are limited to SAP BTP only, some allow open protocols and others require you to custom-build the final integration. We would like to name a few that we came across in our daily work integrating SAP.

Pay attention to the support of the Cloud Events standard. My list below shows the current state for ABAP systems to the best of my knowledge. This is a moving target and can change quickly as the standard spreads.

With the standard, major providers like SAP, Microsoft and others ensure event structure compatibility going forward. Have a look at this post by SAP on the strategic direction between SAP and Microsoft.

You can register early to participate in the new product wave on Azure and BTP. Focus is on SAP Event Mesh and Azure Event Grid integration.

List of popular event options, that we came across.

Approach Comment CloudEvents v1.0 support
S/4HANA Enterprise Event Enablement (SAP Business Events) This component is SAP native and part of S/4HANA and S/4HANA Cloud. It was built upon on SAP Business Even Handling (BEH). It is restricted to SAP Event Mesh. Have a look at this blog and this GitHub repos from SAP for more details. *
SAP NetWeaver Event Enablement Add-On (ASAPIO)

This component is a certified SAP native approach targeting SAP Event Mesh and SAP Integration Suite. The foundation is ASAPIO’s event framework. See also the associated Discovery Center Mission and repos.

Use function module /ASADEV/ACI_SAP_EM_CLOUDEV_FM to format your events accordingly.

ASAPIO Connector for Microsoft Azure Partner solution: Out-of-the-box capability to connect with Azure Integration Services and Event Hub.
Datavard Glue Partner solution: supports multiple targets including Azure based on http protocol.
ABAP SDK for Azure This open-source SDK comes with a set of classes to accelerate your custom Azure integration. It is provided by Microsoft Engineering. Custom build

*verified as of S/4HANA 2020. Prior versions produce Cloud Events lower than v1.0.

Do you have any more providers to add? Please leave a comment.

Going forward we will discuss an approach with cloud-native Azure components. For SAP BTP based alternatives check the SAP Event Mesh community and SAP Mobile Services.

Note: Below reference architecture and prototype are the result of joint work between Bart Delanghe, Thijs Zandvliet, Holger Bruchelt and me. I am just the lucky one that gets to publish this under my profile. Credit where credit is due: Bart, Thijs and Holger you are awesome!

Fig.2 architecture overview

Cloud Eventing or messaging? That is the question!

There is quite the debate within the SAP community if events should be adopted in their “purest” form or not. If so, an event would only contain an identifier and a note-worthy state change.

{
"id" : "123456789",
"state" : "BusinessPartner/created"
}

On the upside this is great for low overhead notifications, decoupling of integration, and minimisation of potential data exposure (imagine sensitive HR events from SuccessFactors for instance). On the downside it likely triggers multiple call-backs to the SAP backend to ask for more details by each interested consumer. SAP also uses the term “data” vs. “notification” events to distintguish between more sensitive signals (data privacy and protection + data loss prevention policies). S4 provides a generic “outbound” notification event for this purpose.

In a cloud native world with less limits regarding scalability we wouldn’t care and favour “pure” events to foster lower coupling of the integration. But the ABAP software monolith requires more caution when it comes to bombarding it with request. Anyone implemented a request-embargo or strong throttling during financial closing or nightly batch processing? 😉

To get the best of both approaches for the are discussed. The Cloud Events standard leaves quite some head room to add properties. That way communication becomes more meaningful right away for the subscribed consumers and eases the load on the backend with fewer callback scenarios. Architecture-wise we cause tighter coupling between the services because they adapt to a specific custom message schema. This can be mitigated by making the fields optional at the receiver.

For our reference implementation we designed a light message to incorporate additional relevant data re-using the SAP field names. It is up to you if you want to embed this in a cloud events wrapper (data section) or anything else.

{
"busobj":"LIKP",
"busobjname":"Outbound Delivery",
"objkey":"0080002839",
"event":"CREATED",
"date":"2021-12-06",
"time":"13:26:13",
"shipto":"USCU_L10",
"loadingdate":"2021-11-15",
"deliverydate":"2021-11-16",
"shipmentlines":[
    {"product":"MZ-FG-R100","quantity":5.000,"uom":"ST","salesorder":"0000002297"}
  ]
}

Let’s have a look at the moving parts

The journey of our Xbox scenario begins with VIP user subscribing to stock arrival notifications for the Xbox series X on the Android app.

Curious VIP user hooked? Check!

Fig.3 Screenshot from Android app (including debug info)

Once new stock arrives it gets processed by SAP. We open the SAP transaction VA02 – Sales Order change and maintain the entries accordingly. We sold 61 Xboxs’ from which we can deliver 5 to some lucky end-customers.

Fig.4 Screenshot of SAP sales order for Xbox

Next, we initiate the delivery of a subset of the shipment to one of our re-sellers using SAP transaction Vl01n.

Fig.5 Screenshot of SAP delivery screen

That kicks off the standard SAP Workflow. We subscribe to the workflow event to inject post-processing using transaction SWE2 – Type Linkages. Until now the approach is identical for both our examples (ABAP SDK for Azure and ASAPIO). They only differ in event receiver settings.

Fig.6 Listing of ASAPIO and ABAP SDK for Azure receiver types

The ABAP class “ZBD_AZSB_SHIPMENT” implements the event marshalling and the post request towards the Azure Service Bus using the ABAP SDK. Have a look at our repos for more details on the ASAPIO config.

Fig.7 Screenshot of event receiver config in SAP

The mentioned function module “ZBD_CHECKXBOXSHIPMENTEVENT” filters the event stream for the object category Xbox. This is the first spot to implement event governance to control what type of events are sent from the ERP. We could envision complex filters based on categories, state properties, suppliers, price, unfulfilled orders etc.

We custom coded the message body and feed it into the ABAP SDK class for the service bus.

Fig.8 Snippet from ABAP event handler to post message to Azure Service Bus

From here the next stop is the Azure Service Bus receiver config. That is being maintained with transaction SM59 – Maintain RFC Destination. We need to create a connection of type http, put the target URL of your service bus as host name, and maintain the desired service bus topic as path prefix. This part of the setup is again similar for ASAPIO and the ABAP SDK.

Fig.9 Screenshot of Azure Service Bus config in SAP

Since we created a delivery, our message was pushed by the SAP workflow to Azure already. As you can see below it was queued (1 active message). Once the Azure LogicApp (low-code solution) picks up the message, its state moves to transferred.

This is the second spot where messages can be filtered. The service bus offers topic filters and actions for that purpose.

Fig.10 Screenshot from Azure Service Bus monitor

Fig.11 Azure LogicApp workflow

We employ a polling trigger that listens on the service bus for new messages. You can fine-tune the polling interval base on your needs. Base64 decoding is required because the ABAP SDK serves the payload as an ABAP XString. With ASAPIO you get un-encoded XML/JSON. Next to the SAP function module this is the third spot, where you could filter, triage, and enrich your message if required.

Finally, we forward the message to our Azure function “sendNotifications” (implemented in Python) that handles the communication with the Azure Notification Hub (see fig.2 for reference). The function also takes care of the look up of subscribed devices (respectively VIP users) on our distributed database Azure CosmosDB.

Have a look at below snippets for reference:

# Retrieve the device tokens from the Cosmos DB
def retrieveDeviceTokens(category):
    try:
        client = CosmosClient(ENDPOINT, KEY)
        database = client.get_database_client(DATABASE)
        container = database.get_container_client(CONTAINER)
        items = list(container.query_items(query="SELECT * FROM c WHERE c.category = '" + category + "'"))

        return items
    except exceptions.CosmosHttpResponseError as e:
        print( '\nAn error occurred. {0}'.format(e.message))
        return list()
# create the notification hub
        logging.info("Prepare notification")
        hub = anh.AzureNotificationHub(APP_NH_CONNECTION_STRING, APP_HUB_NAME, False)

        # retrieve the device tokens to notify from the Cosmos DB
        logging.info("Retrieve device tokens")
        items = retrieveDeviceTokens("xbox-series-x")

        # send the notifications to the relevant devices
        logging.info("Send notification to Android devices")
        for item in items:
            logging.info("Send to device:" + item.get('deviceToken'))
            status, headers = hub.send_google_notification(True, notifymsg, device_handle=item.get('deviceToken'))

One could argue that the implementation could be done solely with the LogicApp using low code. However, there is no built-in task for the Notification Hub yet. So, replicating the requests with plain http calls would complicate the LogicApp flow at this point. There is a typical trade-off between full-code and low code for such scenarios.

In case you want to pursue the LogicApp-only path anyways, find the Notification Hub REST API for Android push messages here.

If you want to go all-in with a full code solution rather than what was provided before, the Azure Service Bus input binding (trigger) for Azure functions will do the trick. Find the Python example here.

Aaaand, finally we get a native push message on our Android device. Not too bad, huh? 😉

Fig.12 UI flow on Android for Xbox notification

The beauty of such a native integration is, that the push messages appear on the built-in dashboard even though your app is not active. That massively increases the impact of your push messages.

Thoughts on production readiness

The architecture described in fig.2 leverages components that power global services such as Bing or Teams for instance. In addition to that it follows an established pub/sub pattern for asynchronous communication and event broadcasting. The consumer side acts directly on the push notification without further processing need (simple event processing). The integration is implemented through standard Android SDK means.

SAP’s standard event enablement has a built-in retry logic that publishes events (in order) in case the receiver is unavailable. Therefore resilency is addressed from the very beginning.

Next interesting property would be geo-location as part of the notification for the subscribers as well as utilizing it as filtering option. You will want to know if the new delivery hits your favourite store round the corner, right? 😉

An integration with the re-seller to enable online purchase off the back of the smartphone notification for the new delivery before it even hits the shelf would also be interesting.

In a nutshell: the implemented architecture reached a good level of maturity to satisfy the initial use case and poses a good foundation to build on top.

Further Reading and SAP Docs references

Blogs and missions by SAP/ASAPIO

Azure references

Final Words

Event-driven architectures are fun and exciting but also a chance to expand into new business opportunities. Using the Xbox example, we saw today how such an architecture would look like with SAP as a source. We described a prototype with push-based stock availability and price notifications to personal Android devices. Such VIP users are willing to pay extra for early access enabling you to create a premium service that capitalizes on the shortage of a high in demand product like the Xbox.

The prototype executes on the reference architecture described in fig.2 and leverages standard Azure components that enable all major smartphone operating systems. The events were sourced from SAP in two ways in our prototype. A flexible approach with custom ABAP leveraging the ABAP SDK for Azure and an integrated one using the certified extension provided by ASAPIO. In addition to that you learned about the Cloud Events standard as well as the difference between “pure” events and messages.

Ready to broadcast some SAP events of your own? Get onboarded on the SAP Customer Initiative to influence product direction early on.

Find the related GitHub repos here.

As always feel free to ask lots of follow-up questions.

 

Best Regards

Bart, Thijs, and Martin

Assigned Tags

      10 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Tobias Griebe
      Tobias Griebe

      Hi Martin Pankraz, Thijs and Bart,

      thank you for this very detailed blog entry with many interesting insights.

      Checking the table "List of popular event options, that we came across" at the beginning of this post, I feel that you are mixing up a few things, especially for the first two entries of this table:

      There are different approaches provided by SAP and you are mixing them up...

      1. SAP S/4HANA Enterprise Event Enablement
        The details and links in your comments section are referring to this approach, but the first column link to the Add-On.
        Depending on the (on-prem) release this uses the AMQP or the MQTT protocol.
      2. SAP NetWeaver Add-On for Event Enablement 
        this is what you are referring to as the second entry in your table.
        Technically this is using the REST protocol.

      Both of them are supporting the CloudEvents standard! Actually the native S/4 events only support CloudEvents as this is the strategic element in SAP's event driven architecture approach. For the Add-On you have full control how your events shall look like, but the default formater also emits CloudEvent conform events.

      Best regards,
      Tobias

      Author's profile photo Martin Pankraz
      Martin Pankraz
      Blog Post Author

      Hey Tobias,

      thanks for the comment. We tested with S/4HANA 1909. Looking forward to our session to clarify. I  am changing the values to tbc. in the meantime.

      KR

      Martin

      Author's profile photo Martin Pankraz
      Martin Pankraz
      Blog Post Author

      Your input was very helpful Tobias Griebe! Thanks for clarifying the different supported CloudEvents  versions across the backend portfolio. I updated the description to be stricter.

      Same for the additional function module to ensure the omitter for the AddOn points towards CloudEvents schema.

      Community collaboration drives clarity! Thank your for your active participation.

      KR

      Martin

      Author's profile photo Jens-Christoph Nolte
      Jens-Christoph Nolte

      Hallo Martin,

      thanks for your blog post. Events should be much more on our minds and we need to learn about them more, also in an S/4HANA context.

      As an application architect, I need to add something from an application perspective. The approach you call "S/4HANA Enterprise Event Enablement (SAP Business Events)" consists of two technical components.

      First, the Enterprise Event Enablement, which is handling communications between ABAP and Event Mesh. You have linked to the documentation, which is rather technical by nature.

      Secondly, the component that connects the applications to Enterprise Event Enablement is the Business Event Handling, which is more concerned with the application side of things (and less with the technical side). So if you want to understand things from an application side, read the Business Event Handling documentation. This also lets you better understand the content we deliver.

      I understand your blog post is investigating technical aspects, but readers may appreciate the application view here as well. And you can find the current set of delivered events on API Hub (links is for Cloud, but similar is there for on premse) - including the event OutboundDelivery.Created. Business Event Handling is generally available from release 2008/2020. In 1909 you mention above you had a "preview-version" that had less content and events were not yet CloudEvents 1.0 (but 0.2) compliant (the 1.0 standard was not available at time of implementation).

      Best regards,

      Christoph

      Author's profile photo Martin Pankraz
      Martin Pankraz
      Blog Post Author

      Thank you for your addition Christoph!

      Author's profile photo Rajesh PS
      Rajesh PS

      Martin Pankraz

      But custom coding /sdk brings lot of problems and surprise in future like new features not accepted, version management frequent change, high dependency with customs & its related libraries, performance lockups sometimes. I see this library is 3years ago.
      Any strong alternative Solution from SAP ? 🙂
      Author's profile photo Martin Pankraz
      Martin Pankraz
      Blog Post Author

      Hey Rajesh PS, the blog sheds light on the available options on the table at the top. It is up to you decide if you want to use partner solutions like ASAPIO, community SDKs, or SAP's own solutions on BTP.

      To be clear: The open-source ABAP SDK for Azure hosted on GitHub receives regular updates. Double check there. Pull-Requests were accepted this month and latest source updates are a couple of weeks back. You probably saw only one folder with static files that didn't change since release.

      KR
      Martin

      Author's profile photo Rajesh PS
      Rajesh PS

      Martin Pankraz

      How about the performance in case of high volumes with Azure event hubs- > SAP S4HANA  ? with custom ABAP SDK solution
      Author's profile photo Rajesh PS
      Rajesh PS

      Martin Pankraz from S4HANA will it query using HTTP to cosmos DB or Event hub?

      Author's profile photo Martin Pankraz
      Martin Pankraz
      Blog Post Author

      Well the Azure services and its APIs are built for global scale. The ABAP SDK simply leverages those APIs. Either way very high volumes with a need of 100% delivery require queuing and retry strategies. I encourage you to have a look here for the different properties and choices for that part of your architecture.

      KR

      Martin