Empfangsknoten in Java erstellen

Es wird ein Empfangsknoten verwendet, um eine Nachricht in einem Nachrichtenfluss zu empfangen, normalerweise von einer Quelle, die nicht von den integrierten Empfangsknoten unterstützt wird.

Vorbereitungen

Ein benutzerdefinierter Java-Knoten wird als Datei mit der Erweiterung .jar verteilt.

Neues Java-Projekt erstellen

Vor der Erstellung von Java-Knoten in der Workbench müssen Sie ein neues Java-Projekt erstellen:

  1. Wechseln Sie zur Java-Perspektive.
  2. Klicken Sie Datei > Neu > Projekt. Wählen Sie im linken Menü Java aus, und wählen Sie anschließend aus dem rechten Menü Java Project (Java-Projekt) aus.
  3. Benennen Sie das Projekt. Die Anzeige Java Settings (Java-Einstellungen) wird angezeigt.
  4. Wählen Sie die Registerkarte Libraries (Bibliotheken) aus, und klicken Sie auf Add External JARs (Externe JARs hinzufügen).
  5. Wählen Sie Installationsverzeichnis\classes\jplugin2.jar aus.
  6. Folgen Sie den Eingabeaufforderungen in den anderen Registerkarten, um weitere Build-Einstellungen zu definieren.
  7. Klicken Sie auf Fertigstellen.
Sie können jetzt die Quelle für Ihren Java-Knoten in diesem Projekt entwickeln.

Klasse des Empfangsknotens deklarieren

Jede Klasse, durch die MbInputNodeInterface implementiert wird und im LIL-Pfad des Brokers enthalten ist, wird mit dem Broker als Empfangsknoten registriert. Bei der Implementierung von MbInputNodeInterface muss auch eine run-Methode für diese Klasse implementiert werden. Die Methode run zeigt den Start des Nachrichtenflusses an, enthält die Daten, in der die Nachricht erfasst wird, und gibt die Daten an den Fluss weiter. Der Broker ruft die Methode run auf, wenn Threads entsprechend dem angegebenen Threading-Modell verfügbar sind.

Wenn Sie beispielsweise die Klasse des Empfangsknotens deklarieren möchten, gehen Sie folgendermaßen vor:

package com.ibm.jplugins;

import com.ibm.broker.plugin.*;

public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
...

Führen Sie die folgenden Schritte aus, um diese Aktion in der Workbench vollständig durchzuführen:

  1. Klicken Sie auf Datei > Neu > Klasse.
  2. Legen Sie in den Paket- und Klassennamenfeldern die entsprechenden Werte fest.
  3. Löschen Sie den Text im Textfeld Superclass (Superklasse), und klicken Sie auf die Schaltfläche Durchsuchen.
  4. Wählen Sie MbInputNode aus.
  5. Klicken Sie neben dem Textfeld 'Interface' (Schnittstelle) auf die Schaltfläche Hinzufügen, und wählen Sie MbInputNodeInterface aus.
  6. Klicken Sie auf Fertigstellen.

Knotenkonstruktor definieren

Wenn eine Instanz des Knotens erstellt wird, wird der Konstruktor der Knotenklasse des Benutzers aufgerufen. In dieser Klasse können Sie die Knotenterminals erstellen und Standardwerte für die Attribute initialisieren.

Einem Empfangsknoten sind eine Reihe von Ausgabeterminals zugeordnet, er verfügt jedoch normalerweise nicht über Eingabeterminals. Verwenden Sie die Methode createOutputTerminal, um einem Knoten Ausgabeterminals hinzuzufügen, wenn eine Instanz des Knotens erstellt wird. Im Folgenden finden Sie ein Beispiel für die Erstellung eines Knotens mit drei Ausgabeterminals:

public BasicInputNode() throws MbException
{
	createOutputTerminal ("out");
	createOutputTerminal ("failure");
	createOutputTerminal ("catch");
	setAttribute ("firstParserClassName","myParser");
	attributeVariable = "none"; 
}

Externe Daten in einem Puffer empfangen

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. Wenn Sie beispielsweise die Eingabe aus einer Datei lesen möchten, gehen Sie wie folgt vor:

  1. Erstellen Sie einen Eingabedatenstrom, um die Daten aus der Datei zu lesen:
    FileInputStream inputStream = new FileInputStream("myfile.msg");
  2. Erstellen Sie eine Bytefeldgruppe, die dieselbe Größe wie die Eingabedatei hat:
    byte[] buffer = new byte[inputStream.available()];
  3. Lesen Sie die Daten aus der Datei in die Bytefeldgruppe ein:
    inputStream.read(buffer);
  4. Schließen Sie den Eingabedatenstrom:
    inputStream.close();
  5. Erstellen Sie eine Nachricht, die in die Warteschlange eingereiht werden soll:
    MbMessage msg = createMessage(buffer);
  6. Erstellen Sie ein neues Nachrichten-Assembly, das diese Nachricht enthalten soll:
    msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE);
    MbMessageAssembly newAssembly =
         new MbMessageAssembly( assembly, msg );

Nachricht weitergeben

Wenn Sie ein Nachrichten-Assembly erstellt haben, können Sie dies an einen der Terminals des Knotens weitergeben.

Geben Sie beispielsweise Folgendes ein, um das Nachrichten-Assembly an das Ausgangsterminal out weiterzugeben:
MbOutputTerminal out = getOutputTerminal("out");
out.propagate(newAssembly);
Gehen Sie zum Löschen der Nachricht folgendermaßen vor:
msg.clearMessage();

Rufen Sie zum Löschen des Speichers, der der Nachrichtenbaumstruktur zugeordnet ist, die clearMessage()-Funktion innerhalb des letztenTry/Catch-Blocks auf.

Threading und Transaktionalität steuern

Die Broker-Infrastruktur verarbeitet Transaktionen wie das Festschreiben einer WebSphere MQ- oder Datenbank-Arbeitseinheit, wenn die Nachrichtenverarbeitung abgeschlossen ist. Allerdings befinden sich Ressourcen, die in einem benutzerdefinierten Knoten geändert wurden, nicht zwangsläufig unter transaktionsorientierter Steuerung des Brokers.

Jeder Thread eines Nachrichtenflusses wird aus einem Thread-Pool zugewiesen, der für jeden Nachrichtenfluss verwaltet wird, und beginnt 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. Die Infrastruktur des Brokers fängt alle nicht behandelten Ausnahmebedingungen ab und setzt die Transaktion zurück.

Das Verhalten von Transaktionen und Threads wird mithilfe eines entsprechenden Rückgabewerts bestimmt:

MbInputNode.SUCCESS_CONTINUE
Die Transaktion wird festgeschrieben, und der Broker ruft die Methode run erneut mit demselben Thread auf.
MbInputNode.SUCCESS_RETURN
Die Transaktion wird festgeschrieben, und der Thread wird an den Thread-Pool zurückgegeben, wobei vorausgesetzt wird, dass dies nicht der einzige Thread für diesen Nachrichtenfluss ist.
MbInputNode.FAILURE_CONTINUE
Die Transaktion wird zurückgesetzt, und der Broker ruft die Methode run erneut mit demselben Thread auf.
MbInputNode.FAILURE_RETURN
Die Transaktion wird zurückgesetzt, und der Thread wird in den Thread-Pool zurückgegeben. Dabei wird vorausgesetzt, dass es sich nicht um den einzigen Thread für diesen Nachrichtenfluss handelt.
MbInputNode.TIMEOUT
Die Methode run darf nicht unbegrenzt blockieren, während sie auf Eingabedaten wartet. Während der Nachrichtenfluss durch Benutzercode blockiert wird, können Sie den Broker nicht beenden oder neu konfigurieren. Durch die Methode run muss die Steuerung regelmäßig an den Broker übergeben werden. Dabei wird die Steuerung von der Methode run zurückgegeben. Wenn nach einer bestimmten Zeit (z. B. 5 Sekunden) keine Eingabedaten empfangen wurden, sollte die Rückgabe der Methode mit dem Rückkehrcode TIMEOUT erfolgen. Vorausgesetzt, dass der Broker nicht neu konfiguriert oder beendet werden muss, wird die Methode run des Empfangsknotens sofort aufgerufen.
Um Multithread-Nachrichtenflüsse zu erstellen, rufen Sie die Methode dispatchThread auf, nachdem eine Nachricht erstellt wurde, aber bevor die Nachricht an ein Ausgabeterminal weitergegeben wird. Durch diese Aktion wird gewährleistet, dass nur ein Thread auf Daten wartet, während andere Threads die Nachricht verarbeiten. Neue Threads werden bis zu einem Maximalwert aus dem Thread-Pool abgerufen. Dieser Wert wird durch das Attribut Zusätzliche Instanzen des Nachrichtenflusses angegeben. Beispiel:
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;
}

Knotennamen deklarieren

Sie müssen den Namen des Knotens deklarieren, damit dieser von der Workbench verwendet und identifiziert werden kann. Alle Knotennamen müssen die Endung "Node" haben. Deklarieren Sie den Namen mit der folgenden Methode:

public static String getNodeName()
{
   return "BasicInputNode";
}
Wenn diese Methode nicht deklariert wird, erstellt das Java-API-Framework einen Standardknotennamen gemäß den folgenden Regeln:
  • Der Klassenname wird an den Paketnamen angehängt.
  • Die Punkte werden entfernt, und der erste Buchstabe von jedem Teil des Paket- und Klassenamens wird in Großbuchstaben gesetzt.
Beispiel: Standardmäßig wird folgender Klasse der Knotenname "ComIbmPluginsamplesBasicInputNode" zugewiesen:
package com.ibm.pluginsamples;
public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
   ...

Attribute deklarieren

Deklarieren Sie Knotenwerte auf die gleiche Weise die Eigenschaften von Java-Beans. Die Methoden Get und Set müssen für die Attribute geschrieben werden; und das API-Framework schließt aus den Regeln für die Java-Bean-Introspektion auf die Attributnamen. Sie können beispielsweise die folgenden zwei Methoden deklarieren:

private String attributeVariable;

public String getFirstAttribute()
{
  return attributeVariable;
}

publc void setFirstAttribute(String value)
{
  attributeVariable = value;
}

Der Broker schließt daraus, dass in diesem Knoten ein Attribut mit der Bezeichnung 'firstAttribute' enthalten ist. Dieser Name wird von den Namen der Methoden zum Abrufen oder Festlegen abgeleitet, und nicht von den Variablennamen von Mitgliedern interner Klassen. Attribute können nur als Zeichenfolge angezeigt werden. Deshalb müssen Sie numerische Typen in den get- oder set-Methoden in bzw. aus Zeichenfolgen konvertieren. In der folgenden Methode wird beispielsweise ein Attribut mit der Bezeichnung 'timeInSeconds' definiert:

int seconds;

public String getTimeInSeconds()
{
  return Integer.toString(seconds);
}

public void setTimeInSeconds(String value)
{
  seconds = Integer.parseInt(value);
}

Knotenfunktion implementieren

Wie bereits beschrieben, wird die Methode run vom Broker zur Erstellung der Eingabenachricht aufgerufen. Durch diese Methode wird die erforderliche Verarbeitungsfunktion für den Empfangsknoten bereitgestellt.

Standardmäßige Attribute des Nachrichtenparsers überschreiben (optional)

Eine Empfangsknotenimplementierung bestimmt normalerweise, welcher Nachrichten-Parser eine Eingabenachricht anfangs analysiert. Beispiel: Der integrierte MQInput-Knoten gibt an, dass ein MQMD-Parser für die Syntaxanalyse des MQMD-Headers erforderlich ist. Ein benutzerdefinierter Empfangsknoten kann einen geeigneten Header oder Nachrichten-Parser und den Modus, in dem die Syntaxanalyse gesteuert wird, mithilfe der folgenden Standardattribute auswählen, die enthalten sind und die Sie überschreiben können:

rootParserClassName
Definiert den Namen des Root-Parsers, durch den die vom benutzerdefinierten Empfangsknoten unterstützten Nachrichtenformate syntaktisch analysiert werden. Die Standardeinstellung ist der bereitgestellte Root-Parser GenericRoot, durch den der Broker die verschiedenen Parser zuordnet und verkettet. Dieser Attributwert wird von einem Knoten normalerweise nicht geändert.
firstParserClassName
Definiert den Namen des ersten Parsers in einer Parser-Kette, durch die die Syntaxanalyse des Bitstroms durchgeführt wird. Die Standardeinstellung ist XML.
messageDomainProperty
Optionales Attribut, durch das der Name des Nachrichtenparsers definiert wird, der für die Syntaxanalyse der Eingabenachricht erforderlich ist. Die unterstützten Werte sind die gleichen wie diejenigen, die vom MQInput-Knoten unterstützt werden.
messageSetProperty
Optionales Attribut, das die Nachrichtengruppen-ID oder den Nachrichtengruppennamen im Feld Nachrichtengruppe definiert, falls der MRM-Parser durch das Attribut messageDomainProperty angegeben wurde.
messageTypeProperty
Optionales Attribut, das die Nachrichten-ID im Feld Nachrichtentyp definiert, falls der MRM-Parser durch das Attribut messageDomainProperty angegeben wurde.
messageFormatProperty
Optionales Attribut, das das Nachrichtenformat im Feld Nachrichtenformat definiert, falls der MRM-Parser durch das Attribut messageDomainProperty angegeben wurde.

Knoteninstanz löschen

Eine Knoteninstanz wird durch folgende Aktionen gelöscht:
  • Sie beenden den Broker.
  • Entfernen des Knotens oder den Nachrichtenflusses, in dem der Knoten enthalten ist, und erneutes Einsetzen der Konfiguration.
Wenn der Knoten gelöscht wird, kann er Bereinigungsvorgänge wie beispielsweise das Schließen von Sockets vornehmen, wenn er die optionale Methode onDelete implementiert. Falls diese Methode vorhanden ist, wird sie vom Broker kurz vor dem Löschen des Knotens aufgerufen.

Implementieren Sie die Methode onDelete wie folgt:

public void onDelete()
{
  // perform node cleanup if necessary
}
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Feedback

Copyright IBM Corporation 1999, 2009Copyright IBM Corporation 1999, 2009.
Letzte Aktualisierung : 2009-02-17 15:30:01

as09950_