This is a test message to test the length of the message box.
Login
ABAP RAP Events
Erstellt von Software-Heroes

RAP - Events

329

Wie kannst du eigentlich Events in RAP erzeugen und mit ABAP verarbeiten? Hier erfährst du mehr zur eventgetriebenen Verarbeitung.

Werbung


In diesem Artikel schauen wir an, wie wir mit unserem RAP BO Events erzeugen können, diese mit Daten anreichern und lokal im System verarbeiten. Dabei gehen wir auf verschiedene Besonderheiten ein.

 

Einleitung

In diesem Artikel wollen wir unsere App für das Report Pattern erweitern und um ein Event erweitern. Eventgetriebene Architektur wird immer mehr zum Standard in der Entwicklung, da du dadurch Anwendungen voneinander entkoppeln kannst. Im Grunde erzeugt eine Anwendung oder ein Prozess ein Event, welches durch eine Queue aufgenommen wird und an Subscriber verteilt wird. Ein Event enthält in den meisten Fällen den Schlüssel der auslösenden Instanz, vielleicht ein paar Zusatzinformationen und das eigentliche Event, wie zum Beispiel angelegt, geändert oder gelöscht.

 

Event

Im ersten Schritt müssen wir in unserem RAP Objekt ein Event definieren. Dem Event wollen wir eine Payload mitgeben, um zum Consumer einige Zusatzinformationen geben zu können.

 

Erweiterung

Das Event soll in der Aktion zum Laden des Excels ausgelöst werden. Dazu wollen wir dem Event noch einige Zusatzinformationen mitgeben, die über das Popup übergeben werden. In diesem Fall erweitern wie die abstrakte Entität "ZBS_S_DRPExcelPopup" um ein neues Feld "EventComment".

@EndUserText.label: 'Excel Popup'
define abstract entity ZBS_S_DRPExcelPopup
{
  @EndUserText.label: 'Comment'
  EventComment : abap.char(60);
  @EndUserText.label: 'Test run'
  TestRun : abap_boolean;
}

 

Parameter

Dazu benötigen wir im nächsten Schritt die zusätzlichen Parameter, die wir dem Event mitgeben wollen. Dazu legen wir eine abstrakte Entität an, die die Struktur des Parameters abbildet. Damit haben wir die Möglichkeit, neben dem Schlüssel auch noch zusätzliche Informationen zu übergeben. Grundsätzlich können wir Daten zur Entität auch im Event nachlesen.

@EndUserText.label: 'Additional event data'
define abstract entity ZBS_S_DRPEventData
{
    EventComment : abap.char(60);
    LastEditor : abap.char(12);
}

 

Eventdefinition

Im Verhalten definieren wir nun das Event und auch die Parameter, die wir bei der Erzeugung mitgeben wollen. Dazu erweitern wir die unterste Schicht der Verhaltensdefinition ZBS_R_DRPCurrency. In unserer Hauptentität übernehmen wir das Event.

event AfterExcelLoad parameter ZBS_S_DRPEventData;

 

Auslösen

Die Best-Practice sieht vor, dass wir das Event beim Speichern auslösen. Dazu steht uns der ADDITIONAL SAVE zur Verfügung, falls wir komplett im Managed Verhalten sind. Da wir aber bereits einen UNMANAGED SAVE verwenden, können wir die Methode erweitern, um das Event auszulösen. Versuchst du allerdings im STRICT(2) Modus das Event in einer Aktion auszulösen, erhalten wir in unserer Anwendung einen Fehler.

 

Wir müssen also die Verhaltensimplementierung von ZBP_BS_DRP_CURRENCY anpassen, um das Event auszulösen. Da wir keinen Indikator in den Daten haben, ob die Excel Datei geladen wurde, merken wir uns den Schlüssel in einem lokalen Puffer. Normalerweise könntest du hier die veränderten Daten als Referenz benutzen.

CLASS lcl_buffer DEFINITION.
  PUBLIC SECTION.
    TYPES tt_keys TYPE TABLE FOR ACTION IMPORT zbs_r_drpcurrencycurrency~loadexcelcontent.

    CLASS-DATA gt_event TYPE tt_keys.
ENDCLASS.

 

Im nächsten Schritt befüllen wir den Puffer, wenn die Aktion "LoadExcelContent" erfolgreich ausgelöst wurde und übernehmen den Schlüssel.

INSERT ls_key INTO TABLE lcl_buffer=>gt_event.

 

In der Methode SAVE_MODIFIED lösen wir nun das Event für die gepufferten Schlüssel aus. Mit dem neuen Statement RAISE ENTITY EVENT geben wir unsere Schlüssel und Parameter mit.

LOOP AT lcl_buffer=>gt_event INTO DATA(ls_event).
  RAISE ENTITY EVENT ZBS_R_DRPCurrency~AfterExcelLoad
        FROM VALUE #( ( %key   = ls_event-%key
                        %param = VALUE #( EventComment = ls_event-%param-EventComment
                                          LastEditor   = cl_abap_context_info=>get_user_technical_name( ) ) ) ).
ENDLOOP.

 

Das Event wird nun im System erzeugt und wir können uns darauf registrieren, um es zu empfangen und zu verarbeiten. Damit können wir die nachfolgenden Prozesse auslagern oder Schnittstellen für andere Entwickler schaffen.

 

Konsumierung

In diesem Artikel wollen wir lokal auf das Event reagieren und es im selben System verarbeiten. Dabei benötigen wir keinen Event Broker oder ein Binding, sondern können direkt eine Klasse anlegen, welches das Event verarbeitet.

 

Klasse

Um Events verarbeiten zu können, legen wir eine neue globale Klasse an, die im lokalen Teil die Implementierung der Events beinhaltet. Hier folgen wir dem Pattern der Verhaltensimplementierung. Hinter dem Zusatz FOR EVENTS OF ergänzen wir unser Business Objekt.

CLASS zcl_bs_drp_event_consumption DEFINITION
  PUBLIC ABSTRACT FINAL
  FOR EVENTS OF ZBS_R_DRPCurrency.

  PUBLIC SECTION.
ENDCLASS.


CLASS zcl_bs_drp_event_consumption IMPLEMENTATION.
ENDCLASS.

 

Im nächsten Schritt können wir die lokale Klasse implementieren. Dazu legen wir eine lokale Klasse an, der Name der Klasse ist hier egal, sie muss allerdings von der Klasse CL_ABAP_BEHAVIOR_EVENT_HANDLER erben. Für jedes Event würden wir nun eine eigene Methode anlegen.

CLASS lcl_local_events DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
  PRIVATE SECTION.
    METHODS after_excel_load FOR ENTITY EVENT it_parameters FOR Currency~AfterExcelLoad.
ENDCLASS.


CLASS lcl_local_events IMPLEMENTATION.
  METHOD after_excel_load.
    IF 0 = 0.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Der Name der Methode ist ebenfalls egal, sollte aber beschreibend bleiben. Der Name des Import Parameters kann ebenfalls frei gewählt werden, wenn bei dir im Unternehmen noch Namenskonventionen verlangt werden. Nach dem FOR kommt zuerst einmal die Entität und dann das entsprechende Event. Hier kannst du in Eclipse auch den Content Assist (STRG + LEER) verwenden.

 

Test

Im nächsten Schritt testen wir einmal den Aufruf des Events, dazu können wir einen Breakpoint in die Methode setzen und die Aktion im UI ausführen.

 

Nach der Ausführung der Aktion erhalten wir zuerst einmal das Erfolgspopup, dass die Daten in die Entität geladen und verarbeitet wurden. Im Anschluss startet in unserem Eclipse der Debugger. Schauen wir uns den Parameter an, wurde ein Event zugestellt, welches die zusätzlichen Daten für das Event enthält.

 

Logik

Zum Abschluss wollen wir auf das Event reagieren, in dem wir dem aktuellen User eine E-Mail zusenden mit dem aktuellen Stand des Datensatzes und dem Kommentar. Du solltest allerdings beachten, dass du dich in den RAP Transaktionsphasen befindest und damit den Regeln unterliegst.

cl_abap_tx=>modify( ).

LOOP AT it_parameters INTO DATA(ls_parameter).
  send_mail_to_receiver( ls_parameter ).
ENDLOOP.

cl_abap_tx=>save( ).

LOOP AT mt_mails INTO DATA(lo_mail).
  lo_mail->send_async( ).
ENDLOOP.

 

In dem Beispiel starten wir mit MODIFY in CL_ABAP_TX. Diese Phase musst du allerdings nicht setzen, diese ist der Standard, wenn die Methode gestartet wird. Im Anschluss können wir die Mail vorbereiten, per EML Daten nachlesen und weitere Daten aktualisieren. Sind wir so weit damit fertig, müssen wir für den Versand der E-Mail die Phase auf SAVE wechseln. Nun können wir Inserts, Updates und Modifys absetzen. Allerdings können wir immer noch keinen COMMIT oder einen ROLLBACK absetzen, da dieser durch RAP gesteuert wird. Daher verwenden wir die Methode SEND_ASYNC, um die Mail zu versenden. 

 

Eine kleine Besonderheit haben wir noch bei der Aufbereitung der E-Mail eingebaut, hier erzeugen wir ein Image Tag und hängen das angehangene Bild in die Mail als Content ein. Dazu konvertieren wir das Bild nach BASE64 und übernehmen es mit dem richtigen MIME-Type in das IMG Tag. Damit erscheint das Bild innerhalb der Mail.

READ ENTITIES OF ZBS_R_DRPCurrency
     ENTITY Currency
     ALL FIELDS WITH VALUE #( ( Currency = is_parameter-Currency ) )
     RESULT DATA(lt_currency).

DATA(ls_currency) = VALUE #( lt_currency[ 1 ] OPTIONAL ).

DATA(ld_base64) = cl_web_http_utility=>encode_x_base64( ls_currency-PictureAttachement ).

DATA(ld_message) = |<h3>{ is_parameter-EventComment }</h3>|.
ld_message &&= |<img src="data:{ ls_currency-PictureMimetype };base64, { ld_base64 }" style="height:200px; width: 200px" />|.
ld_message &&= |<p>{ ls_currency-CurrencyComment }</p>|.

RETURN ld_message.

 

Vollständiges Beispiel

Alle Änderungen aus diesem Blog findest du im folgenden Commit des GitHub Repository. Bei diesem Commit mussten wir noch Änderungen vornehmen bei der SAVE_MODIFIED Methode, da sich kleinere Fehler eingeschlichen hatten. Mehr Details zu dieser Methode findest du in diesem Artikel.

 

Fazit

Die Implementierung von Events in RAP funktioniert sehr einfach, allerdings solltest du auf die verschiedenen RAP-Phasen achten, um eine saubere Verarbeitung, ohne viele Fehler, zu erreichen.

 

Quelle:
SAP Help - Business Events
SAP Help - Business Event Consumption


Enthaltene Themen:
RAPBTPEvents
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


RAP - API Pattern

Kategorie - ABAP

In diesem Artikel schauen wir uns das API-Pattern für RAP an und wie du es flexibel in der ABAP Entwicklung einsetzen kannst, um Schnittstellen zur Verfügung zu stellen.

20.06.2025

RAP - Mehrere Filter und Einstellungen

Kategorie - ABAP

Wie sieht es eigentlich aus, wenn wir in RAP mehrere Filter und Felder als Standard setzen wollen und dazu noch eine standardmäßige Sortierung benötigen?

16.05.2025

RAP - Länge von Meldungen

Kategorie - ABAP

Deine Meldung wird bei der Ausgabe mit RAP abgeschnitten? Lass uns das Problem und eine Lösung anschauen.

13.05.2025

RAP - Suchhilfe und Schlüssel optimieren

Kategorie - ABAP

In diesem Artikel optimieren wir unsere Suchhilfen im Custom Pattern, verwenden das Additional Binding und machen unsere RAP Anwendung fit für den Endanwender.

06.05.2025

RAP - Festwert-Filter

Kategorie - ABAP

Wie verwendest du Festwerte aus einer Domäne für einen Filter und passt diesen nach deinen Bedüfnissen in RAP an? Mehr dazu hier.

02.05.2025