Prima di iniziare
Viene visualizzato il pannello relativo alle impostazioni Java.
Qualsiasi classe che implementa MbInputNodeInterface ed è contenuta nel percorso della LIL del broker viene registrata con il broker come un nodo di input. Quando MbInputNodeInterface viene implementato, è necessario implementare anche un metodo run per tale classe. Il metodo run rappresenta l'avvio del flusso di messaggi, contiene i dati che formulano il messaggio e lo trasmettono nel flusso. Il broker richiama il metodo run quando i thread divengono disponibili in conformità al modello di thread specificato.
Ad esempio, per dichiarare la classe del nodo di input:
package com.ibm.jplugins; import com.ibm.broker.plugin.*; public class BasicInputNode extends MbInputNode implements MbInputNodeInterface { ...
Quando viene creata l'istanza del nodo, viene richiamato il costruttore della classe del nodo dell'utente. Ovvero dove vengono creati i terminali del nodo e inizializzato qualsiasi valore predefinito per gli attributi.
Ad un nodo di input sono associati una serie di terminali di output, ma tale nodo non dispone solitamente di alcun terminale di input. Utilizzare il metodo createOutputTerminal per aggiungere terminali di output ad un nodo quando viene creata l'istanza di tale nodo. Ad esempio, per creare un nodo con tre terminali di output:
public BasicInputNode() throws MbException { createOutputTerminal ("out"); createOutputTerminal ("failure"); createOutputTerminal ("catch"); setAttribute ("firstParserClassName","myParser"); attributeVariable = "none"; }
Un nodo di input può ricevere dati da qualsiasi tipo di origine esterna, come un file system, una coda o un database, nello stesso modo di qualsiasi altro programma Java, purché l'output proveniente dal nodo sia nel formato corretto.
E' possibile fornire un buffer di input (o flusso di bit) per contenere dati di input e associarlo ad un oggetto messaggio. Un messaggio viene creato da un array di byte utilizzando il metodo createMessage della classe MbInputNode e quindi da tale messaggio viene creato un assemblaggio di messaggi valido. Per informazioni dettagliate su questi metodi, fare riferimento a API Java. Ad esempio, per leggere l'input da un file:
Una volta creato un assemblaggio di messaggi, è possibile quindi distribuirlo ad uno dei terminali del nodo.
MbOutputTerminal out = getOutputTerminal("out"); out.propagate(newAssembly);
msg.clearMessage();
Per svuotare la memoria assegnata all'albero del messaggio, richiamare la funzione clearMessage() all'interno del blocco finale try/catch.
L'infrastruttura del broker gestisce il risultato delle transazioni come controllare il commit di unità di lavoro di database o WebSphere MQ una volta completata l'elaborazione del messaggio. In ogni caso, le risorse modificate dall'interno di un nodo definito dall'utente non finiranno necessariamente sotto il controllo transazionale del broker.
Ogni thread del flusso di messaggi è assegnato da un pool di thread mantenuto per ciascun flusso di messaggi e la cui esecuzione viene avviata nel metodo run.
Il nodo definito dall'utente utilizza valori di restituzione per indicare se una transazione ha avuto esito positivo, per controllare se è stato eseguito il commit o il rollback delle transazioni e per controllare quando il thread viene restituito al pool. Eventuali eccezioni non gestite sono rilevate dall'infrastruttura del broker e viene eseguito il rollback della transazione.
Il funzionamento delle transazioni e dei thread viene determinato utilizzando un appropriato valore di restituzione tra quelli riportati di seguito:
public int run( MbMessageAssembly assembly ) throws MbException { byte[] data = getDataWithTimeout(); // metodo fornito dall'utente // restituisce null in caso di 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; }
E' necessario dichiarare il nome del nodo in quanto verrà identificato dal workbench. Tutti i nomi di nodo devono terminare con "Node". Si dichiara il nome utilizzando il seguente metodo:
public static String getNodeName() { return "BasicInputNode"; }
package com.ibm.pluginsamples; public class BasicInputNode extends MbInputNode implements MbInputNodeInterface { ...
Gli attributi del nodo vengono dichiarati nello stesso modo delle proprietà di Java Bean. E' sotto la propria responsabilità la scrittura di metodi per ottenere e impostare gli attributi e il framework dell'API deduce i nomi di attributo utilizzando le regole di introspezione Java Bean. Ad esempio, se si dichiarano i due seguenti metodi:
private String attributeVariable; public String getFirstAttribute() { return attributeVariable; } publc void setFirstAttribute(String value) { attributeVariable = value; }
Il broker deduce che questo nodo ha un attributo denominato firstAttribute. Tale nome viene ricavato dai nomi dei metodi "get" o "set" e non dai nomi di variabile dei membri di classe interna. Gli attributi possono essere esposti solo come stringhe, è quindi necessario convertire qualsiasi tipo numerico relativo alle stringhe in tali metodi. Ad esempio, il metodo riportato di seguito definisce un attributo denominato timeInSeconds:
int seconds; public String getTimeInSeconds() { return Integer.toString(seconds); } public void setTimeInSeconds(String value) { seconds = Integer.parseInt(value); }
Come già descritto, il metodo run viene richiamato dal broker per creare il messaggio di input. Questo metodo deve fornire tutta la funzione di elaborazione per il nodo di input.
L'implementazione di un nodo di input determina normalmente il programma di analisi che inizialmente analizza un messaggio di input. Ad esempio, il nodo MQInput primitivo richiede che per analizzare l'intestazione MQMD venga utilizzato un programma di analisi MQMD. Un nodo di input definito dall'utente può selezionare un programma di analisi del messaggio o un'intestazione appropriata, e la modalità secondo cui viene gestita l'analisi, utilizzando i seguenti attributi inclusi come impostazione predefinita, che è comunque possibile sovrascrivere:
Il metodo onDelete viene implementato nel modo seguente:
public void onDelete() { // eseguire cleanup del nodo se necessario }