• Keine Ergebnisse gefunden

3 Übersetzung der Grundaktivitäten

3.1 receive

Ein BPEL-Prozess bietet seine WebService-Operationen externen Partnern durch die receive-Aktivität an. Sie erlaubt dem BPEL-Prozess auf eine passende Nachricht zu warten und diese in einer Variablen abzulegen. Die receive-Aktivität spezifiziert über welchen PartnerLink die Nachricht empfangen wird, sowie welche Operation und optional PortType von dem Partner aufzurufen ist. Die receive-Aktivität blockiert solange die Ausführung von nachfolgenden Aktivitäten, bis eine passende Nachricht empfangen wird.

Die Aktivität spielt eine entscheidende Rolle im Lebenszyklus eines BPEL-Prozesses. Eine Möglichkeit eine neue Prozessinstanz zu erzeugen, ist eine receive-Aktivität mit dem Attribut createInstance=“yes“ zu versehen. [OAS07a] definiert eine startActivity als eine receive- oder pick-Aktivität, deren Attribut createInstance auf den Wert „yes“ gesetzt ist. Es ist erlaubt mehr als eine startActivity in einem BPEL-Prozess zu haben. Weiterhin definiert [OAS07a]

eine initialStartActivity als eine startActivity, die eine neue Prozessinstanz erzeugt. Die initialStartActivity einer bestimmten Prozessinstanz muss zu Ende ausgeführt werden, bevor andere startActivities aktiv werden. Das führt dazu, dass nur eine Nachricht, die in startActivities empfangen wird, die aktuelle Prozessinstanz erzeugt, wenn die Reihenfolge in der die einzelnen Nachrichten ankommen, nicht vorhersehbar ist. Zu diesem Zweck müssen mehrere startActivities mit correlationSets (vgl. Abschnitt 2.1) mindestens ein gemeinsames correlationSet besitzen und das Attribut initiate aller gemeinsamer correlationSets muss auf den Wert „join“ gesetzt werden. Konforme Implementierungen müssen sicherstellen, dass nur eine der eingehenden Nachrichten, die aktuelle Prozessinstanz erzeugt (normalerweise ist das die erste empfangene Nachricht, dennoch ist es implementierungsabhängig). Später ankommende Nachrichten werden an die receive-Aktivitäten in der bereits erzeugten Prozessinstanz weitergeleitet.

Das optionale Attribut messageExchange wird benutzt, um eine receive-Aktivität mit einer reply-Aktivität zu assoziieren.

Zur Verdeutlichung des Vorgangs der Evaluierung des Kontrollflusses und der Ausführung der receive-Aktivität durch das receive-EWFN sollen die einzelnen Schritte, die dabei durchlaufen werden, an dieser Stelle anhand eines Beispiels einer receive-Aktivität exemplarisch vorgestellt werden. Die Definition dieser receive-Aktivität ist in Listing 1 dargestellt.

<receive partnerLink=“Seller“ operation=“PurchaseResponse“ variable=”POResponse”

messageExchange=”ME”>

<correlations>

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

<correlation set=”Invoice” initiate=”yes” />

</correlations>

</receive>

Listing 1: Definition einer receive-Aktivität

Abbildung 6 zeigt den Aufbau des receive-EWFNs. Zuerst betrachtet man den Fall, dass die receive-Aktivität keine startActivity ist, d.h. das Attribut createInstance=“no“ ist. Wie sich das receive-EWFN verändert, wenn createInstance=“yes“ ist, d.h durch die receive-Aktivität eine neue Prozessinstanz erzeugt wird, wird im Anschluss erläutert.

Abbildung 6: receive-EWFN

Die Idee bei der Übersetzung der receive-Aktivität ist folgend: wenn der Kontrollfluss bei der receive-Aktivität angekommen ist, dann wird anhand der Plätze P1 und P2 überprüft, ob ein Konflikt mit einem parallel stattfindenden receive besteht. Bei einem Konflikt wird der Kontrollfluss an den FaultHandler weitergereicht und der receive ist damit beendet.

Ansonsten wird mit dem Empfang einer passenden Nachricht fortgeführt. Die einzelnen Nachrichten werden dabei, wie im Abschnitt 2.4 beschrieben, als Tupel in dem Platz

Messages modelliert. Eine Nachricht passt auf einem receive, wenn das Correlation Consistency Constaint (vgl. Abschnitt 2.1) nicht verletzt ist. Dazu benötigt man den Platz Correlations. Bevor der Inhalt der Nachricht in einer Variablen (repräsentiert als Tupel in dem Platz Variables) gespeichert wird und damit der Kontrollfluss an den Platz ended weitergereicht wird, werden alle CorrelationSets initiiert. Dabei können weitere Fehler signalisiert werden.

Im Folgenden wird die Evaluierung des Kontrollflusses durch die Transition T1 beschrieben.

Wenn die receive-Aktivität für eine Prozessinstanz aktiviert wird, dann liegt ein CF-Token auf dem start-Platz des receive-EWFN. Im nächsten Schritt wird in(te2) auf dem Platz P1 ausgeführt. te2 wird definiert als te2=(„Seller“, “PurchaseResponse“, „PurchaseOrder“, state:String). Wenn state=“open“ ist, dann bedeutet das, dass kein parallel stattfindender receive für das Tripel (Seller, PurchaseResponse, PurchaseOrder) in der aktuellen Prozessin-stanz aktiv ist. Danach wird out(tu2) auf dem Platz P1 mit tu2=(„Seller“,

“PurchaseResponse“, „PurchaseOrder“, „closed“) ausgeführt. Wenn state=“closed“ ist, dann wird der BPEL-Standardfehler bpel:conflictingReceive in den Platz failed geschrieben.

Analog dazu verläuft das Entdecken von einem parallel verlaufenden receive für das Tripel (Seller, PurchaseResponse, ME), d.h. es wird in(te3) mit te3= („Seller“,

„PurchaseResponse“, „ME“, state:String) auf dem Platz P2 ausgeführt. Wenn state=“open“

ist, dann wird out(tu3) mit tu3=(„Seller“, “PurchaseResponse“, „ME“, „closed“) ausgeführt, ansonsten wird der BPEL-Standardfehler bpel:conflictingRequest in den Platz failed geschrieben. In beiden Fällen wird der receive damit beendet.

Als nächstes muss T1 auf eine passende Nachricht warten. Passend bedeutet in diesem Zu-sammenhang, dass der Correlation Consistency Constaint eingehalten wird. Die Variable, in der die Nachricht abgelegt werden soll, muss von einem messageType sein, dessen Namen dem inputMessage der entsprechenden Operation äquivalent ist [W3C01]. Da WSDL-Messages aus mehreren logischen Parts aufgebaut werden können und die einzelnen Parts mit einem Typ aus einem beliebigen Typsystem, z.B. XSD [W3C04a], assoziiert werden, wird auf eine genaue Definition von te4 verzichtet. Durch te4 wird eine Nachricht aus dem Platz Messages gelesen, d.h. es wird read(te4) ausgeführt. Informal beschrieben liefert te4 eine Nachricht zurück, die auf dem PartnerLink „Seller“ bei dem Aufruf der Operation

„PurchaseResponse“ empfangen wurde. Der Datentyp dieser Nachricht muss dem Datentyp der Variablen „POResponse“ entsprechen. Weiterhin muss gelten, dass die Werte der Properties für den CorrelationSet „PurchaseOrder“ mit den Werten der Properties für einen bereits initiierten CorrelationSet „PurchaseOrder“ für die Prozessinstanz in der der receive aktiv ist übereinstimmen müssen. Ist der CorrelationSet „PurchaseOrder“ in der Prozessinstanz nicht initiiert oder ist der Correlation Consistency Constraint nicht erfüllt, dann blockiert die Operation read(te4) solange bis eine passende Nachricht empfangen wird.

Element aus der Menge A\B, die folgend definiert sind: A ist die Menge aller initiierten CorrelationSets für die Prozessinstanz, in der der receive aktiv ist. B ist die Menge, die als einziges Element den CorrelationSet „PurchaseOrder“ enthält. Informal beschrieben, werden dadurch eine zweite aktive receive-Aktivität aufgefunden (signalisiert durch „closed“), die auf den PartnerLink „Seller“ und der Operation „PurchaseResponse“ auf eine Nachricht warten. Als nächstes schreibt T1 das Tupel, das als Ergebnis der Operation in(te5) erhalten wurde, in den Platz P1 zurück, wobei das letzte Element auf dem Wert von id gesetzt wird.

Da jedoch mehr als zwei CorrelationSets in einem Scope oder Process (vgl. Abschnitt 5.1) deklariert sein können, muss die Operation in(te5) nicht nur ein einziges passendes Tupel zurückliefern, sondern alle Tupel, die den gleichen PartnerLink und Operation, wie die receive-Aktivität selbst, aber unterschiedliche CorrelationSets spezifizieren. Dazu benötigt man eine Erweiterung der Linda-Primitiven (vgl. Abschnitt 2.2) um eine neue Operation, die ähnlich einer read- bzw. take-Operation ist, allerdings alle passenden Tupel zurückliefert. In [M05] ist eine Erweiterung der einfachen Linda-Primitiven, die dieser Anforderung nachkommen, vorgeschlagen.

Als nächstes wird read(te6) auf dem Platz P1 ausgeführt, wobei te6=(„Seller“,

„PurchaseResponse“, „PurchaseOrder“, „closed“, id1:Integer). Nun werden die Werte von id1 und id verglichen und wenn sie gleich sind, dann wird der BPEL-Standardfehler bpel:ambigousReceive in den Platz failed geschrieben. Ansonsten wird der CorrelationSet

„Invoice“ initiiert, die Nachricht wird in die Variable „POResponse“ (repräsentiert als ein Tupel in dem Platz Variables) gespeichert und ein CF-Token wird auf den Platz ended produziert. Die Elemente derjenigen Tupel, die man für das Signalisieren eines Fehlers benutzt hat, werden auf „open“ zurückgesetzt. Wenn der CorrelationSet „Invoice“ bereits initiiert worden ist, dann wird den BPEL-Standardfehler bpel:correlationViolation in den Platz failed geschrieben. In beiden Fällen ist der receive damit beendet.

Im Folgenden betrachtet man, wie sich das Aussehen des receive-EWFN verändert, wenn eine oder mehrere receive-Aktivitäten mit dem Attribut createInstance=“yes“ vesehen sind. Das bedeutet im Einzelnen, welche zusätzlichen Plätze werden benötigt und welches Verhalten durch die Transition T1 gewährleistet werden muss, um das Erhalten der BPEL-Semantik zu garantieren.

Listing 2 zeigt ein Beispiel für eine Definition einer flow-Aktivität (vgl. Abschnitt 4.6), die zwei receive-Aktivitäten enthält. Es handelt sich dabei um startActivities mit dem gemeinsamen CorrelationSet „OrderNo“.

<correlationSets xmlns:cor=http://example.com/supplyCorrelation“>

<correlationSet name=“OrderNo“ properties=“cor:Order“ />

</correlationSets>

<flow>

<receive name=“GetLoginData“ partnerLink=“Customer“ operation=”enterLoginData” createInstance=”yes”>

<correlations>

<correlation set=”OrderNo“ initiate=“join“/>

<correlations>

</receive>

<receive name= “GetProductData“ partnerLink=“Customer“ operation=”enterProductData”

createInstance=”yes”>

<correlations>

<correlation set=”OrderNo“ initiate=“join“/>

<correlations>

</receive>

</flow>

Listing 2: Definition einer flow-Aktivität mit zwei receive-Aktivitäten

Wie am Anfang dieses Abschnittes bereits erläutert wurde, muss die initialStartActivity zu Ende ausgeführt werden, bevor die andere startActivity aktiv wird. In dem Beispiel oben be-deutet das, dass entweder die GetLoginData Aktivität oder die GetProductData Aktivität für zwei eingehende Nachrichten, die die gleichen Werte für das Property „Order“ enthalten, eine neue Prozessinstanz erzeugen wird.

Auf dem ersten Anblick könnte man meinen, dass man ähnlich wie bei dem Signalisieren von bpel:conflictingReceive bzw. bpel:conflictingRequest vorgehen kann, d.h. man hat einen zusätzlichen Platz, der Tupel der Form (correlationSet, property, value, state) speichert. Dann könnte jede receive-Aktivität in diesem Platz nachschauen, ob sich da ein Tupel befindet, der die zu erzeugende Prozessinstanz repräsentiert und dessen state=“open“ ist, danach state=“closed“ setzen und die Prozessinstanz in dem Platz Correlations erzeugen. Dieser Ansatz wird nicht funktionieren, weil dieser Platz, auf den man im Folgenden mit dem Namen ProsessInstance referenziert, nicht vorinitialisiert werden kann. Bei der Prozessinitialisierung kann man also nicht Tupel in diesem Platz ablegen, d.h. er ist leer. Damit es aber möglich ist, dass zwei receive-Aktivitäten synchron in dem Platz Tupel schreiben können ohne sich dabei in die Quere zu kommen, benötigt man einen zusätzlichen Platz, z.B. mit dem Namen PID, der eine Art Synchronisation-Token enthält. Bevor jetzt ein receive ein Tupel in dem Platz ProcessInstance schreibt, benötigt er das Token aus dem Platz PID und erst dann ist es sichergestellt, dass nur eine von mehreren für die Erzeugung der gleichen Prozessinstanz konkurrierende receive-Aktivitäten die Prozessinstanz tatsächlich erzeugen wird. Damit die Tupel aus dem Platz ProcessInstance wieder entfernt werden können, könnte man zuerst in den Platz Correlations schauen, ob sich da bereits eine Prozessinstanz befindet und wenn ja, dann das Verhalten von einem receive mit createInstance=“no“ nachgehen.

Erwähnenswert ist weiterhin, dass das Tupel in dem Platz PID die ID der zu erzeugenden

Operation eines WSDL-PortTypes des Prozesses. Die reply-Aktivität spezifiziert den PartnerLink, PortType und Operation über die die Antwort zu verschicken ist. Optional enthält sie das Attribut Variable, das die Variable spezifiziert, die die Nachricht enthält.

Das optionale Attribut messageExchange wird benutzt nur wenn bei der Ausführung einer Prozessinstanz mehrere gleichzeitig aktive IMA-reply Paare auftreten können.

[OAS07a] beschreibt eine open-IMA als der Zustand einer WebService-Operation, die durch eine Request-Response-IMA gestartet wurde, noch nicht aber durch eine assoziierte reply-Aktivität erfolgreich beendet wurde. Weiterhin definiert [OAS07a] eine orphaned-IMA als eine open-IMA, die einen PartnerLink oder MessageExchange benutzt, die in einem Scope, der gerade beendet wird oder beendet worden ist, definiert sind. Wenn die primäre Aktivität und die EventHandlers eines Scope beendet werden, dann wird überprüft, ob orphaned-IMAs existieren. Im Zusammenhang mit der reply-Aktivität bedeutet das, dass open-IMAs duch entsprechende reply-Aktivitäten „geschlossen“ werden, um dadurch nicht zu orphaned-IMAs zu werden.

Bei der Ausführung der reply-Aktivität kann einen BPEL-Standardfehler signalisiert werden, wenn die Aktivität nicht mit einer open-IMA assoziiert werden kann. Die Assoziation basiert dabei auf der Kombination aus PartnerLink, Operation und MessageExchange.

Listing 3 zeigt ein Beispiel für die Definition einer reply-Aktivität. Anhand dieses Beispiels wird im Folgenden die Evaluierung des Kontrollflusses durch das entsprechende reply-EWFN vorgestellt.

<reply partnerLink=“Customer“ operation=“Request“ variable=”Approval” messageExchange=”ME”>

<correlations>

<correlation set=”RequestID” initiate=”no” />

<correlation set=”ApprovalNo” initiate=”join” />

<correlation set=”ResponseID” initiate=”yes” />

</correlations>

</reply>

Listing 3: Definition einer reply-Aktivität

Abbildung 7 zeigt den Aufbau des reply-EWFNs.

Abbildung 7: reply-EWFN

Die Idee bei der Übersetzung ist folgend: zuerst wartet man, dass ein CF-Token auf dem Platz start geschrieben wird. Damit ist das reply aktiviert. Im nächsten Schritt wird überprüft, ob zu der reply-Aktivität eine zuvor erhaltene receive-Aktivität existiert. Dazu benötigt man den Platz P2 in dem reply-EWFN. Danach wird der Inhalt der Variablen (repräsentiert als Tupel im Platz Variables) ausgelesen und der Correlation Initiation Constraint (vgl. Abschnitt 2.1) überprüft, weshalb auf den Platz Correlations lesend zugegriffen wird. Ein Fehler aufgrund der oben genannten Überprüfungen wird über den Platz failed an den FaultHandler weitergeleitet. Der Inhalt der Variablen wird in eine Nachricht gespeichert, d. h. ein Tupel wird in den Platz Messages gespeichert. Die CorrelationSets werden initiiert und die open-IMA für das receive wird „geschlossen“. Der Kontrollfluss geht in den Platz ended über und die reply–Aktivität ist beendet.

Im Folgenden wird die Evaluierung des Kontrollflusses durch die Transition T1 beschrieben.

Wenn die reply-Aktivität aktiviert wird, dann liegt ein CF-Token auf dem start-Platz des reply-EWFN. Danach wird read(te2) auf dem Platz P2 ausgeführt mit te2=(„Customer“,

Platz Variables mit te3=(„Approval“, type:String, data:dataType) ausgeführt. Der Correlation Consistency Constraint (vgl. Abschnitt 2.1) wird überprüft, d.h. ob die Werte der Properties für den CorrelationSet „RequestID“ identisch sind mit den entsprechenden MessageParts der Variablen „data“. Falls der CorrelationSet „ApprovalNo“ für die aktuelle Prozessinstanz bereits initiiert worden ist, dann wird die gleiche Überprüfung vorgenommen.

Wenn der Correlation Consistency Constraint für eins von beiden CorrelationSets verletzt ist, dann wird der BPEL-Standardfehler bpel:correlationViolation in den Platz failed geschrieben. Als nächstes wird versucht, die CorrelationSets „ResponseID“ und

„ApprovalNo“, falls letzter nicht bereits initiiert worden ist, zu initiieren. Wenn der CorrelationSet „ResponseID“ bereits existiert, dann wird der BPEL-Standardfehler bpel:correlationViolation in den Platz failed geschrieben. Im letzten Schritt wird out(tu3) mit tu3=(„Customer“, „Request“, data) auf den Platz Messages ausgeführt und das reply ist damit beendet.

3.3 invoke

Die invoke-Aktivität wird verwendet um einen Web Service aufzurufen. Es wird spezifiziert über welchen PartnerLink der Partner Web Service aufzurufen ist, sowie die aufzurufende Operation des Partner-PortTypes. Die Operation kann sowohl One-Way als auch Request-Response sein, entsprechend den WSDL-Übertragungsprimitiven [W3C07a]. WS-BPEL benutzt die gleiche Syntax für die beiden Operationsarten mit einigen zusätzlichen Attributen für den Request-Response Fall. Ein One-Way Aufruf spezifiziert nur das Attribut inputVariable, während eine Request-Response-Operation zusätzlich das Attribut outputVariable festlegt.

Bei der Ausführung der invoke-Aktivität kann der BPEL-Standardfehler bpel:

uninitializedPartnerRole signalisiert werden. Bei einer Request-Response-Operation kann zusätzlich eine Fehlernachricht, sofern durch die entsprechende Operation spezifiziert, empfangen werden. Die Fehlernachricht veranlasst das Ausführen einer intern festgelegten catch- bzw. catchAll-Aktivität oder den Aufruf des zuständigen FaultHandlers.

Listing 5 zeigt ein Beispiel für die Definition einer invoke-Aktivität. Anhand dieses Beispiels wird im Folgenden die Evaluierung des Kontrollflusses durch das entsprechende reply-EWFN vorgestellt. Das Beispiel zeigt den Request-Response Fall, weil dieser sicherlich der kompliziertere ist und die One-Way Variante mit sich beinhaltet. Dem Leser wird an einer geeigneten Stelle bei der Beschreibung des Kontrollflusses mitgeteilt, wo der One-Way-invoke zu Ende ist. Listing 4 zeigt die WSDL-PortTypeDefinition des PortTypes

„PurchasingPT“, der in dem Beispiel benutzt wird. Dadurch ist es ersichtlich und nachvollziehbar, dass der invoke als Antwort eine Fehlernachricht erhalten kann, die für den Vorgang der Evaluierung des Kontrollflusses von entscheidender Bedeutung ist.

<wsdl:definitions

targetNamespace=“http://example.com/purchasing“

xmlns:smsg=“http://example.com/supplyMessages“>

xmlns:wsdl=“http://schemas.xmlsoap.org/wsdl/“>

xmlns:pos=“http://example.com/purchasing“>

<wsdl:portType name=“PurchasingPT“>

<wsdl:operation name=“Purchase“>

<wsdl:input message=“smsg:POMessage“/>

<wsdl:output message=”smsg:POResponse”/>

<wsdl:fault name=”tns:RejectPO” message=”smsg:PoReject”/>

</wsdl:operation>

</wsdl:definitions>

Listing 4: Definition einer Request-Response-Operation mit einem fault-Element

Im Listing 5 repräsentiert das Präfix SP den Namensraum “http://example.com/purchasing“.

<invoke partnerLink="Seller" portType="SP:PurchasingPT" operation="SP:Purchase" inputVariable="sendPO"

outputVariable="getResponse">

<correlations>

<correlation set="PurchaseOrder" initiate="yes" pattern="request" />

<correlation set="Invoice" initiate="yes" pattern="response" />

</correlations>

</invoke>

Listing 5: Definition einer invoke-Aktivität

Abbildung 8 zeigt die Plätze und Transitionen aus denen sich das invoke-EWFN zusammensetzt.

Abbildung 8: invoke-EWFN

Bevor man mit der genauen Beschreibung der Transition T1 beginnt, möchte man die Idee bei der Übersetzung der invoke-Aktivität erläutern. Ein invoke ist sehr ähnlich von der Funktionsweise einem reply gefolgt von einem receive. Die zu versendende Nachricht wird aus einer Variablen gelesen und als eine Nachricht verschickt, anschließend wird auf eine Nachricht gewartet und diese wird in eine Variable gespeichert. Im Unterschied zu einem reply benötigt man bei einem invoke keine Nachricht, die zuvor durch eine IMA [OAS07a]

empfangen wurde. Für die Übersetzung bedeutet das, dass keine Überprüfung stattfindet und deswegen einen Zugriff auf den Platz P2 nicht benötigt wird. Bei einem receive wurde das Signalisieren des BPEL-Standardfehlers bpel:conflictingReceive durch den Platz P1 modelliert. Da dieser Fehler bei einem invoke nicht auftreten kann, wird ein Zugriff auf den Platz P1 in dem invoke-EWFN ebenfalls nicht benötigt. Der Correlation Initiation Constraint bzw. Correlation Consistency Constraint (vgl. Abschnitt 2.1) werden getrennt für die beide Nachrichten (input und output) überprüft.

Da bei der Übersetzung der reply- und der receive-Aktivität bereits Vorarbeit durch die genaue Beschreibung der Transitionen für diese zwei Aktivitäten, geleistet wurde, verzichtet man an dieser Stelle von der gesamten Spezifikation der Transition T1. Stattdessen werden nur die Stellen bei der Kontrollflussevaluierung berücksichtigt, die eigen für die invoke-Aktivität sind und deswegen bereits nicht besprochen wurden.

Im Folgenden gilt die Annahme, dass der PartnerLink „Seller“ mit dem initializePartnerRole=“yes“ Attribut definiert wurde.

Nachdem ein CF-Token aus dem start-Platz gelesen wurde, überprüft die invoke-Aktivität ob der PartnerLink „Seller“ initialisiert wurde (vgl Abschnitt 5.1). Dazu wird der Platz PartnerLinks benötigt. Es wird also read(te1) auf dem Platz PartnerLinks mit te1=(„Seller“

value:String) ausgeführt. Wenn der PartnerLink nicht initialisiert worden ist, dann wird der BPEL-Standardfehler bpel:unitializedPartnerRole in den failed Platz geschrieben und der invoke ist damit beendet. Ansonsten wird wie im Abschnitt 3.2 vorgegangen (d.h. die gleiche Kontrollflussevaluierung wie bei einem reply). An dieser Stelle wäre ein One-Way-invoke beendet, d.h. ein CF-Token wird in den Platz ended geschrieben. Da man das kompliziertere Szenario mittels eines Request-Response-invoke beschreiben möchte wird die Kontrollflussevaluierung für die invoke-Aktivität weiter mit dem Warten auf eine passende Nachricht auf dem Platz Messages weiter. Das Warten auf eine passende Nachricht bedeutet

value:String) ausgeführt. Wenn der PartnerLink nicht initialisiert worden ist, dann wird der BPEL-Standardfehler bpel:unitializedPartnerRole in den failed Platz geschrieben und der invoke ist damit beendet. Ansonsten wird wie im Abschnitt 3.2 vorgegangen (d.h. die gleiche Kontrollflussevaluierung wie bei einem reply). An dieser Stelle wäre ein One-Way-invoke beendet, d.h. ein CF-Token wird in den Platz ended geschrieben. Da man das kompliziertere Szenario mittels eines Request-Response-invoke beschreiben möchte wird die Kontrollflussevaluierung für die invoke-Aktivität weiter mit dem Warten auf eine passende Nachricht auf dem Platz Messages weiter. Das Warten auf eine passende Nachricht bedeutet