Skip to Content

Include Payload values in exception alerts using BADI and without BPM or UDF

A typical problem in Alert configuration (ALRTCATDF) is that it only allows to  use a set of pre-defined container variables in the message body of email generated. The body is created from the texts and the container variables defined in the long text section. None of these pre-defined variables is a part of message payload content except for the message GUID. Usually in case of an exception, the email provides a link to monitoring  item where the exception raised. The key of the message (eg. order number, quote number or material number) can only be found by browsing the message payload on the monitoring item.  However there is no way to quickly identify the key of the message at the time of email generation.

 

There is a couple of blogs on how to define alerts and add custom variables using BPM or UDF. But these are good if we want to create an alert on custom conditions. (For example, a condition like ‘ if the amount is exceeded a certain limit…’).

 

When searching through the possibility of adding payload variables to the alert message, I found that the BADI ALERT_EXIT has provided an alternative .  The focus is on the method “MODIFY_LONG_TEXT” where the long text defined in alert could be modified. It can be easily used to add constant texts just by appending it to the internal table CT_LONG_TEXT  (a changing parameter of this method).

We can define SXMS_MSG_GUID which is the message GUID of the payload  in the container as &SXMS_MSG_GUID&. This will bring the value to the BADI method. Then this value can be used to get the message and parse the payload to find any payload value given the xpath expression of the variable. The BADI is allowed to filter by alert category. This makes it flexible to use only for a given alert category without even executing the method for other categories.

 

Here are the detailed steps involved:

 

  1. ALRTCATDEF: (in PI)

  

2. BADI ALERT_EXIT implementation of method MODIFY_LONG_TEXT

a. Attributes:

  

b. Interface:

 

 ”  

c. Implementation of the method:

 

Source Code:

method IF_EX_ALERT_EXIT~MODIFY_LONG_TEXT.

  data: lv_textline type soli.

  data: lv_msgguid type SXMSMGUID,
        lv_xvalue type text256,
        lv_txt_msgid type char32,
        lv_guid type guid_32.

  clear lv_textline.

  read table ct_long_text into lv_textline index 1.
  if syst-subrc is initial.

    lv_txt_msgid = lv_textline-line+23(32).

    if lv_txt_msgid co ‘0123456789ABCDEFabcdef’.

      lv_msgguid = lv_txt_msgid.
      CALL FUNCTION ‘Z_PI_GET_MSG_PAYLOAD_VALUE’
        EXPORTING
          IV_MSGGUID = lv_msgguid
          IV_XPATH   = ‘Material/MATNR’
        IMPORTING
          EV_XVALUE  = lv_xvalue.

      clear lv_textline.
      concatenate lv_txt_msgid lv_xvalue into lv_textline-line separated by ‘:’.
      append lv_textline to ct_long_text.

    endif.
  endif.

 3. Message search:

I have written a function module (Z_PI_GET_MSG_PAYLOAD_VALUE)  to get the payload value for a given xpath,  based on the similar logic in the following links:

ABAP based Trex in XI: Proto

The specified item was not found.

Source Code:

FUNCTION Z_PI_GET_MSG_PAYLOAD_VALUE.
*”———————————————————————-
*”*”Local Interface:
*”  IMPORTING
*”     VALUE(IV_MSGGUID) TYPE  SXMSMGUID
*”     VALUE(IV_XPATH) TYPE  TEXT256
*”  EXPORTING
*”     VALUE(EV_XVALUE) TYPE  TEXT256
*”———————————————————————-

  DATA persist TYPE REF TO cl_xms_persist.
  DATA xms_msg TYPE REF TO if_xms_message.
  DATA xmb_msg TYPE REF TO cl_xms_message_xmb.
  DATA content TYPE xstring.
  DATA: pid LIKE sxmspmast-pid.
  DATA vers LIKE sxmspmast-vers.
  DATA payload TYPE ref to IF_XMS_PAYLOAD.

  DATA: ixmlfactory TYPE REF TO if_ixml,
           iparser TYPE REF TO if_ixml_parser,
           streamfactory TYPE REF TO if_ixml_stream_factory,
           istream TYPE REF TO if_ixml_istream,
           idocument TYPE REF TO if_ixml_document,
           lv_xpath TYPE string,
           root TYPE REF TO if_ixml_element,
           el   TYPE REF TO if_ixml_element,
           vl   TYPE string.
  DATA msg_tab TYPE sxmsmsgtab.
  DATA wa TYPE LINE OF sxmsmsgtab.
  DATA p_mesg LIKE sxmspmast-msgguid.

 

  CREATE OBJECT persist.

  SELECT * FROM sxmspvers
      APPENDING CORRESPONDING FIELDS OF TABLE msg_tab
      WHERE msgguid = iv_msgguid.

  read table msg_tab into wa index 1.

  CLEAR:  content,
          p_mesg,
          pid,
          vers.
  CLEAR payload.
  FREE xms_msg.
  FREE xmb_msg.

  p_mesg = wa-msgguid .
  pid = wa-pid.
  vers = wa-vers.

  try.
      CALL METHOD persist->read_msg_all
        EXPORTING
          im_msgguid = p_mesg
          im_pid     = pid
          im_version = vers
        IMPORTING
          ex_message = xms_msg.
    catch  cx_xms_syserr_persist.
  endtry.

  if xms_msg is bound.

    xms_msg->deleteheaderbyname(
            nsuri  = if_xms_run_time_env=>co_nsuri
            lcname = if_xms_run_time_env=>co_lcname ).

    xmb_msg ?= xms_msg.

    CALL METHOD
      xmb_msg->if_xms_message_xmb~get_payload_with_main_document
      RECEIVING
        return = payload.
    if not payload is initial.
      CALL METHOD payload->getbinarycontent
        RECEIVING
          return = content.
    endif.

    IF NOT content IS INITIAL.
*  Create DOM
      TYPE-POOLS: ixml.
      CLASS cl_ixml DEFINITION LOAD.

      ixmlfactory = cl_ixml=>create( ).
      streamfactory = ixmlfactory->create_stream_factory( ).
      istream = streamfactory->create_istream_xstring( content ).
      idocument = ixmlfactory->create_document( ).
      iparser = ixmlfactory->create_parser( stream_factory =
                                                    streamfactory
                                            istream = istream
                                            document = idocument ).
      iparser->parse( ).
*       Search for xpath / value
      lv_xpath = iv_xpath.
      root = idocument->get_root_element( ).
      el   = root->find_from_path( path = lv_xpath ).
      if el is bound.
        vl = el->get_value( ).
        ev_xvalue = vl.
      endif.
    endif.
  endif.

ENDFUNCTION.

 

4. The email alert received on a mapping exception:

 

 5. An important note: If you look at the inbox in Runtime Workbench, you will not see the appended line. The inbox will have the original message prior to being  modified by the BADI.

 

7 Comments
You must be Logged on to comment or reply to a post.