Creazione di un nodo di input in Java

Prima di iniziare

Creazione di un nuovo progetto Java

È possibile creare nodi Java da workbench. A tal fine, è necessario creare un nuovo progetto Java, come riportato di seguito:
  1. Passare alla vista Java.
  2. Fare clic su File > Nuovo > Progetto. Selezionare Java dal menu a sinistra quindi selezionare Progetto Java dal menu a destra.
  3. Assegnare un nome al progetto.

    Viene visualizzato il pannello relativo alle impostazioni Java.

  4. Selezionare la scheda relativa alle librerie e fare clic su Aggiungi JAR esterne.
  5. Selezionare install_dir\classes\jplugin2.jar.
  6. Seguire i messaggi di richiesta sulle altre schede per definire qualsiasi altra impostazione di creazione.
  7. Fare clic su Fine.
E' possibile quindi sviluppare l'origine per il nodo Java all'interno del progetto.

Dichiarazione della classe del nodo di input

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
{
...
E' possibile procedere in tal modo nel workbench effettuando quanto riportato di seguito:
  1. Fare clic su File > Nuovo > Classe.
  2. Impostare nei campi relativi al nome di classe e al pacchetto i valori appropriati.
  3. Eliminare il testo nel campo Superclasse e fare clic sul pulsante Sfoglia.
  4. Selezionare MbInputNode.
  5. Fare clic sul pulsante Aggiungi in prossimità del campo di testo relativo alle interfacce e selezionare MbInputNodeInterface.
  6. Fare clic su Fine.

Definizione del costruttore del nodo

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"; 
}

Ricezione di dati esterni in un buffer

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:

  1. Creare un flusso di input da leggere dal file:
    FileInputStream inputStream = new FileInputStream("myfile.msg");
  2. Creare un array di byte della dimensione del file di input:
    byte[] buffer = new byte[inputStream.available()];
  3. Leggere dal file nell'array di byte:
    inputStream.read(buffer);
  4. Chiudere il flusso di input:
    inputStream.close();
  5. Creare un messaggio da inserire nella coda:
    MbMessage msg = createMessage(buffer);
  6. Creare un nuovo assemblaggio di messaggi per contenere questo messaggio:
    msg.finalizeMessage(MbMessage.FINALIZE_VALIDATE);
    MbMessageAssembly newAssembly =
         new MbMessageAssembly( assembly, msg );

Distribuzione del messaggio

Una volta creato un assemblaggio di messaggi, è possibile quindi distribuirlo ad uno dei terminali del nodo.

Ad esempio, per distribuire l'assemblaggio di messaggi al terminale "out":
MbOutputTerminal out = getOutputTerminal("out");
out.propagate(newAssembly);
Per eliminare il messaggio:
msg.clearMessage();

Per svuotare la memoria assegnata all'albero del messaggio, richiamare la funzione clearMessage() all'interno del blocco finale try/catch.

Gestione del thread e possibilità di transazioni

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:

MbInputNode.SUCCESS_CONTINUE
Viene eseguito il commit della transazione e il broker richiama nuovamente il metodo run utilizzando lo stesso thread.
MbInputNode.SUCCESS_RETURN
Viene eseguito il commit della transazione e il thread viene restituito al relativo pool, assumendo che non è l'unico thread per questo flusso di messaggi.
MbInputNode.FAILURE_CONTINUE
Viene eseguito il rollback della transazione e il broker richiama nuovamente il metodo run utilizzando lo stesso thread.
MbInputNode.FAILURE_RETURN
Viene eseguito il rollback della transazione e il thread viene restituito al relativo pool, assumendo che non è l'unico thread per questo flusso di messaggi.
MbInputNode.TIMEOUT
Il metodo run non deve eseguire il blocco a tempo indeterminato mentre è in attesa dell'arrivo di dati di input. Quando il flusso è bloccato dal codice utente, non è possibile eseguire la chiusura o la riconfigurazione del broker. Il metodo run deve fornire il controllo al broker periodicamente uscendo dal metodo stesso. Se dopo un certo periodo di tempo (ad esempio, 5 secondi) non sono stati ricevuti dati di input, il metodo restituisce il codice di ritorno TIMEOUT. Assumendo che il broker non debba eseguire la riconfigurazione o la chiusura, il metodo run del nodo di input viene nuovamente richiamato.
Per creare flussi di messaggi a più thread, viene richiamato il metodo dispatchThread dopo che è stato creato un messaggio, ma prima che il messaggio venga inviato ad un terminale di output. In questo modo si è certi che un unico thread sia in attesa dei dati mentre altri thread stanno elaborando il messaggio. E' possibile ottenere nuovi thread dal relativo pool fino al limite massimo specificato dall'attributo additionalInstances del flusso di messaggi. Ad esempio:
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;
}

Dichiarazione del nome del nodo

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";
}
Se questo metodo non è dichiarato, il framework dell'API Java crea un nome di nodo predefinito utilizzando le seguenti regole:
  • Il nome di classe viene apposto al nome del pacchetto.
  • I punti vengono eliminati e la prima lettera di ciascuna parte del nome di classe e pacchetto viene posta in maiuscolo.
Ad esempio, per impostazione predefinita, alla seguente classe viene assegnato il nome di nodo "ComIbmPluginsamplesBasicInputNode":
package com.ibm.pluginsamples;
public class BasicInputNode extends MbInputNode implements MbInputNodeInterface
{
   ...

Dichiarazione degli attributi

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);
}

Implementazione della funzionalità del nodo

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.

Sovrascrittura degli attributi di programmi di analisi di messaggi predefiniti (facoltativo)

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:

rootParserClassName
Definisce il nome del programma di analisi root che analizza i formati del messaggio supportati da nodo di input definito dall'utente. Il valore predefinito è GenericRoot, un programma di analisi root fornito che fa sì che il broker assegni e concateni i programmi di analisi. E' improbabile che un nodo abbia necessità di modificare questo valore di attributo.
firstParserClassName
Definisce il nome del primo programma di analisi, in quella che potrebbe essere una catena di programmi di analisi responsabili dell'analisi del flusso di bit. Il valore predefinito è XML.
messageDomainProperty
Un attributo facoltativo che definisce il nome del programma di analisi del messaggio richiesto per analizzare il messaggio di input. I valori previsti sono gli stessi previsti dal nodo MQInput. Fare riferimento a Nodo MQInput per ulteriori informazioni sul nodo MQInput.
messageSetProperty
Un attributo facoltativo che definisce l'identificativo della serie di messaggi o il nome della serie di messaggi nel campo Serie di messaggi, solo se il programma di analisi MRM è stato specificato dall'attributo messageDomainProperty.
messageTypeProperty
Un attributo facoltativo che definisce l'identificativo del messaggio nel campoTipo di messaggio, solo se il programma di analisi MRM è stato specificato dall'attributo messageDomainProperty.
messageFormatProperty
Un attributo facoltativo che definisce il formato del messaggio nel campo Formato del messaggio, solo se il programma di analisi MRM è stato specificato dall'attributo messageDomainProperty.

Eliminazione di un'istanza del nodo

Un'istanza del nodo viene eliminata quando:
  • Il broker viene chiuso.
  • Viene eliminato il nodo o il flusso di messaggi contenente il nodo e si ridistribuisce la configurazione.
Durante l'eliminazione del nodo, questo potrebbe voler essere informato in modo da poter eseguire eventuali operazioni di cleanup, come la chiusura dei socket. Se il nodo implementa il metodo onDelete facoltativo, questo viene richiamato dal broker prima che il nodo venga eliminato.

Il metodo onDelete viene implementato nel modo seguente:

public void onDelete()
{
  // eseguire cleanup del nodo se necessario
}
Informazioni correlate
API Java
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
as09950_