Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
stephen_xue
Active Participant
5,975

Introduction


SAP has provided two native components "Enterprise Event Enablement" and "SAP Netweaver Addon for Event Enablement". In the document, the component "SAP Netweaver Addon for Event Enablement" will be used.

I have get lots of helps from Zhang, Fiona's blog post on how to push Data Event from S4 into Event Mesh. Whereas in most cases, the event message will be in deep structure rather than a flat structure. Please go through the rest of section for how to implement it via the framework.

Scope


This is not an end-to-end tutorial. The miss part can be found in Fiona's blog post.

In scope

  • SAP addon configuration

  • Enhancement implementation


Out  scope

  • Event Mesh configuration

  • BTP service configuration


Prerequisit



  1. BTP Event Mesh is working and Service Key has been generated.

  2. SAP Netweaver Addon for Event Mesh has been installed

  3. RFC Destination to Event Mesh and Token has been configured


if above steps have not been done, please check the details steps in Fiona's blog post

Implement Steps


In the example below, a purchase order create event is going to raised from S/4 hana. The event has header-item two layers. Different from all of the relevant blog posts using BOR object, the ABAP OO object will be used to raise the event. The effect would be the same. But just introduce a different way.

Create Custom ABAP Class Event


The class should be compatible with SAP business workflow. The implementation steps are exactly the same. If you are familar with the business workflow via ABAP OO, you can ignore this part.


  1. Interface




The class should inherit interface IT_WORKFLOW



2. Attribute


Add two attributes to the class as below. Since the class is for purchase order, the key should be with type EKKO-EBELN


 

3. Constructor Method


Once the interface has been added, there will few methods inherited from the interface. Please add a custom constructor method


with following source code inside
  METHOD constructor.
DATA(lv_class_name) = cl_abap_classdescr=>get_class_name( me ).
SPLIT lv_class_name+1 AT '=' INTO TABLE DATA(lt_class_name).
me->_por-catid = lt_class_name[ 1 ].
me->_por-typeid = lt_class_name[ 2 ].
me->_por-instid = im_order.
ME->_key = im_order.
ENDMETHOD.

This is how the method looks like



4. Method BI_PERSISTENT~FIND_BY_LPOR


  METHOD bi_persistent~find_by_lpor.
DATA(lv_order) = CONV ebeln( lpor-instid(10) ).
result = NEW zcl_purchase_order( lv_order ).
ENDMETHOD.



5. Method BI_PERSISTENT~LPOR


  METHOD bi_persistent~lpor.
result = _por.
ENDMETHOD.



6. Rest of Methods


For rest of methods, just activate them with empty source code.

7. Class Event


Create an event with name on_create. You can make any names making sense. There is no need add any parameters to the event. The event information will not be transfered via the parameter.


 

Create Virtual Message Type


The message type is a virtune entity used by the framework. Itself doen't contain any structure information.

use tcode WE81 to create the message type


Activate the message type via BD50



Create Event Message Structure


This  is the place define the event message structure. This is the structure of purchase order header. in order to make everything simple, it just contains order id and header text. Item field's type is a table type so that it can be an array in the runtime.


 

This is the item structure. Remember, once create it, please create a table type referring this basic structure, which will be used in the header struture for item type.


now the structure will have two layers.

Link Change Document Object to Custom Event


tcode: SWEC

The mechanism of 'SAP Netweaver Addon for Event Enablement' is triggered via the 'Change Document Object'. here we link the change document object of purchase order creation to the custom event create just now.

The change document object for purchase order is: EINKBELEG


tip: please search table TCDOB for relevant change document object. Furthermore you can create your own custom change document object for your specific requirement.

Configure Replicate Object


This is the main configuration of the component 'SAP Netweaver Addon for Event Enablement'.

Spro --> integration with other SAP component --> SAP Netweaver AddOn for Event enablement --> connection and Replication Object Custominzing





  1. Connection Instance




Please record the name of instance. Here BTP_EVENT_MESH has been used. It will be used later. For the RFC destination configuration, please check Fiona's blog post.


 

2. Outbound Object


Fill the value as below


Explain:

  1. Object name is PO_CREATE. Please record it since it will be used in the filter later.

  2. The SAP native extractor FM for Data Event is /ASADEV/ACI_GEN_VIEW_EXTRACTOR. However this guy can only handle view, which is a flat structure. We will create a custom one replacing it. Fill name ZACI_EVENT_EXTRACTOR here.

  3. Virtual Message type

  4. Select as disaplayed

  5. SAP EM

  6. The SAP native format FM for Data Event is /ASADEV/ACI_GEN_VIEWFRM_SAP_EM. Again the limitation of guy is it only work for flat structure. We will create a custom one replacing it. Fill name ZACI_EVENT_TO_JSON here.


3. Configure Header Attributes


ACI_VIEW should be the event message type created just now.

SAP_EM_TOPIC should be the topic configured in the BTP Event Mesh.



Link Custome Event and Virtual Message Type


tcode SWE2

Receiver Type is the virtual message type created just now.

Receiver FM is /ASADEV/ACI_EVENTS_TRIGGER

Do not forget the check the flag for linkage activation.


tip: the switch for 'Linkage Activated' can be used to switch on/off event connection.

Implement Relevant FM of Replicate Object



  1. Format FM zaci_event_to_json


The way to generate json string from ABAP structure is vary. You can develop own way as well. Just to make sure the parameters should be identical.
FUNCTION zaci_event_to_json .
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(IR_DATA) TYPE DATA
*" VALUE(IV_INSTANCE) TYPE /ASADEV/AMR_ARIBA_ARIBA_INST
*" VALUE(IV_OBJECT) TYPE /ASADEV/AMR_ARIBA_ARIBA_OBJECT
*" EXPORTING
*" REFERENCE(ET_CSV_LINES) TYPE /ASADEV/AMR_TT_CSV_LINE
*" REFERENCE(ET_RETURN) TYPE /ASADEV/ACI_TT_BAPIRET2
*"----------------------------------------------------------------------

DATA:
lt_csv_lines TYPE /asadev/amr_tt_csv_line, "
lt_csv_bundle TYPE /asadev/amr_tt_csv_line, "
ls_amr_obj TYPE /asadev/amr_obj, "
ls_csv_line TYPE LINE OF /asadev/amr_tt_csv_line.

CONSTANTS: lc_attr_db_name TYPE /asadev/aci_def_attr VALUE 'ACI_VIEW'.
FIELD-SYMBOLS: <ft_data> TYPE ANY TABLE.

"get the data:
ASSIGN ir_data->* TO <ft_data>.
IF sy-subrc NE 0 OR <ft_data> IS INITIAL.
RETURN.
ENDIF.

" convert data into json
DATA(lv_json) = /ui2/cl_json=>serialize(
data = <ft_data>
pretty_name = /ui2/cl_json=>pretty_mode-low_case ).

APPEND lv_json to lt_csv_lines.
ls_amr_obj = /asadev/cl_aci_helper=>get_aci_object(
iv_instance = iv_instance
iv_object = iv_object ).

*MOD-003 bundle as many csv_lines as customized into one cloud event
LOOP AT lt_csv_lines INTO ls_csv_line.
APPEND ls_csv_line TO lt_csv_bundle.
IF lines( lt_csv_bundle ) EQ ls_amr_obj-item_lines.
" now wrap the payload in the cloudevents header
CALL FUNCTION '/ASADEV/ACI_SAP_EM_CLOUDEV_FM'
EXPORTING
it_csv_lines = lt_csv_bundle
iv_instance = iv_instance
iv_object = iv_object
IMPORTING
et_csv_lines = lt_csv_bundle
et_return = et_return.

APPEND LINES OF lt_csv_bundle TO et_csv_lines.
IF ls_amr_obj-item_lines GT 0.
DO ls_amr_obj-item_lines - 1 TIMES.
APPEND INITIAL LINE TO et_csv_lines.
ENDDO.
ENDIF.
CLEAR lt_csv_bundle.
ENDIF.
ENDLOOP.

"Append the remaining lines
IF lines( lt_csv_bundle ) GE 1.
CALL FUNCTION '/ASADEV/ACI_SAP_EM_CLOUDEV_FM'
EXPORTING
it_csv_lines = lt_csv_bundle
iv_instance = iv_instance
iv_object = iv_object
IMPORTING
et_csv_lines = lt_csv_bundle
et_return = et_return.

APPEND LINES OF lt_csv_bundle TO et_csv_lines.
IF ls_amr_obj-item_lines GT 0.
DO ls_amr_obj-item_lines - 1 TIMES.
APPEND INITIAL LINE TO et_csv_lines.
ENDDO.
ENDIF.
CLEAR lt_csv_bundle.
ENDIF.
ENDFUNCTION.

 

2. Data Retrieving FM zaci_event_extractor

The save above. You can develop your own version as well. 🙂
FUNCTION zaci_event_extractor .
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" REFERENCE(IV_INSTANCE) TYPE /ASADEV/AMR_ARIBA_ARIBA_INST
*" REFERENCE(IV_OBJECT) TYPE /ASADEV/AMR_ARIBA_ARIBA_OBJECT
*" REFERENCE(IT_BDCP_LINES) TYPE /ASADEV/ACI_TT_BDCP
*" EXPORTING
*" REFERENCE(ET_RETURN) TYPE /ASADEV/ACI_TT_BAPIRET2
*" REFERENCE(ET_KEY_BDCP) TYPE /ASADEV/ACI_TT_BDCP_KEY
*" REFERENCE(ET_TABLE_CONTENT) TYPE /ASADEV/ACI_TT_TABLE_CONTENT
*" REFERENCE(ER_DATA) TYPE REF TO DATA
*" EXCEPTIONS
*" NOT_A_VALID_TABLE
*"----------------------------------------------------------------------

DATA: lo_badi TYPE REF TO /asadev/aci_gen_extractor_badi,
ct_table_content TYPE /asadev/aci_tt_table_content,
lr_dataref_t TYPE REF TO data.

* Get BAdI instance for extractor enhancements
/asadev/cl_aci_badi_helpr=>get_extr_badi(
EXPORTING
iv_instance = iv_instance
iv_object = iv_object
CHANGING
co_extractor_badi = lo_badi
ct_return = et_return ).

IF lo_badi IS BOUND.
/asadev/cl_aci_badi_helpr=>call_badi_extr_post_exit(
EXPORTING
io_extractor_badi = lo_badi
iv_instance = iv_instance
iv_object = iv_object
it_bdcp_lines = it_bdcp_lines
CHANGING
ct_table_content = ct_table_content
ct_return = et_return
cr_data = lr_dataref_t ).
ENDIF.

er_data = lr_dataref_t.
ENDFUNCTION.

3. Implement BAdI /ASADEV/ACI_GEN_EXTR

The data extractor is generic and the concrete extracting logic should be embeded in a certain implementation with a specific filter.

create an implementation for purchase order


configure the filter for the PO implementation by using the bellowing information. The values should be from the above configuration sections. This will guarentee that only PO create event will be processed by the implmentation.


Implement method POST_EXIT. The logic depends on what kind of message structure defined. Here is my code
  METHOD /asadev/aci_extrctpr_if~post_exit.
DATA lr_dataref TYPE REF TO data.
DATA(lv_order) = CONV ebeln( it_bdcp_lines[ 1 ]-tabkey+35 ). " Get PO number
DATA:
ls_data TYPE zpurchase_order.
FIELD-SYMBOLS:
<ls_purchase_order> type zpurchase_order,
<lt_purchase_order> TYPE STANDARD TABLE.
CREATE DATA lr_dataref TYPE TABLE OF zpurchase_order.
ASSIGN lr_dataref->* TO <lt_purchase_order>.
APPEND INITIAL LINE TO <lt_purchase_order> ASSIGNING <ls_purchase_order>.

SELECT SINGLE *
FROM ekko
INTO @DATA(ls_ekko)
WHERE ebeln EQ @lv_order.

SELECT *
FROM ekpo
INTO TABLE @DATA(lt_ekpo)
WHERE ebeln EQ @lv_order.

<ls_purchase_order> = VALUE #(
order_id = lv_order
header_text = ''
).
LOOP AT lt_ekpo ASSIGNING FIELD-SYMBOL(<ls_ekpo>).
APPEND INITIAL LINE TO <ls_purchase_order>-items ASSIGNING FIELD-SYMBOL(<ls_item>).
<ls_item>-item_number = <ls_ekpo>-ebelp.
<ls_item>-item_text = <ls_ekpo>-txz01.
<ls_item>-material = <ls_ekpo>-matnr.
<ls_item>-quantity = <ls_ekpo>-menge.
<ls_item>-uom = <ls_ekpo>-meins.
ENDLOOP.

cr_data = lr_dataref.
ENDMETHOD.

Unit Test


1. Create a Purchase Order in the system


This is a dummy order created in the system with number 4500000749. It has three items whose quantities are 12, 24 and 56.



2. Event Received in the Event Mesh


The event does contain the order id and three items with correct their information.


 

Conclusion



  • ABAP oo Event is working for 'SAP Netweaver Addon for Event Enablement'

  • Deep structure or multi layer can be fulfilled via custom FMs


Questions


During the investiagtion I have come up with a few questions. Hopefully someone can help me.

1. Comparison between two components. "SAP Netweaver Addon for Event Enablement" and "Enterprise Event Enablement". What are pros and cons of them? Which one is more suitable for what kind of requirement?

2. For CPI connects with BTP Event Mesh, we have Webhook and AMQP. Can I know which way is recommended?

 

Cheers.

 
10 Comments
Labels in this area