Estensione delle capacità di un nodo di output o di elaborazione dei messaggi in C

Prima di iniziare

Assicurarsi di aver letto e appreso il seguente argomento:

Accesso ai dati del messaggio

In molti casi, il nodo definito dall'utente ha necessità di accedere al contenuto del messaggio ricevuto sul relativo terminale di input. Il messaggio è rappresentato come una struttura ad albero degli elementi di sintassi. Gruppi di funzioni di utilità vengono forniti per la gestione dei messaggi, l'accesso al buffer di messaggi, la navigazione e l'acceso all'elemento di sintassi. Per informazioni dettagliate sulle funzioni di utilità, fare riferimento a Funzioni di utilità del nodo in C.

I tipi di query che probabilmente verranno eseguiti includono:
  • Reperimento dell'elemento root dell'oggetto messaggio richiesto
  • Accesso alla rappresentazione flusso di bit di una struttura al albero dell'elemento
  • Esecuzione della navigazione o di query nella struttura ad albero richiedendo il child o gli elementi associati per nome
  • Richiamo del tipo di elemento
  • Richiamo del valore dell'elemento

Ad esempio per eseguire la query del nome e del tipo del primo child del contenuto:

void cniEvaluate( ...               
){                                    
  ...
/* Naviga sull'elemento di destinazione */ 
  rootElement = cniRootElement(&rc, message);
  bodyElement = cniLastChild(&rc, rootElement);
  bodyFirstChild = cniFirstChild(&rc, bodyElement);

/* Esegue la query del nome del valore dell'elemento di destinazione */
  cniElementName(&rc, bodyFirstChild, (CciChar*)&elementname, sizeof(elementName)); 
  bytes = cniElementCharacterValue(
		&rc, bodyfirstChild, (CciChar*)&eValue, sizeof(eValue));
  ...    
}

Per accedere alla rappresentazione del flusso di bit della struttura al albero di un elemento è possibile utilizzare la funzione cniElementAsBitstream. Mediante tale funzione, è possibile ottenere la rappresentazione del flusso di bit di un elemento in un messaggio. Per informazioni dettagliate su come utilizzare questa funzione e il codice di esempio, fare riferimento a cniElementAsBitstream.

Trasformazione di un oggetto messaggio

Il messaggio di input ricevuto è si sola lettura quindi, prima che un messaggio possa essere trasformato, è necessario scriverlo su un nuovo messaggio di output utilizzando la funzione cniCreateMessage. E' possibile copiare gli elementi dal messaggio di input oppure è possibile creare nuovi elementi e collegarli al messaggio. I nuovi elementi sono generalmente in un dominio del programma di analisi.

Ad esempio:
  1. Per scrivere il messaggio in entrata su un nuovo messaggio:
    {
      ...
      context = cniGetMessageContext(&rc, message)); 
      outMsg = cniCreateMessage(&rc, context)); 
      ...
    }
  2. Per effettuare una copia del nuovo messaggio:
    cniCopyElementTree(&rc, sourceElement, targetElement);
  3. Per modificare il valore di un elemento di destinazione:
      cniSetElementIntegerValue(&rc, targetElement, L"newValue", 8); 
  4. Dopo aver eseguito la finalizzazione e la distribuzione del messaggio, è necessario eliminare il messaggio di output utilizzando la funzione cniDeleteMessage:
     cniDeleteMessage(&rc, outMsg);
Come parte della trasformazione, potrebbe essere necessario creare un nuovo contenuto del messaggio. A tal fine, sono disponibili le seguenti funzioni:
cniCreateElementAsFirstChildUsingParser
cniCreateElementAsLastChildUsingParser
cniCreateElementAfterUsingParser
cniCreateElementBeforeUsingParser
Queste funzioni devono essere utilizzate in quanto sono specifiche dell'assegnazione di un programma di analisi ad una cartella della struttura ad albero del messaggio.
Quando si crea il contenuto di un messaggio, non utilizzare le seguenti funzioni in quando queste non eseguono l'associazione di un programma di analisi di proprietà con la cartella:
cniCreateElementAsFirstChild
cniCreateElementAsLastChild
cniCreateElementAfter
cniCreateElementBefore

Accesso a ESQL

I nodi possono richiamare espressioni ESQL utilizzando la sintassi ESQL del nodo Compute. E' possibile creare e modificare i componenti del messaggio utilizzando espressioni ESQL ed è possibile fare riferimento agli elementi sia del messaggio di input che dei dati provenienti da un database esterno utilizzando le funzioni cniSqlCreateStatement, cniSqlSelect, cniSqlDeleteStatement e cniSqlExecute.

Ad esempio, per popolare l'elemento Result con il contenuto di una colonna in una tabella di database:

{
  ...
  sqlExpr = cniSqlCreateStatement(&rc, 
   (NODE_CONTEXT_ST *)context->nodeObject,
   L"DB", CCI_SQL_TRANSACTION_AUTO,
   L"SET OutputRoot.XML.Result[] = (SELECT T.C1 AS Col1 FROM Database.TABLE AS T;");
  ...
  cniSqlSelect(&rc, sqlExpr, destinationList, exceptionList, message, outMsg);
  cniSqlDeleteStatement(&rc, sqlExpr);
  ...                                                               
}

Per ulteriori informazioni su ESQL, fare riferimento a Panoramica di ESQL.

Se il nodo definito dall'utente utilizza principalmente ESQL è possibile considerare l'utilizzo di un nodo compute, vedere Nodo Compute.

Distribuzione di un messaggio

Prima di distribuire un messaggio è necessario decidere quali dati del flusso di messaggi si desidera distribuire e quale terminale deve ricevere tali dati.
  1. Se il messaggio ha subito modifiche, è necessario finalizzarlo prima di eseguirne la distribuzione utilizzando la funzione cniFinalize. Ad esempio:
          cniFinalize(&rc, outMsg, CCI_FINALIZE_NONE);
  2. terminalObject viene ricavato da un elenco che il nodo definito dall'utente mantiene egli stesso. Per distribuire il messaggio al terminale di output, utilizzare la funzione cniPropagate:
      if (terminalObject) {
        if (cniIsTerminalAttached(&rc, terminalObject)) {
          if (rc == CCI_SUCCESS) {
            cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg);
          }
        }

    Nell'esempio riportato in precedenza, la funzione cniIsTerminalAttached viene utilizzata per verificare se il messaggio può essere distribuito al terminale specificato. Se la funzione cniIsTerminalAttached non viene utilizzata e il terminale non è collegato ad un altro nodo mediante un connettore, il messaggio non viene distribuito e nessun messaggio di avviso viene restituito. Utilizzare la funzione cniIsTerminalAttached per prevenire questo problema.

  3. Se è stato creato un nuovo messaggio di output utilizzando cniCreateMessage, dopo aver eseguito la distribuzione del messaggio, è necessario eliminare il messaggio di output utilizzando la funzione cniDeleteMessage:
     cniDeleteMessage(&rc, outMsg);

Scrittura su un'unità di output

Un messaggio che ha subito delle modifiche deve essere serializzato su un flusso di bit. È possibile quindi accedere al flusso di bit ed eseguirne la scrittura su un'unità di output. È possibile scrivere il messaggio su un flusso di bit utilizzando la funzione cniWriteBuffer. Ad esempio:
{
  ...
  cniWriteBuffer(&rc, message);
  writeToDevice(cniBufferPointer(&rc, message), cniBufferSize(&rc, message));
  ...                                                               
}
In questo esempio, il metodo writeToDevice è scritto dall'utente che scrive un flusso di bit su un'unità di output.

Tenere presente che è possibile eseguire la serializzazione di un messaggio solo una volta.

Nota: quando si scrive sulle code WebSphere MQ, è necessario utilizzare il nodo MQOutput fornito, in quanto il broker mantiene internamente una connessione WebSphere MQ e handle di coda aperta su base thread-by-thread e questi vengono sono inseriti nella cache per ottimizzare le prestazioni. Inoltre, il broker gestisce scenari di ripristino quando si verificano determinati eventi WebSphere MQ e ciò potrebbe avere effetti negativi se in un nodo di output definito dall'utente sono state utilizzate chiamate MQI WebSphere MQ.
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
as24989_