FaultHandling Hinweise zum Design von Fault Handling in SOA Composite Applications Matthias Furrer Principal Consultant Dezember 2014 Dieses Dokument beschreibt allgemeine Hinweise und Best Practices zum Fault- und Exception Handling zur Anwendung in SOA Composite Applications der Oracle SOA Suite 11g. Folgende Themenbereiche werden behandelt: • Business- Fault und System-Fault in SOA Composite Applications • Auslösung und Behandlung von Faults in SOA Composite Applications • Einsatz des Fault-Policy Frameworks In diesem Dokument werden neben generellen Empfehlungen auch aus Sicht des Entwicklers, praktische „How-To’s“ beschrieben, wie ein effizientes Fehlerhandling innerhalb von Service Components mit der Oracle SOA Suite durchgeführt werden kann. Die in diesem Dokument beschriebenen Szenarien wurden getestet mit Oracle SOA Suite 11.1.1.7 (11gR1 PS6). [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 2 / 26 1. Fehlerkategorien in SOA Composite Applikationen 1.1 Business Fault Business Fault sind gültige Response Nachrichten, informieren den Service Consumer jedoch darüber, dass im Verarbeitungs- Prozess ein Fehler aufgetreten ist. Business Faults können beschrieben werden als den Zustand der Nicht-Erfüllung einer spezifischen Geschäftsanforderung. Typische Beispiele sind fachliche Validierungsfehler, die in einem Service auftreten können. Typische Merkmale von Business Fault in einem Prozess sind: Vorhersehbar Wiederherstellbar oder kein Bedarf zur Wiederherstellung Retry meist nicht sinnvoll Rollback/Compensation oft nicht notwendig (bspw. bei Validierungsfehlern) Business Fault sind immer im Service Contract (WSDL) des Provider Services als SOAP Faults definiert und zeigen die Fehlerinformation über eine entsprechend definierte Fault Message an. Business Fault der Service Provider können von aufrufenden Service Komponenten über FaultPolicies und/oder entsprechenden Catch-Blöcke im BPEL Code abgehandelt werden. Identifiziert wird der Fault dabei durch den retournierten Namespace. In Oracle Service Bus können diese über entsprechende Error Handler mit Hilfe des Error-Pipeline-Konstrukt im Message Flow des Proxy Services abgefangen werden. Gemäss Spezifikationen von W3C muss die entsprechende Serviceinstanz bei Rückgabe eines SOAP Fault immer mit HTTP Response Status «500» antworten [W3C-SOAP]. Ebenso ist dies im Basic Profile 1.2 von WS-I beschrieben [WSI-PROF1.2]. Viele gebräuchliche Implementierungen von Webservice Frameworks beziehen sich darauf, so wird bspw. im Oracle Service Bus (OSB) ein ErrorHandler Catch Block implizit nur dann aufgerufen, wenn der Service Provider mit HTTP Status «500» antwortet. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 3 / 26 1.2 System (Runtime) Fault Runtime Fault entstehen durch Probleme innerhalb einer BPEL Prozess Service Komponente, oder durch Probleme beim Aufruf von Webservices oder JCA Adaptern. Diese Fehler sind nicht benutzerdefiniert und werden von der Laufzeitumgebung ausgelöst. Grundsätzlich handelt es sich dabei um schwer vorhersehbare technische Fehler oder durch Fehler in der Programmlogik unter bestimmten Konstellationen. Diese Laufzeitfehler sind im http://schemas.oracle.com/bpel/extension definiert und beziehen sich immer auf den Messagetype RuntimeFaultMessage. Analog den Business Fault können diese über den Namespace oder Messagetype/LocalPart entweder direkt über einen Catch-Block im BPEL Prozess oder aber über das Fault Policy Framework abgefangen und behandelt werden. 1.2.1 Wichtigste Laufzeit Fehler 1.2.1.1 remoteFault remoteFault entstehen beim Aufruf von externen Services. Dies ist beispielsweise dann der Fall, wenn versucht wird über einen JCA Adapter auf eine Datenbank zuzugreifen, welche aktuell nicht verfügbar ist oder einen Webservice aufzurufen der unter der angegebenen URL nicht erreichbar ist. SOAP Fault von externen Webservices oder Fault welche aus SOA Servicekomponenten an den Aufrufer retourniert werden und nicht in deren Service-Contract als SOAP-Fault definiert sind, werden in BPEL Service Komponenten ebenfalls als remoteFault empfangen. 1.2.1.2 bindingFault bindingFault entstehen innerhalb einer bestimmten Aktivität und häufig beispielsweise im JCA Adapter Framework. Fehler bei Datenoperationen – z.B. ungültige Werte, Primärschlüsselverletzungen etc. werden als bindingFault zurückgegeben und können im Prozess als solche behandelt werden. 1.2.1.3 selectionFailure selectionFailure treten typischerweise dann auf, wenn ohne entsprechende Ignore Anweisung über XPath auf ein Element in einer XML Struktur zugegriffen wird, welches nicht vorhanden ist. 1.2.1.4 rollback rollback kann aus BPEL Service Komponenten – typischerweise in einem Sub-Prozess – durch eine Throw Activity ausgelöst werden, um eine globale Transaktion zu steuern. Abhängig vom Transaction Property kann die aufrufende Komponente eine XA Transaktion rückgängig machen oder die globale Transaktion wird automatisch zurückgerollt. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 4 / 26 2. Auslösung von Faults in SOA Composite Applikationen 2.1 Auslösen von Business Faults aus BPEL Service Komponenten 2.1.1 Service Contract Contract (WSDL) Voraussetzung für die Rückgabe von Business Faults ist die Definition des entsprechenden Fault im Service Contract in der PortType Section für die jeweilige Operation: <wsdl:operation name="myOperation"> <wsdl:input name="myOperationRequest" message="tns:myOperationRequestMsg"/> <wsdl:output name="myOperationResponse" message="tns:myOperationResponseMsg"/> <wsdl:fault name="ValidationFault" message="err:ValidationFaultMsg"/> <wsdl:fault name="EntityNotFoundFault" message="err:EntityNotFoundFaultMsg"/> </wsdl:operation> Dabei kann eine beliebige Anzahl von Fault definiert werden. In obigem Beispiel werden zwei verschiedene mögliche Fehler für die Operation „myOperation“ definiert. Faults können gemäss Spezifikationen von W3C jedoch nur für Operationen mit synchronem Message Exchange Pattern verwendet werden. Ebenso müssen die Faults zwingend in der Binding Section für die Operation definiert sein: <wsdl:operation name="myOperation"> <soap:operation soapAction="http://bds.trivadis.com/test/faulthandling/ServiceProvider"/> <wsdl:input> <soap:body use="literal" parts="myOperationRequest"/> </wsdl:input> <wsdl:output> <soap:body use="literal" parts="myOperationResponse"/> </wsdl:output> wsdl:fault name="ValidationFault"> <soap:fault name="ValidationFault" use="literal"/> </wsdl:fault> <wsdl:fault name="EntityNotFoundFault"> <soap:fault name="EntityNotFoundFault" use="literal"/> </wsdl:fault> </wsdl:operation> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 5 / 26 2.1.2 BPEL Process Service Komponente In BPEL Prozessen können Business Fault sowohl über die throw als auch die reply Anweisung an den aufrufenden Service (innerhalb oder ausserhalb der SOA Suite) ausgelöst werden. Sowohl für den Service-Consumer als auch die Service-Komponente selbst gibt es entscheidende Unterschiede zwischen den beiden Varianten. Diese werden in den nachfolgenden Kapiteln beschrieben. Um einen typisierten Business Fault in der korrekten, gemäss WSDL definierten Struktur, auszulösen, muss in beiden Fällen eine Faultvariable, welche der im Service Contract vorgesehenen Fault Message entspricht, verwendet werden. Ansonsten entspricht der Payload der Response Message nicht der im Service Contract definierten Struktur. Die vordefinierte outputVariable kann dazu nicht verwendet werden, da diese vom Framework auf die reguläre Output Message Struktur der Serviceoperation definiert wird. 2.1.2.1 Definition der Fehlervariable Die Definition der Faultvariable kann entweder über die graphische Benutzeroberfläche oder direkt im Code erfolgen. Dabei sollte die Variable als MessageType definiert werden. Faultvariablen Definition über Design-View: Faultvariablen Definition im BPEL-Code: <variable name="ValidationFaultVariable" messageType="client:ValidationFaultMsg"/> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 6 / 26 2.1.2.2 Erzeugung des Fault Payload in Rückgabevariable Die Fault Variable kann ganz normal wie jede andere Laufzeitvariable in BPEL mittels einer assign Anweisung befüllt werden. Im Beispiel unten wird das Element welches bei der Rückgabe an den Service Consumer für die SOAP Fault Message verwendet wird, mit einem konstanten Wert und zusätzlichen Angaben zu Prozess- und Instanz-Identifikation gesetzt: Beispiel Fault Payload Population im BPEL-Code: <assign name="setValidationFault"> <copy> <from>concat('Validation Fault in Process: ', ora:getProcessId(), ' / InstanceId ', ora:getInstanceId())</from> <to>$ValidationFaultVariable.ValidationFault/client:validationFaultString</to> </copy> </assign> 2.1.2.3 Fehlerauslösung des Business Faults mittels ‚throw‘ Activity Bei Eintreten einer Fehlersituation, kann in der entsprechenden Verzweigung des Programmablaufs der Fehler ausgelöst werden. Dies kann wiederum auch direkt über die graphische Oberfläche der IDE oder direkt im Code definiert werden. Wird ein Business Fault über die Throw Activity ausgelöst und es befindet sich keine Fehlerbehandlungsroutine in Form einer catch Anweisung in der Prozessdefinition für den geworfenen Fehler, werden keine nachfolgenden Schritte in der Ablauflogik mehr ausgeführt. In diesem Fall wird die Instanz unmittelbar beendet. Fehlerauslösung mit Throw Activity über Design-View: Fehlerauslösung mit Throw Activity im BPEL-Code: <throw name="ThrowValidationFault" faultName="ns1:ValidationFault" faultVariable="validationFaultVariable"/> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 7 / 26 2nd1.2.4 Rückgabe des Business Faults mittels Reply Activity Wie bei der throw Anweisung kann der Business Fault bei Eintreten einer Fehlersituation in der entsprechenden Verzweigung des Programmablaufs mittels einer reply Anweisung an den Service Consumer zurückgeben werden. Im Unterschied zur Throw Activity wird bei Verwendung der Reply Activity die Prozess-Ablauflogik nicht beendet. Nachfolgend definierte Schritte im Prozessablauf werden trotzdem noch komplett bis zum Prozessende ausgeführt. Wird demzufolge die reply Anweisung nicht aus einem Catch-Block der Prozessdefinitionsebene ausgeführt, muss entweder mit Programmablauflogik oder mit dem skipCondition Konstukt in BPEL sichergestellt werden, dass unerwünschte nachfolgend definierte Prozessschritte nicht mehr ausgeführt werden. Alternativ kann auch eine exit Anweisung unmittelbar nach der Fehlerrückgabe zur Beendigung der Prozessinstanz verwendet werden. Damit wird allerdings zusätzlich auch die Composite-Instance auf den Status „Terminated“ gesetzt. Im Gegensatz dazu, wird bei einer Fehlerrückgabe mit Fault QName der Instanz-Status mit „Faulted“ markiert. Fehlerrückgabe über Design-View: Fehlerrückgabe im BPEL-Code: <reply name="ReplyDefinedFaultIfRequested" partnerLink="serviceprovider_client" portType="client:ServiceProviderPortType" operation="ServiceProviderOperation" variable="ValidationFaultVariable" xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable" faultName="client:ValidationFault"/> Wichtig dabei ist, dass im Gegensatz zu einem Reply ohne Fehler, das Element faultName definiert wird. Dies stellt sicher dass der HTTP 500 Status an den Consumer retourniert wird. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 8 / 26 2.2 Auslösen von System Faults aus BPEL Service Komponenten Ein Systemfault wird normalerweise mit einer throw Anweisung ausgelöst. Grundsätzlich könnte dies zwar auch über eine Reply Activity geschehen. Bei System Faults handelt es sich typischerweise jedoch um schwerwiegende Fehler, die einen unmittelbaren Abbruch der Prozessinstanz und Rollback der Transaktion auslösen sollen. Zudem wird die Reply Activity üblicherweise nur für Request/Reply Nachrichtenaustausch, also für Services mit synchronem Interface, verwendet. 2.3 Unterschiedliches Verhalten von Fehlerrückgabe über throw und reply 2.3.1 Unterschiede im Verhalten und SOAP Response Szenario: Direktaufruf des Provider-Composites als SOAP-WS (Implementierung in BPEL) Kein Faulthandling im Prozess Request / Reply Message Exchange Pattern (synchrones Interface) Faulttype RückgabeArt BusinessFault Systemfault (nicht in WSDL) SOAP Faultcode Throw Abbruch Prozess ja Reply Nein Businessfault Name Throw ja Systemfault Name Reply nein env:Server Businessfault Name Response Payload Gemäss Faultdefinition [B-2.3.1a] Gemäss Faultdefinition [B-2.3.1a] Generisch [B-2.3.1b] Instance State Faulted Component State Faulted Faulted Completed Faulted Faulted Entspricht Response Provider [B-2.3.1c] Faulted Completed Wie aus obiger Aufstellung ersichtlich, wird dabei die SOAP Response unterschiedlich generiert. Probleme kann unter Umständen der Business- oder System-Faultname im faultcode Element verursachen, da hier sowohl in der SOAP 1.1. [W3C-SOAP-F11] als auch SOAP 1.2 Spezifikation [W3C-SOAP-F11] nur ein definiertes Set von gültigen Werten zugelassen ist. Zusätzlich wird bei einer Rückgabe mittels Throw Activity der Component State auf „Faulted“ gesetzt, während diese bei Verwendung einer Retry Activity auf „Completed“ markiert werden. Die Composite-Instanz wird in jedem Fall als abgebrochen markiert, da im vorliegenden Szenario nirgends ein Fehlerhandling stattfindet. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 9 / 26 Beispiel [B-2.3.1a]: SOAP Response bei Businessfault Rückgabe <env:Body> <env:Fault xmlns:ns0="http://bds.trivadis.com/test/faulthandling/ServiceProvider"> <faultcode>ns0:ValidationFault</faultcode> <faultstring/> <faultactor/> <detail> <ValidationFault xmlns="http://bds.trivadis.com/test/faulthandling/ServiceProvider"> <validationFaultString>Validation Fault in Process ServiceProvider / InstanceId 480276</validationFaultString> </ValidationFault> </detail> </env:Fault> </env:Body> Beispiel [B-2.3.1b]: SOAP Response bei SystemFault Rückgabe mit throw <env:Body> <env:Fault xmlns:ns0="http://schemas.oracle.com/bpel/extension"> <faultcode>ns0:assertFailure</faultcode> <faultstring>faultName: {{http://schemas.oracle.com/bpel/extension}assertFailure} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage}</faultstring> <faultactor/> <detail> <exception/> </detail> </env:Fault> </env:Body> Beispiel [B-2.3.1c]: SOAP Response bei SystemFault Rückgabe mit reply <env:Body> <env:Fault> <faultcode>env:Server</faultcode> <faultstring>TVD Fault Summary</faultstring> <faultactor/> <detail> <exception>TVD Fault Detail</exception> </detail> </env:Fault> </env:Body> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 10 / 26 2.3.2 Auswirkungen auf den Service Consumer (SOA Component/Application) Szenario: Aufruf des Service Providers (BPEL Service Komponente) aus Consumer (BPEL) Faulthandling im Consumer ist vorhanden Synchrone Kommunikation zwischen Consumer und Provider Keine Business-Fault definiert im Service Consumer Faulttype RückgabeArt Provider BusinessFault Systemfault Systemfault (nicht in WSDL) Fehler erhalten im Consumer Response Payload Consumer Throw Reply Throw Abbruch Prozess Consumer nein nein nein Original Fault Original Fault bpelx:remoteFault Gemäss Faulthandling Gemäss Faulthandling Gemäss Faulthandling Composite Inst. State / Provider Compo. Inst. State Faulted Completed Faulted Reply nein bpelx:remoteFault Gemäss Faulthandling Completed Die Rückgabeart des Fehlers wirkt sich auf den Instance State der Composite-Instanz aus. Wird ein Fehler mittels Throw Activity zurückgegeben, wird sowohl der Instance State des Composites als auch der Provider Komponente als „Faulted“ markiert, obwohl der Fehler in der aufrufenden Komponente (Consumer) behandelt worden ist. Bei einer Rückgabe mit Reply Activity werden diese Instanzen auf „Completed“ gesetzt. Zu beachten ist auch, dass bei Interaktionen zwischen SOA Components Fehler die im aufgerufenen Service geworfen werden und nicht im WSDL des aufrufenden Services definiert sind, von der aufrufenden Komponente immer als bpelx:remoteFault empfangen werden. Fehlerrückgabe im Provider mit reply Anweisung: Fehlerrückgabe im Provider mit throw Anweisung: [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 11 / 26 2.3.2.1 Szenario: Kein Fault Handling im Service Consumer Aufruf des Service Providers (BPEL Service Komponente) aus Consumer (BPEL Service Komponente) Kein Faulthandling im Consumer vorhanden Synchrone Kommunikation zwischen Consumer und Provider Keine Business-Fault definiert im Service Consumer Faulttype RückgabeArt Provider BusinessFault Systemfault Systemfault (nicht in WSDL) SOAP faultCode Response Payload Consumer Throw Reply Throw Abbruch Prozess Consumer ja ja ja Businessfault Name Businessfault Name Systemfault Name Generisch [B-2.3.2a] Generisch [B-2.3.2a] Generisch [B-2.3.2a] Reply ja env:Server Entspricht Response Provider [B-2.3.2b] Composite Inst. State / Provider Inst. State Faulted Faulted Faulted Faulted Die Rückgabeart des Fehlers wirkt sich auf die Response des Consumers aus, falls dieser den Fehler nicht behandelt. Beispiel [B-2.3.2a]: Generische SOAP Response bei Rückgabe mit Throw Activity <env:Body> <env:Fault xmlns:ns0="http://bds.trivadis.com/test/faulthandling/ServiceProvider"> <faultcode>ns0:ValidationFault</faultcode> <faultstring>faultName: {{http://bds.trivadis.com/test/faulthandling/ServiceProvider}ValidationFault} messageType: {{http://bds.trivadis.com/test/faulthandling/ServiceProvider}ValidationFaultMsg} parts: {{ValidationFault=<ValidationFault xmlns="http://bds.trivadis.com/test/faulthandling/ServiceProvider"> <validationFaultString>Validation Fault in Process ServiceProvider / InstanceId 480109</validationFaultString></ValidationFault>}cause: {null} </faultstring> <faultactor/> <detail> <exception/> </detail> </env:Fault> </env:Body> Beispiel [B-2.3.2b]: SOAP Response bei Rückgabe mit Reply Activity <env:Body> <env:Fault> <faultcode>env:Server</faultcode> <faultstring>TVD Fault Summary</faultstring> <faultactor/> <detail> <exception>TVD Fault Detail</exception> </detail> </env:Fault> </env:Body> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 12 / 26 2.3.3 Transaktionen Das Transaktionsverhalten von BPEL Service Komponenten in der SOA-Suite hängt von folgenden Faktoren ab: Property bpel.config.transaction auf Component Ebene in Composite Definition (composite.xml) Property bpel.config.oneWayDeliveryPolicy auf Component in Composite Definition (composite.xml) für One-Way oder Asynchrone Services Fehlerbehandlung vorhanden Fehlerauslösung / -rückgabe (throw oder reply Anweisung) Eine detaillierte Beschreibung über die Transaktionssemantik der BPEL Service Engine befindet sich im Oracle SOA Suite Developer Guide [ORA-FMW-TR]. 2.3.3.1 Szenario: Fehlerrückgabe--Art in synchronen Aufrufen Einfluss der Fehlerrückgabe Aufruf des Service Providers (BPEL Service Komponente) aus Consumer (BPEL Service Komponente) mit Faulthandling im Consumer Synchrone Kommunikation zwischen Consumer und Provider Verwendung EIS Ressource mit Unterstützung von globalen Transaktionen (z.B. XA Datasource) Transaction Property Provider required requiresNew RückgabeRückgabe-Art Provider Throw Transaktion im Provider Prozess Abhängig von Fault-Handling in Consumer Reply Throw Abhängig von Fault-Handling in Consumer Rollbacked Reply Saved Transaktion im Consumer Prozess Consumer steuert die globale Transaktion. Falls Fehler abgefangen wird (Catch) wird globale Transaktion committed – ansonsten verworfen. Consumer steuert die globale Transaktion Consumer läuft in eigener Transaktion. Falls Fehler abgefangen wird (Catch) wird Transaktion geschrieben – ansonsten verworfen. Consumer läuft in eigener Transaktion. Falls das Transaction Property (bpel.config.transaction) einer BPEL-Komponente auf required gesetzt ist, nimmt dieser Service an einer ggf. bereits vorhandenen Transaktion teil. In diesem Falle ist das Transaktionsverhalten abhängig davon, ob die aufrufende Komponente (Consumer) den zurückgegebenen Fehler behandelt oder nicht. Die Fehlerrückgabeart ist in diesem Fall nicht relevant. Falls im Consumer kein Fehlerhandling stattfindet, wird die gesamte Transaktion zurückgefahren. Falls das Transaction Property jedoch auf requiresNew gesetzt wird, wird in jedem Fall eine neue Transaktion eröffnet. Dies bedeutet, dass falls in der aufgerufenen Komponente (Provider) ein unbehandelter Fehler auftritt, dessen Transaktion zurückgefahren wird – unabhängig davon ob der Aufrufer den Fehler behandelt oder nicht. Da die throw Anweisung ohne entsprechende Behandlung im gleichen Prozess immer einen Abbruch bewirkt, wird auch die dazugehörige [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 13 / 26 Transaktion rückgängig gemacht. Eine reply Anweisung gilt dagegen als Fehlerbehandlung, auch wenn dabei ein SOAP-Fault als Service-Response erzeugt wird. 2.4 Empfehlungen • Business Fault sollten aufgrund der oben beschriebenen Auswirkungen auf das Transaktionsverhalten generell über die Reply Activity an den Consumer retourniert werden. • Falls explizit Runtime Fault ausgelöst werden müssen, sollte dazu generell die Throw Activity verwendet werden, da diese den Prozessablauf sofort beendet und die Instanz als fehlerhaft markiert. • Die Throw Activity sollte nur verwendet werden, um Transaktionen der „eigenen“ Komponente abzubrechen. • In Services mit asynchronem Message Exchange Pattern können Fehler über dedizierte Fehlermessages mittels Invoke Activity an die Callback-Adresse des Consumer zurückgegeben werden. Diese sind jedoch keine SOAP Faults. • Bei der Verwendung der Throw Activity in one-way oder asynchronen Services sollten die Auswirkungen auf das Transaktionsverhalten ebenfalls berücksichtigt werden – z.B. (bpel.config.oneWayDeliveryPolicy). [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 14 / 26 3. Behandlung von Faults in SOA Composite Applikationen 3.1 Behandlung von Faults in BPEL Service Komponenten 3.1.1 Behandlung von Runtime Faults 3.1.1.1 Einbindung Einbindung der Definitionen von Runtime Faults Um auf den Inhalt von Runtime Faults Variablen abfragen zu können, müssen die Definitionen von RuntimeFault.wsdl importiert werden. Dies kann direkt in der Definition der BPEL Komponente oder im WSDL über folgende Anweisung erreicht werden. <import namespace="http://schemas.oracle.com/bpel/extension" location="oramds:/soa/shared/bpel/RuntimeFault.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"/> Falls bereits explizit ein Runtime Fault mit einer Throw Activity über die graphische Oberfläche im BPEL Flow benutzt wurde, wird diese Anweisung automatisch erzeugt. Allerdings wird dabei das Fault WSDL lokal ins Projekt kopiert und da referenziert. Sinnvollerweise sollte diese jedoch wie oben gezeigt aus dem MDS importiert werden. 3.1.1.2 Definitionen im RuntimeFaultMessage Nachdem die Definitionen in das Projekt eingebunden sind, kann über die zugeordnete Fault Variable auf folgende Elemente in der generischen Message-Struktur von Runtime Fault im Catchblock zugegriffen werden: <message name="RuntimeFaultMessage"> <part name="code" type="xsd:string"/> <part name="summary" type="xsd:string"/> <part name="detail" type="xsd:string"/> </message> Diese Informationen können verwendet werden um bspw. wiederum eine einheitliche Fault Response an den Consumer des entsprechenden Service zu generieren. Alternativ kann auch die Oracle Advanced XPath Funktion ora:getFaultAsString verwendet werden. Diese liefert den Fehler jedoch unstrukturiert und damit nur als String Type. Beispiel Inhalt Fault Variable bei bindingFault <RuntimeFault> <part name="summary" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <summary> Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'insert' failed due to: DBWriteInteractionSpec Execute Failed Exception. insert failed. Descriptor name: [ClsMsgQueue.MessageClsIvav]. Caused by java.sql.BatchUpdateException: ORA-00001: unique constraint (MFU_IVZ.MCI_UK) violated . Please see the logs for the full DBAdapter logging output prior to this exception. This exception is considered not retriable, likely due to a modelling mistake. To classify it as retriable instead add property nonRetriableErrorCodes with value "-1" to your deployment descriptor (i.e. weblogic-ra.xml). To auto retry a retriable fault set these composite.xml [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 15 / 26 properties for this invoke: jca.retry.interval, jca.retry.count, and jca.retry.backoff. properties are integers. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary> </part> <part name="detail" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <detail> ORA-00001: unique constraint (MFU_IVZ.MCI_UK) violated </detail> </part> <part name="code" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <code>1</code> </part> </RuntimeFault> All Beispiel: Rückgabewert von ‚getFaultAsString() bei bindingFault <Var xmlns:def="http://www.w3.org/2001/XMLSchema" xsi:type="def:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> com.oracle.bpel.client.BPELFault: faultName: {{http://schemas.oracle.com/bpel/extension}bindingFault} messageType: {{http://schemas.oracle.com/bpel/extension}RuntimeFaultMessage} parts: {{ summary=<summary>Exception occured when binding was invoked. Exception occured during invocation of JCA binding: "JCA Binding execute of Reference operation 'insert' failed due to: DBWriteInteractionSpec Execute Failed Exception. insert failed. Descriptor name: [ClsMsgQueue.MessageClsIvav]. Caused by java.sql.BatchUpdateException: ORA-00001: unique constraint (MFU_IVZ.MCI_UK) violated . Please see the logs for the full DBAdapter logging output prior to this exception. This exception is considered not retriable, likely due to a modelling mistake. To classify it as retriable instead add property nonRetriableErrorCodes with value "-1" to your deployment descriptor (i.e. weblogic-ra.xml). To auto retry a retriable fault set these composite.xml properties for this invoke: jca.retry.interval, jca.retry.count, and jca.retry.backoff. All properties are integers. ". The invoked JCA adapter raised a resource exception. Please examine the above error message carefully to determine a resolution. </summary> ,detail=<detail>ORA-00001: unique constraint (MFU_IVZ.MCI_UK) violated </detail> ,code=<code>1</code>} </Var> 3.1.2 Behandlung von Business Faults Um auf den Inhalt von Business Fault Variablen abfragen zu können, muss gleich wie bei den Runtime Fault eine Fault Variable definiert werden. Diese kann direkt im Catch Block mit dem entsprechenden Messagetype definiert werden. Beispiel Fault Variable im Catch-Block: <catch faultName="ns1:ValidationFault " faultVariable="BusinessFaultVariable" faultMessageType="ns1:ValidationFaultMsg"> Damit kann dann in der zugehörigen Fehlerbehandlungslogik auf den Inhalt der Fehlermeldung zugegriffen werden. Diesbezüglich besteht kein Unterschied zu Runtime Fault. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 16 / 26 3.1.3 Fault Catch Block in BPEL Runtime Fault sowie Business Fault können gleichermassen über eine Catch Activity im BPEL Prozess abgefangen, behandelt und an den Consumer zurückgegeben werden. Gegebenenfalls kann bei entsprechender Anforderung diese Fehlerbehandlung auch mit einem bestimmten Scope assoziert werden, in welchem nach Behandlung der Programmablauf fortgesetzt wird. Typischerweise wird bei Laufzeitfehlern der Programmablauf jedoch abgebrochen, wobei eine entsprechende SOAP Faultmessage an den Consumer zurückgegeben wird. Folgende Aufstellung zeigt einen Überblick über ein mögliches Fehlerbehandlungsszenario in einem allgemeinen Catch-Block auf Ebene Prozessdefinition in BPEL: FaultType received bindingFault remoteFault Business Fault (spezifisch) Übrige Fehler (‚catchAll‘) FaultAction Werden in einen im Service-Contract des entsprechenden Service definierten Business-Fault transformiert. Werden dem Aufrufer mittels Reply (oder alternativ Throw) Activity als SOAP-Fault retourniert. Werden über die Rethrow Activity an den Consumer zurückgegeben. Dies ermöglicht dem Aufrufer einen allfälligen Retry über eine Fault-Policy. Werden in einen im Service-Contract des entsprechenden Service definierten Business-Fault mittels Reply Activity als SOAP-Fault retourniert. Werden in einen im Service-Contract des entsptrechenden Service definierten Business-Fault transformiert und dem Aufrufer mittels Reply Activity als SOAP-Fault retourniert. Folgende Ausschnitte aus BPEL Code aus der faultHandler Section illustrieren dieses Fehlerbehandlungs-Szenario in einem Prozess-Service: Beispiel Fault Catch Block im BPEL Service Consumer: <faultHandlers> <catch faultName="bpelx:bindingFault" faultVariable="bindingFaultThrown" faultMessageType="bpelx:RuntimeFaultMessage"> <documentation>BPEL binding fault handler: return a ServiceFault with additional information of the current instance</documentation> <scope name="BindingFault" exitOnStandardFault="no"> <variables> <variable name="serviceFault" messageType="isf:ServiceFaultMsg"/> </variables> <sequence name="CreateServiceFault"> <assign name="createFault"> <copy> <from>$bindingFaultThrown.code</from> <to>$serviceFault.ServiceFault/isf:ErrorCode</to> </copy> <copy> <from>concat(ora:getCompositeName(), '.', ora:getProcessId())</from> <to>$serviceFault.ServiceFault/isf:ServiceId</to> </copy> <copy> <from>concat(ora:getCompositeInstanceId(), ':', ora:getInstanceId())</from> <to>$serviceFault.ServiceFault/isf:InstanceId</to> </copy> <copy> <from>$bindingFaultThrown.detail</from> <to>$serviceFault.ServiceFault/isf:Message</to> </copy> <copy> <from>$bindingFaultThrown.summary</from> <to>$serviceFault.ServiceFault/isf:OriginalFault</to> </copy> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 17 / 26 </assign> <reply name="ReplyServiceFault" faultName="ns1:ServiceFault" variable="serviceFault" partnerLink="myOperation_client" portType="ns1:MyOperationPortType" operation="myOperation"/> </sequence> </scope> </catch> <catch faultName="ns1:ValidationFault"> <reply name="replyValidationFault" faultName="ns1:ValidationFault" variable="validationFaultVariable" partnerLink="myOperation_client" portType="ns1:MyOperationPortType" operation="myOperation"/> </catch> <catch faultName="bpelx:remoteFault" faultVariable="remoteFaultThrown" faultMessageType="bpelx:RuntimeFaultMessage"> <sequence name="Sequence6"> <rethrow name="rethrowRemoteFault"/> </sequence> </catch> <catchAll> <bpelx:annotation> <bpelx:documentation>Catch all handler: create a ServiceFault containing the original Fault</bpelx:documentation> </bpelx:annotation> <scope name="HandleFault" exitOnStandardFault="no"> <variables> <variable name="serviceFault" messageType="isf:ServiceFaultMsg"/> </variables> <sequence name="CreateServiceFault"> <assign name="createFault"> <copy> <from>concat(ora:getCompositeName(), '.', ora:getProcessId())</from> <to>$serviceFault.ServiceFault/isf:ServiceId</to> </copy> <copy> <from>concat(ora:getCompositeInstanceId(), ':', ora:getInstanceId())</from> <to>$serviceFault.ServiceFault/isf:InstanceId</to> </copy> <copy> <from>ora:getFaultAsString()</from> <to>$serviceFault.ServiceFault/isf:Message</to> </copy> </assign> <reply name="ReplyServiceFault" faultName="ns1:ServiceFault" variable="serviceFault" partnerLink="myOperation_client" portType="ns1:MyOperationPortType" operation="myOperation"/> </sequence> </scope> </catchAll> </faultHandlers> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 18 / 26 3.2 Empfehlungen • Asynchrone BPEL Prozesse sollten immer mindestens einen Fehlerbehandlungsblock (catchAll) implementieren, welcher eine entsprechende Fehler-Response an den Consumer zurückliefert.Dadurch wird sichergestellt, dass der Aufrufer in jedem Fall eine Response erhält und Transaktions-Timeout’s verhindert. • Synchrone Prozesse sollten aufgetretene Laufzeitfehler möglichst alle in einem Fehlerblock behandeln und diese als typisierte SOAP Faults an den Consumer zurückgeben. Ausnahme können Services bilden, deren Consumer vollständig bekannt sind und sichergestellt ist, dass Fehler entsprechend beim Aufrufer behandelt werden. • Fehlerbehandlungsroutinen im Catch-Block sollten möglichst wenig Logik beinhalten. Eine Entkoppelung von komplexeren Fehlerbehandlungsfunktionen kann durch Message Queueing (EDN oder JMS) in generischen Fehlerhandlern erzielt werden. • Falls Retries in Services mit synchronem Message Exchange Patterns verwendet werden muss sichergestellt werden, dass diese die definierten oder allgemein angenommenen TimeoutWerte nicht überschreiten. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 19 / 26 4. Einsatz des FaultFault-Policy Frameworks SOA Suite erlaubt ein Fehlerhandling über zuweisbare und wiederverwendbare Fault Policies. In diesen Fault Policies kann generisch definiert werden, wie auf bestimmte Faults im zugeordnetem Composite reagiert werden soll, ohne dies bspw. im BPEL Flow selber implementieren zu müssen. Faults werden dabei aufgrund des Namespaces in der Fault Message identifiziert. BPEL: http://docs.oracle.com/cd/E28280_01/dev.1111/e10224/bp_faults.htm#SOASE9904 Mediator: http://docs.oracle.com/cd/E21764_01/integration.1111/e10224/med_faulthandling.htm JCA Adapter: http://docs.oracle.com/cd/E21764_01/integration.1111/e10231/life_cycle.htm#CIAIICJJ Besonders zu beachten gilt dabei, dass über Fault Policies nur Fehler aus aufgerufenen Services behandelt werden können (Fault Responses von Endpoint References) – bzw. Fehler aus Invoke Activities. Fehler die im BPEL Prozess selber mittels der Throw Activity geworfen werden, durchlaufen nicht die in der Faultpolicy definierten Verarbeitungsanweisungen. Das Fault Management Framework kann alle Fehler für eine Invoke Activity behandeln (Business oder Runtime). Eine Faultpolicy übersteuert alle Fault Handling Aktivitäten, die in Catch Activities in einem BPEL Prozess definiert worden sind. Die Faultpolicy kann jedoch über die rethrow Action entsprechend konfiguriert werden, sodass die Fehler an die Prozessinstanz zurückgegeben werden und darin dann die Anweisungen in den entsprechenden Catch Blöcken durchlaufen werden. Der generelle Ablauf bei der Auswertung beim Einsatz von Fault-Policies beim Auftreten eines Fehlers in einem BPEL-Prozess ist wie folgt: 1. Falls Faultpolicy vorhanden und entsprechender Fehler darin definiert: Ausführung der Regeln gemäss Faultpolicy. a. Falls rethrow Action in Faultpolicy definiert ist: Rückpropagierung des Fehlers an die Prozessinstanz und Ausführung der Anweisungen im Catch-Block des entsprechenden Prozesses. b. Andernfalls Ausführung der Actions der Faultpolicy (zum Beispiel Abort oder Human Intervention). 2. Andernfalls Ausführung der Anweisungen im Catch-Block des BPEL-Prozesses. Falls kein Catch-Block vorhanden ist, wird Default Faulthandler aufgerufen (rethrow). [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 20 / 26 4.1 Implementierung in BPEL Service Komponenten 4.1.1 Deklaration der zu verwendenden Fault Policy im Composite Die zu verwendende Faultpolicy muss in den Composite-Definitionen (composite.xml) der Applikation angegeben werden. Dies muss manuell direkt im Code geschehen. Für eine Gültigkeit über das gesamte composite muss die Deklaration zwischen dem service und component Element erfolgen ... </service> <property name="oracle.composite.faultPolicyFile">faultpolicy/sync_faultpolicy.xml</property> <property name="oracle.composite.faultBindingFile">faultpolicy/sync_faultbinding.xml</property> <component …..>. Wiederverwendbare Fault policies und/oder Bindings sollten in MDS verwaltet werden und im Composite entsprechend über oramds://apps referenziert werden. 4.1.1.1 Referenzen:: Spezifische Fault Policies auf Referenzen Falls für spezifische Referenzen (aufgerufene Services) in einem Composite ein unterschiedliches Fehlerbehandlungsverhalten durchgeführt werden soll, kann dies über die Angabe entsprechender Deklarationen im Faultbinding Dokument erreicht werden. Im Beispiel unten wird für die Referenz auf den ‚myReferenceService myReferenceService ‘ Service die Policy sync_referencefaultpolicy verwendet – für alle anderen Services die Definitionen aus sync_faultpolicy. <composite faultPolicy="sync_faultpolicy"/> <reference faultPolicy="sync_referencefaultpolicy"> <name>myReferenceService</name> </reference> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 21 / 26 4.2 Fehlerbehandlung im Fault Policy Framework 4.2.1 Aufbau Fehlercatch Wie beschrieben, findet die Definition der durchzuführenden Aktionen basierend auf dem FaultNamespaces und Fault-Namen statt. Jeder zu behandelnden Fehler kann dabei mit den entsprechenden Aktionen definiert werden. Beispiel Definition für Remote-Fault mit Retry Action in Fault-Policy: <faultName xmlns:bpelx=http://schemas.oracle.com/bpel/extension name="bpelx:remoteFault"> <condition> <action ref="ora-retry"/> </condition> </faultName> 4.2.1.1 Fault--Payload Conditions – Auswertung des Fault Teilweise kann es für die Fehlerbehandlung notwendig sein, eine Unterscheidung der Fehlerart nicht nur aufgrund des Fehlernamens vorzunehmen, sondern zusätzlich auch den Inhalt der Fehlermeldung auszuwerten. Im Beispiel unten wird falls der Messagepart code des erhaltenen SOAP-Fault den Wert 902 hat, eine benutzerdefinierte tvd-retry-1 Aktion durchgeführt – in allen anderen Fällen die Aktion default-rethrow-fault. Beispiel Definition mit Unterscheidung Fault Payload in Policy: <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault"> <condition> <test>$fault.code="902"</test> <action ref="tvd-retry-1"/> </condition> <condition> <action ref="default-rethrow-fault"/> </condition> </faultName> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 22 / 26 4.2.2 FehlerFehler-Actions Fehler-Actions beschreiben die durchzuführenden Aktionen und werden von den entsprechenden Fehler-Catches referenziert. Diese Fehler-Actions können wiederum verschachtelt implementiert werden. Im Beispiel unten führt die Action „tvd-retry-1“ drei Wiederholungen des Aufrufs durch – beim Scheitern dieser Aufrufe wird die Aktion default-rethrow-fault durchgeführt, welche wiederum den Fehler an die Prozess-Instanz zurück propagiert. Beispiel Definition Fehler-Actions: <Action id="tvd-retry-1"> <retry> <retryCount>3</retryCount> <retryInterval>1</retryInterval> <retryFailureAction ref="default-rethrow-fault"/> </retry> </Action> <Action id="default-rethrow-fault"> <rethrowFault/> </Action> 4.2.2.1 Wichtigste Fehleranweisungen im Fault Policy Framework Die in den Fehlerbehandlungsaktionen verwendeten Fehleranweisungen haben ein vordefiniertes Verhalten – sind aber im Falle von retry (siehe Beispiel oben) und javaAction weiter konfigurierbar. Folgende Aufstellung beschreibt als Überblick das Verhalten dieser Anweisungen: Fehleranweisung <abort/> <replayScope/> <rethrowFault/> <humanInterventio n/> <javaAction …/> <retry …/> Beschreibung Bricht die Prozessinstanz mit terminate Anweisung ab. Wiederholt die Ausführung des Scopes im BPEL Prozess indem der Fehler aufgetreten ist Propagiert den Fehler zurück in die Prozessinstanz, wo diese über Catch-Block behandelt werden kann. Hält die Prozessinstanz auf der fehlerauslösenden Aktion im BPEL Prozess an. Benutzer können die Instanz ab da über Fusion Middleware Control UI manuell mit der entsprechenden Anweisungen (z.B. abort oder retry) verwalten. Führt eine Java KJlasse aus, welche ein bestimmtes Interface (IFaultRecoveryJavaClass) implementiert haben muss. Wiederholt den Aufruf entsprechend den definierten Parametern [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 23 / 26 4.3 Besonderheiten im Retry bei JCA Adaptern JCA Adapter haben per Default bereits einen vordefinierten Retry Intervall. Falls in der Faultpolicy ebenfalls ein Retry – bspw. für einen BPEL RemoteFault – konfiguriert wird, kann es zu unerwünschten Nebeneffekten kommen. Einerseits kann es dadurch auch ohne Definition einer Faultpolicy zu Timeout Situationen kommen wenn die Anzahl Neuversuche den konfigurierten Wert für Transaction Timeout übersteigt. Anderseits können auch redundante Neuversuche durchgeführt werden, falls in der Faultpolicy ebenfalls Wiederholungsversuche konfiguriert sind. Das JCA Retry Property kann nicht auf den Wert 0 gesetzt werden. Um die Neuversuche des JCA Adapters zu deaktivieren müssen die Anweisungen in composite.xml deaktiviert werden. <reference name="myReferenceService" ui:wsdlLocation="MyReferenceService.wsdl"> <interface.wsdl …….)"/> <binding.jca config="MyReferenceService_db.jca"/> <!--<property name="jca.retry.maxInterval" type="xs:string" many="false" override="may">30</property> <property name="jca.retry.backoff" type="xs:int" many="false" override="may">1</property> <property name="jca.retry.interval" type="xs:int" many="false" override="may">1</property> <property name="jca.retry.count" type="xs:int" many="false" override="may">1</property>--> </reference> [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 24 / 26 4.4 Empfehlungen • Faultpolicies werden typischerweise für Services mit one-way oder asynchronem Interface eingesetzt. Dort können Fehlerbehandlungs-Aktionen wie Retry, Human-Intervention problemlos und ohne Berücksichtigung von time-out Einschränkungen eingesetzt werden. • Eine typische Faultpolicy für Bulk-Datenverarbeitung enthält eine definierte Anzahl automatisierter Neuversuche bei Nichterreichbarkeit des Endpoints mit einer HumanIntervention Action nach Scheitern dieser Retries. Damit kann die Prozessinstanz zu einem späteren Zeitpunkt, nach Behebung der Störung, ordnungsgemäss zu Ende verarbeitet werden. • Für Services mit synchronem Interface können Fault-Policies eingesetzt werden, um Retries für bekannte, sehr kurzfristige Störungen auf Kommunikationsebene durchzuführen. Es sollten dabei jedoch zwingend immer die entsprechenden time-out Einschränkungen berücksichtigt werden. Bei erfolglosem Retry kann die rethrow Action verwendet werden um den Fehler zur Behandlung im Service selber zurück zu propagieren. • Mit Ausnahme zur Behandlung von remoteFault ist ein retry in der Regel nicht sinnvoll. • Die zentrale Definition von generischen, umgebungsspezifischen Fault Policies im MDS ist sinnvoll. Damit können kritische Werte wie Anzahl Wiederverbindungsversuche domänenweit und spezifisch pro Umgebung verwaltet werden. [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 25 / 26 Referenzen [W3C-SOAP] [W3C-SOAP-F11] [W3C-SOAP-F12] [WSI-PROF1.2] [ORA-FMW-TR] Simple Object Access Protocol (SOAP 1.1), W3C Note, 08 May 2000 World Wide Web Consortium (W3C) SOAP HTTP Responses http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383529 Simple Object Access Protocol (SOAP 1.1), W3C Note, 08 May 2000 World Wide Web Consortium (W3C) SOAP Fault Codes http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383510 SOAP Version 1.2 Part 1: Messaging Framework, April 2007 World Wide Web Consortium (W3C) SOAP Fault Codes http://www.w3.org/TR/2007/REC-soap12-part1-20070427/#faultcodes Basic Profile Version 1.2, November 2010 Webservice Interoperability Organization http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383529 Fusion Middleware Developer's Guide for Oracle SOA Suite Transaction and Fault Propagation Semantics in BPEL Processes Oracle Corp. http://docs.oracle.com/cd/E36909_01/dev.1111/e10224/soa_transactions. htm [email protected] . www.trivadis.com . Info-Tel. 0800 87 482 347 . Datum 02.07.2015 . Seite 26 / 26
© Copyright 2024 ExpyDoc