Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
AlexPfeil
Product and Topic Expert
Product and Topic Expert
2,007

Introduction

Update: After the Release of the Development Artifacts in SAP Note 3486106 I changed the Blog to use the Objects delivered by this Note. 

After the announcement of Karsten here and Christians Blog here I would like to offer a simple and detailed HowTo Guide to activate and enhance Event Integration via Application Interface Framework to Advanced Event Mesh.

SAP Note for Release Strategy: https://me.sap.com/notes/3480454

SAP Note for AIFAEM Metering: https://me.sap.com/notes/3474406

SAP Application Interface Framework does not only make it easy and brings a lot of Flexibility to enhance Events, but also included in the AEM Licence.

Some parts of the process are always the same, some are dependent on the scenario. In this blog I will show you the process on the Example Business Partner. We will enhance the Business Partner Event with Name and Address Data. Let´s dive in.

Following artefacts are delivered by Note 3486106  to support the integration:

  • Function Module: /AIF/AIF_ACTION_CALL_AEM - AIF Action FM to integrate SAP SAP Integration Suite, advanced event mesh via HTTP Rest.
  • Function Module: /AIF/TRANSFER_TO_AIF_RECEIVER - Receiver Function Module for the integration of the AIF runtime in transaction swe2
  • Value Mapping Function Modules /AIF/AEM_GET_ID, /AIF/AEM_GET_SOURCE, /AIF/AEM_GET_TIME - AIF Mapping FMs to support the creation of header information of a cloud event
  • View /AIF/NAME_MAP (maintainable via sm30): view to define the name mapping from ABAP to Json."
  • DDIC Structure /AIF/EVENT_RAW as Default Source Structure for BOR Events (SWE2)
  • DDIC Structure /AIF/AEM_CONTROLLER as mandatory Structure inside of the Custom Target DDIC Structure (Consisting of CONTROLLER and DATA, DATA is custom depending on scenario) 
  • DDIC Structure /AIF/AEM_CE_HEADER if you want to include the CloudEvent Header in the DATA-Structure

   Please keep in mind that the DDIC Objects need to be created manually during the Import of the Note.

1) Event Linkage in SWE2

In Transaction SWE2 we can add Linkages for SAP Standard Object Events. On New Entries we just have to add an entry with Function Module "/AIF/TRANSFER_TO_AIF_RECEIVER". The Event Types consist of technical Business Object Keys. In order to find the right Key Value, click on the F4 Help and use the Information System to Search for your Object

AlexPfeil_7-1722523041743.png

AlexPfeil_8-1722523082655.png

You can find the Linkage between Standard Events and BOR Objects in CDS View BEH_I_EVENT

AlexPfeil_0-1730383379582.png

(I put a filter here on OBJECT_REPRESENTATION_TYPE = "BO" and BO_TYPE = "*BusinessPartner*"

In our Case I will choose BUS1006 Business Partner

The Checkbox "Linkage Activated" should be not active yet, because Event would go into error in the Function Module, since we haven´t set up the AIF Interface yet.

AlexPfeil_0-1729061723847.png

The Action Function will always pass the Event to AIF Runtime Configuration Group AEM / 001. You will need to create it in /N/AIF/PERS_CGR:

AlexPfeil_11-1729187084946.png

2) AIF Target Structure Design

Before we get to define the Interface, we need to design the expected Output of our Event. Here you need to know, that AIF requires DDIC Types as Structures. The AIF AEM Addon requires a Structure with "CONTROLLER" and "DATA". 

 

 

 

 

 

@EndUserText.label : 'Event Message'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zaif_aem_bupa_event_message {

  controller : /aif/aem_controller;
  data       : zaif_aem_bupa;

}

 

 

 

 

 

2.1) Controller

The "Controller"-Structure requires these Fields, so the AIF Action later has all the information needed to call the AEM and pass the event to the right topic. It is provided in the AIFAEM Installation

 

 

 

 

 

 

 

@EndUserText.label : 'Controller'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure /aif/aem_controller {

  rfc_dest        : rfcdest;
  topic           : abap.string(0);
  uri             : abap.string(0);
  name_mapping_id : /aif/name_map_id;

}

 

 

 

 

 

The RFC_DEST is the Destination maintained in SM59. With AIF we always use the REST Endpoint to the AEM. The assumption here is that the SM59 connection to AEM is already established. This might be done with Basic Auth or Client Certificate. One way is described here 

AlexPfeil_0-1722521749081.png

The Name Mapping ID (provided in the AIFAEM Installation) refers to the Database Table /AIF/NAME_MAP which is used to map the ABAP Field Names to JSON Tags.

 

 

 

 

 

@EndUserText.label : 'Name Mappings'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #C
@AbapCatalog.dataMaintenance : #ALLOWED
define table /aif/name_map {

  key mandt           : mandt not null;
  key name_mapping_id : /aif/name_map_id not null;
  key abap            : name_feld not null;
  json                : /aif/json_name;

}

 

 

 

 

My Entries:

AlexPfeil_3-1729190215688.png

 

 

 

2.2) Data

This Element in the Target Structure basically is what the AIF Action will convert into a json and send as Payload to the AEM. You can include the Event Header like Christian did in his Blog (referenced at the beginning, provided Structure in AIFAEM Installation:/AIF/AEM_CE_HEADER) or simply the Payload itself, like me with zaif_aem_bupa. AEM knows the Topic because we specify the Topic to AEM in the Controller-Structure Field Topic or in the URI.

 

 

 

 

 

@EndUserText.label : 'BusinessPartner'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zaif_aem_bupa {

  businesspartner : zaifaem_abusinesspartner;
  bpaddress       : zaif_aem_abpaddress_tt;

}

 

 

 

 

 

Every Customer is free to design whatever fits to their needs here. To reduce effort to design structures and make Move-Corresponding work after Data Selection, I decided to orientate on the CDS Views, where I get the Data from in my Structure Mapping Function Module (which you will see in the section after this). Generally in S/4HANA CDS views are part of the Virtual Data Model, which forms the basis for data access. For more information feel free to read the SAP Help here.

I chose to call the CDS View behind this API: https://api.sap.com/api/OP_API_BUSINESS_PARTNER_SRV/resource/Business_Partner

For every Entity here there is a CDS View in the System you can check in ABAP Developer Studio.

Many CDS Views are documented in the SAP Accelerator Hub. They can be used as well. Example: I_BusinessPartner: https://api.sap.com/cdsviews/PCE_I_BUSINESSPARTNER

Since CDS Views cannot be used in AIF, I use the DDIC Views generated by the CDS Views. For General Data i chose the CDS View A_BusinessPartner, which generates DDIC View ABUSINESSPARTNER

AlexPfeil_2-1722522215042.png

I created a Structure "zaifaem_abusinesspartner" with only the Fields I need: 

 

 

 

 

 

 

@EndUserText.label : 'ABUSINESSPARTNER but with less fields'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zaifaem_abusinesspartner {

  businesspartner : abap.string(0);
  firstname       : abap.string(0);
  lastname        : abap.string(0);

}

 

 

 

 

 

 

For the Address the Address below A_BusinessPartner --> ABUPARTADDRESS.

AlexPfeil_3-1722522246556.png

Since there could be multiple addresses, we need a Table Type here. So I created one for ABUPARTADDRESS in SE11:

AlexPfeil_0-1729186026847.png

 

 

 

 

 

@EndUserText.label : 'ABUPARTADDRESS but with less fields'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zaifaem_abupartaddress {

  addressid         : abap.string(0);
  validitystartdate : abap.string(0);
  validityenddate   : abap.string(0);
  streetname        : abap.string(0);
  cityname          : abap.string(0);
  housenumber       : abap.string(0);
  postalcode        : abap.string(0);
  country           : abap.string(0);

}

 

 

 

 

 

Now that the Target Structure is designed, we can move on to create the AIF Interface

3) AIF Interface Design

The RAW (Source) Structure for BOR Events is always the same (provided by the AIFAEM Installation) --> /aif/event_raw

 

 

 

 

 

@EndUserText.label : '/aif/event_raw'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure /aif/event_raw {

  objtype : swo_objtyp;
  objkey  : swo_typeid;
  event   : swo_event;
  rectype : swe_rectyp;

}

 

 

 

 

 

In /N/AIF/CUST -> Define Namespaces we defined our Namespace "AEM" and in /N/AIF/CUST -> Define Interface our Interface:

AlexPfeil_1-1729186156888.png

In /N/AIF/CUST -> Additional Interface Properties -> Specify Interface Engines we also need to change the Application and Persistence Engine to XML

AlexPfeil_6-1722522539677.png

Also we need to specify on what condition the AIF needs to call this interface (because the Source Structure is always the same for all Events). Therefore we need to open /N/AIF/CUST -> System Configuration -> Interface Determination -> Interface Determination For XML.

AlexPfeil_2-1729186191061.png

We could define Rules here on multiple Fields. For example a different Interface for different Events (Create, Change,..). But here we only do this based on the Object Type.

AlexPfeil_3-1729186214543.png

 

 

4) AIF Structure Mapping

In /N/AIF/CUST -> Define Structure Mapping we can define what and how exactly needs to be mapped to our Target Structure. We only have one Source Structure: /AIF/EVENT_RAW. The Target Structure is the Root Structure of our Target Message.

4.1) Controller

Here we defined some fix values. This is always the same for all Business Partners

AlexPfeil_5-1729186327086.png

For the Destination i have defined a Global Fixed Value in /N/AIF/CUST -> Define Fix Values, which i am referring here. The other Fix Values are defined locally in the Interface.

AlexPfeil_6-1729186372350.png

(usually I would determine the URI part "change" dynamically, but to keep it simple I added this as fixed value) 

The Topic could contain more detailed information and organizational dimensions, which might be specific for the object (for instance sap.com/businesspartner/change/v1/Organization/<BusinessPartnerNumber>). Instead of a Fix Value you might want to use the AIF Field Mapping or ABAP Coding (for instance in the Structure Mapping Function Module in chapter 4.2) to dynamically set the Topic. For Topic Nomenclature Best Practices check out this Page: https://help.pubsub.em.services.cloud.sap/Messaging/Topic-Architecture-Best-Practices.htm 

In my example I don´t send the Event Header (/AIF/AEM_CE_HEADER) in the DATA-Segment (compared to Christian´s Blog referenced at the beginning). The Topic Name is provided in the URL as /Topic/<Topic Name>.  

4.2) DATA

In AIF there are many ways to check & Map Data. We have Value Mappings, Conditions and the freedom to add ABAP Coding in many places. Christian showed us in his blog how to do it in Customizing, which would be the cleanest way. But if there are multiple Fields to be fetched from the same Database-Table (or CDS View), it is not the most performant way to do it. That is why I chose to implement the selection of the data in one Structure Mapping Function Module. 

With the F1-Help we always get a Template from AIF which we can copy and use in that specific Step

AlexPfeil_7-1729186566791.png

 

After copying the Template /AIF/FILE_TEMPL_MAP I changed the OUT_STRUC Data Type to our Target Data Type ( and /AIF/EVENT_RAW as RAW_STRUCT)

AlexPfeil_1-1722524085413.png

In the Function Module I select the Data and move it to the Target Structure afterwards:

 

 

 

 

 

FUNCTION zaif_aem_bupa_get_data .
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(RAW_STRUCT) TYPE  /AIF/EVENT_RAW
*"     REFERENCE(RAW_LINE)
*"     REFERENCE(SMAP) TYPE  /AIF/T_SMAP
*"     REFERENCE(INTREC) TYPE  /AIF/T_INTREC
*"     REFERENCE(SENDING_SYSTEM) TYPE  /AIF/AIF_BUSINESS_SYSTEM_KEY
*"       OPTIONAL
*"  TABLES
*"      RETURN_TAB STRUCTURE  BAPIRET2 OPTIONAL
*"  CHANGING
*"     REFERENCE(OUT_STRUCT) TYPE  ZAIF_AEM_BUPA_EVENT_MESSAGE
*"     REFERENCE(DEST_LINE)
*"     REFERENCE(DEST_TABLE)
*"     REFERENCE(APPEND_FLAG) TYPE  C
*"----------------------------------------------------------------------

  SELECT
    FROM A_BusinessPartner
    FIELDS
      BusinessPartner,
      FirstName,
      lastName,
      businesspartnercategory,
      \_BusinessPartnerAddress-addressid,
      \_BusinessPartnerAddress-ValidityStartDate,
      \_BusinessPartnerAddress-validityenddate,
      \_BusinessPartnerAddress-streetname,
      \_BusinessPartnerAddress-cityname,
      \_BusinessPartnerAddress-housenumber,
      \_BusinessPartnerAddress-postalcode,
      \_BusinessPartnerAddress-country
   WHERE BusinessPartner = _struct-objkey
    INTO TABLE (lt_result).

  IF lt_result IS NOT INITIAL.
    READ TABLE lt_result ASSIGNING FIELD-SYMBOL(<ls_result>) INDEX 1. "General Data is the same in every Row
    IF <ls_result> IS ASSIGNED.
      MOVE-CORRESPONDING <ls_result> TO out_struct-data-businesspartner.
    ENDIF.
    MOVE-CORRESPONDING lt_result TO out_struct-data-bpaddress.
  ELSE.
    CALL FUNCTION '/AIF/UTIL_ADD_MSG'
      EXPORTING
        msgty      = 'E'
        msgid      = '/AIF/MES'
        msgno      = '000'
        msgv1      = 'No Business partner found'
      TABLES
        return_tab = return_tab.

  ENDIF.

ENDFUNCTION.

 

 

 

 

 

5) AIF Action Creation & Assignment

The Action, which is calling the AEM, has to be created and configured.

/N/AIF/CUST -> Interface Development -> Define Action

The Function Module "ZAIF_ACTION_CALL_AEM" is provided by the AIFAEM AddOn and can be used for all Event Interfaces.

AlexPfeil_8-1729186671679.png

 

After saving, the Action can be assigned to the Interface in /N/AIF/CUST -> Interface Development -> Define Structure Mapping -> Assign Action

AlexPfeil_3-1722524634180.png

6) Testing & Monitoring

As mentioned in Step 1, the Event Linkage in SWE2 needs to be activated. After that we can trigger the Event. In this case we just change a Business Partner in Transaction BP:

AlexPfeil_4-1722525030190.png

--> AIF Monitoring /N/AIF/ERR

AlexPfeil_7-1722525841183.png

to See the RAW Structure, we need to activate "Display Root Field" in  /N/AIF/CUST -> Error Handling -> Define Namespace-Specific-Features:

AlexPfeil_9-1729186768171.png

 

--> Result (Double Click on /AIF/EVENT_RAW:

 

AlexPfeil_0-1729190047750.png

 

to see the mapped result, we can use the Technical Mode and transform

AlexPfeil_8-1722525883057.png

AlexPfeil_9-1722525912997.png

Now we can see the data:

AlexPfeil_1-1729190095467.png

AlexPfeil_2-1729190159995.png

Message on Advanced Event Mesh (Try Me! Functionality and Sub on Topic "sap/aif/>" :

AlexPfeil_4-1729190411429.png

 

TroubleShooting

If you cannot find your Event in AIF, first thing is to check the Interface Determination. Other Tips:

- Check SM58 if an error occured during TRFC Processing in the BOR Framework. If another User is there, you need to debug with this UserID

-Check SWEL if there is an error in the SWE Trace (Activation of Trace in SWELS if not active)

Summary

This Blog shows how to easily set up an Application Interface Framework (AIF) Interface for any SAP Standard Event on the example Business Partner. Additionally the AIF offers a lot of other features which can be used, for instance to do Checks, Value Mappings or enhance the Monitoring to Select Events based on any Information the Target Data contains. This should enable many Customers to easily publish and enhance Events to Advanced Event Mesh.    

2 Comments