• Keine Ergebnisse gefunden

5 Übersetzung des Scopes

5.7 Event Handlers

EventHandlers werden in einem Scope anhand des EventHandlers-Elements spezifiziert. Sie können parallel ablaufen und ihre assoziierte Aktivität wird ausgeführt, wenn der entsprechende Event eintritt. Die Aktivität eines EventHandlers darf nur ein Scope sein. Es gibt zwei Arten von Events – Nachrichten- und Alarm-Events.

Nachrichten-Events werden durch das onEvent-Element spezifiziert. Sie werden ausgelöst sobald eine Nachricht auf einem spezifizierten PartnerLink beim Aufruf einer Operation eintrifft. Das optionale Attribut variable spezifiziert eine Variable mit ihrem Typ, die lokal für den Scope, der mit einem EventHandler assoziiert ist, deklariert wird, und in der die Nachricht abgelegt wird. Das bedeutet, dass jede EventHandler-Instanz ihre eigene Kopie von Variablen enthält, die nicht für andere Instanzen verfügbar ist.

Die Operation kann sogar eine Request-Response-Operation sein. Der EventHandler sollte aber dann eine reply-Aktivität enthalten, die die Antwortnachricht sendet.

Die Semantik von spezifizierten Correations ist die gleiche wie bei einer receive-Aktivität.

Allerdings dürfen auch CorrelationSets benutzt werden, die in dem assoziierten Scope deklariert sind. Alle Variablen, die in dem assoziierten Scope eines EventHandlers explizit oder implizit deklariert werden, sind während des Kompensierens für die entsprechende CompensationHandler-Instanz verfügbar.

Bei einer Request-Response-Operation wird immer einen Default-MessageExchange verwendet. Das ist sogar dann der Fall, wenn dieser MessageExchange nicht explizit in dem assoziierten Scope deklariert wird. Dadurch ist es möglich, dass mehrere EventHandler-Instanzen Nachrichten empfangen können, ohne dabei einen BPEL-Standardfehler (z.B.

bpel:conflictingRequest) zu signalisieren und ohne einen MessageExchange explizit zu deklarieren.

Alarm-Events werden durch das onAlarm-Element spezifiziert. Es gibt, ähnlich wie bei einer wait-Aktivität (vgl. Abschnitt 3.5), unterschiedliche Events. Man kann durch das for-Element ein Zeitintervall spezifizieren, nach dessen Ablauf, der assoziierte Scope ausgeführt wird oder durch das until-Element - einen absoluten Zeitpunkt angeben.

EventHandlers werden aktiviert sobald der Vater-Scope gestartet wird. Sobald die primäre Aktivität des Vater-Scopes beendet wird, werden alle EventHandlers in diesem Scope zu Ende ausgeführt und danach deaktiviert.

Ein Alarm-Event kann nur ein einziges Mal ausgelöst werden, während ein Nachrichten-Event mehrfach ausgeführt werden kann.

Ein Fehler bei der Ausführung eines EventHandlers wird an den FaultHandler in seinem assoziierten Scope propagiert. Kann der Fehler nicht behandelt werden, wird er an den Vater-Scope weitergereicht.

Listing 24 zeigt ein Beispiel für die Definition eines EventHandlers.

<eventHandlers>

<onEvent partnerLink="purchasing" operation="queryPurchaseOrderStatus" ...>

<correlations>

<correlation set="PurchaseOrder" initiate="no" />

</correlations>

<scope>...</scope>

</onEvent>

<onAlarm>

<until>'2002-12-24T18:00+01:00'</until>

<scope>...</scope>

</onAlarm>

</eventHandlers>

Listing 24: Beispiel für ein EventHandler

In Abbildung 26 ist das EventHandlers-EWFN dargestellt.

Abbildung 26: EventHandlers-EWFN

Im EventHandlers-EWFN sind für jedes Event-Scope-Paar zwei EWFNs enthalten, eines für das Event und eins für den assoziierten Scope. Bei einem Nachrichten-Event ist das Event-EWFN dem receive-Event-EWFN (vgl. Abschnitt 3.1) sehr ähnlich, das Event-EWFN für den assoziierten Scope entspricht dem Scope-EWFN. Die Beschreibung dieser EWFNs wird deswegen nur die Unterschiede berücksichtigen. Bei einem Alarm-Event entspricht das Event-EWFN dem wait-EWFN (vgl. Abschnitt 3.5) und das wait-EWFN für den assoziierten Scope dem Scope-wait-EWFN. Die Schnittstelle zu dem umgebenden Scope bilden die Plätze start und ended, die sich auf dem äußeren Rahmen befinden. Der Platz IDs wird von dem Nachrichten-Event-EWFN benutzt und speichert ein Tupel mit einer Integer-Variablen, die die nächste zu vergebende ID für eine Scope-Instanz enthält. Dieser Platz muss vorinitialisiert werden. Das Deaktivieren der EventHandlers erfolgt über die Plätze from_MW und to_MW.

Bei der Betrachtung der Kontrollflussevaluierung wird man zwei Szenarien unterscheiden.

Im ersten Szenario betrachtet man den Fall, dass der umgebende Scope die EventHandlers aktiviert. Es befindet sich also ein CF-Token auf dem start-Platz des EventHandlers-EWFNs.

Die Transition T1 schaltet wenn ein CF-Token empfangen wird und produziert daraufhin ein CF-Token auf den start-Platz jedes Event-EWFNs. Die Transition in einem Event-EWFN (T2) liest nur dieses CF-Token und dadurch können weitere Nachrichten-Events bei Empfang einer geeigneten Nachricht ausgelöst werden. Die Logik, die von der Tansition T2 ausgeführt wird, ist gleich wie die Logik der Transition im receive-EWFN (vgl.

Abschnitt 3.1) bis zum dem Zeitpunkt, wo eine passende Nachricht empfangen worden ist.

Der einzige Unterschied besteht nur in der Bedingung, die erfüllt sein muss, damit man die BPEL-Standardfehler bpel:conflictingReceive oder bpel:conflictingRequest signalisiert.

Anders als im receive-EWFN wird der Fehler bpel:conflictingReceive nicht an den FaultHandler des assoziierten Scopes weitergegeben, wenn entweder der spezifizierte PartnerLink oder die CorrelationSets in dem assoziierten Scope deklariert sind. Ebenso wird der Fehler bpel:conflictingRequest nicht signalisiert, wenn die in dem onEvent spezifizierten PartnerLink- oder MessageExchange-Attribut in dem assoziierten Scope deklariert sind. Das gleiche trifft zu, wenn kein MessageExchange-Attribut explizit spezifiziert ist. Der Grund dafür ist, dass jede onEvent-Instanz ihre eigene Kopie von den Daten, die im assoziierten Scope deklariert sind, hält sowie ein implizites Default-MessageExchange deklariert.

Nachdem eine passende Nachricht eingetroffen ist, holt sich die die Transition T2 die ID der nächsten zu erzeugenden Scope-Instanz und bevor die ID zurück geschrieben wird, wird sie inkrementiert. Danach wird die Logik dieses Nachrichten-Event zu Ende ausgeführt und wenn keinen Fehler dabei signalisiert wird, schreibt die Transition T2 ein CF-Token auf dem ended-Platz des Event-EWFNs. Die Nachricht wird in den Variables-ended-Platz des assoziierten Scopes gespeichert und alle CorrelationSets, die zu initialisieren sind und in dem assoziierten Scope deklariert sind, werden mit Werten belegt. Der ended-Platz des Event-EWFNs ist identisch mit dem start-Platz des assoziierten Scopes. Sein EWFN entspricht dem Scope-EWFN (vgl.

Abschnitt 5.1).

Der Kontrollfluss bei einem Alarm-Event ist identisch mit dem bei einer Ausführung einer wait-Aktivität gefolgt von einem Scope.

Im zweiten Szenario wird der Fall betrachtet, dass der umgebende Scope beendet wurde und deswegen müssen seine EventHandlers deaktiviert werden. Eine Deaktivierung wird durch ein DP-Token auf dem start-Platz des EventHandlers-EWFNs signalisiert. Die Transition T1 schreibt beim Empfang eines DP-Token ein Tupel mit dem Wert eh in den to_MW-Platz.

Dadurch wird der Middleware-Komponente signalisiert, alle Tokens aus dem EventHandlers-EWFN einschließlich der Tokens aus den Event-EventHandlers-EWFNs zu entziehen. Die Tokens in den Scope-EWFNs werden belassen, da alle laufenden EventHandler-Instanzen nicht unterbrochen werden dürfen. Die Transition T3 schaltet wenn ein Token in den from_MW-Platz landet. Danach wartet sie auf ein CF- oder FAIL-Token auf dem ended-from_MW-Platz jedes Scopes, das mit einem onAlarm assoziirt ist, sowie auf die gleichen Tokens auf dem ended Platz des onEvent-Scope-EWFNs. Die Anzahl der Tokens, die dabei aus diesem Platz gelesen werden müssen, wird anhand des Platzes IDs bestimmt. Dieser Platz speichert dabei die Anzahl der aktiven oder bereits beendeten onEvent-Instanzen. Zum Schluss wird ein