Vorbereitungen:
Ein Empfangsknoten kann wie jedes andere Java-Programm Daten aus allen Arten von externen Quellen, z. B. einem Dateisystem, einer Warteschlange oder einer Datenbank, empfangen, solange die Ausgabe des Knotens im richtigen Format vorliegt.
Sie müssen einen Eingabepuffer (oder einen Bitstrom) bereithalten, in dem Eingabedaten enthalten sind, und ihn einem Nachrichtenobjekt zuordnen. Dann erstellen Sie mit der Methode createMessage der Klasse MbInputNode eine Nachricht aus einer Bytefeldgruppe, und anschließend generieren Sie aus dieser Nachricht ein gültiges Nachrichten-Assembly. Weitere Informationen zu diesen Methoden finden Sie im Abschnitt Java-API. Wenn Sie beispielsweise die Eingabe aus einer Datei lesen möchten, gehen Sie wie folgt vor:
Wenn Sie ein Nachrichten-Assembly erstellt haben, können Sie dies an einen der Terminals des Knotens weitergeben.
MbOutputTerminal out = getOutputTerminal("out"); out.propagate(newAssembly);
Die Broker-Infrastruktur verarbeitet Transaktionen wie das Festschreiben einer WebSphere MQ- oder Datenbank-Arbeitseinheit, wenn die Nachrichtenverarbeitung abgeschlossen ist. Wenn jedoch ein benutzerdefinierter Knoten verwendet wird, können Ressourcenaktualisierungen nicht automatisch vom Broker festgeschrieben werden.
Jeder Nachrichtenfluss-Thread wird aus einem Thread-Pool zugeordnet, der für jeden Nachrichtenfluss verwaltet wird, und startet die Ausführung in der Methode run.
Der benutzerdefinierte Knoten verwendet Rückgabewerte, um anzugeben, ob eine Transaktion erfolgreich war, um zu steuern, ob Transaktionen festgeschrieben oder zurückgesetzt werden, und um zu steuern, wann der Thread an den Pool zurückgegeben wird. Alle nicht verarbeiteten Ausnahmebedingungen werden von der Broker-Infrastruktur abgefangen, und die Transaktion wird zurückgesetzt.
Sie bestimmen das Verhalten von Transaktionen und Threads, indem Sie den entsprechenden Rückgabewert verwenden:
public int run( MbMessageAssembly assembly ) throws MbException { byte[] data = getDataWithTimeout(); // user supplied method // returns null if timeout if( data == null ) return TIMEOUT; MbMessage msg = createMessage( data ); msg.finalizeMessage( MbMessage.FINALIZE_VALIDATE ); MbMessageAssembly newAssembly = new MbMessageAssembly( assembly, msg ); dispatchThread(); getOutputTerminal( "out" ).propagate( newAssembly ); return SUCCESS_RETURN; }
Mit Hilfe der Klasse 'mbException' fangen Sie Ausnahmebedingungen ab und greifen darauf zu. Die Klasse 'mbException' gibt eine Feldgruppe von Ausnahmeobjekten zurück, die die untergeordneten Elemente einer Ausnahmebedingung in der Ausnahmeliste des Brokers darstellen. Jedes zurückgegebene Element gibt seinen Ausnahmetyp an. Wenn eine Ausnahmebedingung keine untergeordneten Elemente hat, wird eine leere Feldgruppe zurückgegeben. Im folgenden Codebeispiel ist ein Beispiel für die Syntax der Klasse 'MbException' dargestellt.
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { try { // plug-in functionality } catch(MbException ex) { traverse(ex, 0); throw ex; // if re-throwing, it must be the original exception that was caught } } void traverse(MbException ex, int level) { if(ex != null) { // Do whatever action here System.out.println("Level: " + level); System.out.println(ex.toString()); System.out.println("traceText: " + ex.getTraceText()); // traverse the hierarchy MbException e[] = ex.getNestedExceptions(); int size = e.length; for(int i = 0; i < size; i++) { traverse(e[i], level + 1); } } }
Weitere Informationen zur Verwendung der Klasse 'mbException' finden Sie in der Javadoc.
Sie können einen benutzerdefinierten Nachrichtenverarbeitungs- oder Sendeknoten so entwickeln, dass er auf alle aktuellen Ausnahmebedingungen zugreifen kann. Sie können beispielsweise die Klasse 'MbSQLStatement' verwenden, um Datenbankausnahmebedingungen abzufangen. Diese Klasse legt den Wert des Attributs 'throwExceptionOnDatabaseError' fest, das das Verhalten des Brokers bestimmt, wenn ein Datenbankfehler auftritt. Wenn dieser Wert auf 'True' festgelegt wird, kann eine Ausnahmebedingung abgefangen und von der benutzerdefinierten Erweiterung bearbeitet werden.
Im folgenden Codebeispiel ist ein Beispiel für die Verwendung der Klasse 'MbSQLStatement' dargestellt.
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { MbMessage newMsg = new MbMessage(assembly.getMessage()); MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg); String table = assembly.getMessage().getRootElement().getLastChild().getFirstChild().getName(); MbSQLStatement state = createSQLStatement( "dbName", "SET OutputRoot.XML.integer[] = PASSTHRU('SELECT * FROM " + table + "');" ); state.setThrowExceptionOnDatabaseError(false); state.setTreatWarningsAsErrors(true); state.select( assembly, newAssembly ); int sqlCode = state.getSQLCode(); if(sqlCode != 0) { // Do error handling here System.out.println("sqlCode = " + sqlCode); System.out.println("sqlNativeError = " + state.getSQLNativeError()); System.out.println("sqlState = " + state.getSQLState()); System.out.println("sqlErrorText = " + state.getSQLErrorText()); } getOutputTerminal("out").propagate(assembly); }