Antes de empezar
Una biblioteca de implementación cargable, o LIL, es el módulo de implementación para un nodo (o analizador) C. Una LIL se implementa como una biblioteca de enlaces dinámicos (DLL). No tiene la extensión de archivo .dll sino .lil.
Las funciones de implementación que el desarrollador debe escribir se listan en el apartado Funciones de implementación de nodo en C. Las funciones de programa de utilidad que WebSphere Message Broker proporciona para ayudar en este proceso se listan en el apartado Funciones de programa de utilidad de nodo en C.
WebSphere Message Broker proporciona el origen de dos nodos de ejemplo definidos por el usuario denominados SwitchNode y TransformNode. Puede utilizar estos nodos en su estado actual o puede modificarlos. También puede utilizar el ejemplo Extensión definida por el usuario.
Conceptualmente, un nodo de proceso de mensajes se utiliza para procesar un mensaje de algún modo y un nodo de salida se utiliza para producir un mensaje como una corriente de bits. Sin embargo, cuando se codifica un nodo de proceso de mensajes o un nodo de salida, éstos son esencialmente lo mismo. Puede realizar el proceso de mensajes en un nodo de salida y, del mismo modo, puede producir un mensaje en una corriente de bits utilizando un nodo de proceso de mensajes. Aunque, para una mayor sencillez, este tema hace referencia principalmente al nodo como nodo de proceso de mensajes, describe la funcionalidad de ambos tipos de nodo.
El procedimiento siguiente muestra cómo declarar el nodo en el intermediario:
void defineSwitchNode(void* factoryObject){ static CNI_VFT vftable = {CNI_VFT_DEFAULT}; /* Configurar tabla de funciones con punteros a funciones de implementación de nodo */ vftable.iFpCreateNodeContext = _createNodeContext; vftable.iFpDeleteNodeContext = _deleteNodeContext; vftable.iFpGetAttributeName2 = _getAttributeName2; vftable.iFpSetAttribute = _setAttribute; vftable.iFpGetAttribute2 = _getAttribute2; vftable.iFpEvaluate = _evaluate; cniDefineNodeClass(0, factoryObject, L"SwitchNode", &vftable); return; }Dicha función se invoca desde la hebra de configuración.
Un nodo definido por el usuario se identifica a sí mismo como un nodo que proporciona las posibilidades de un nodo de proceso de mensajes o de salida implementando la función cniEvaluate. Los nodos definidos por el usuario tienen que implementar una función de implementación cniEvaluate y/o cniRun o, de lo contrario, el intermediario no cargará el nodo definido por el usuario y la función de utilidad cniDefineNodeClass fallará, devolviendo CCI_MISSING_IMPL_FUNCTION.
Cuando se despliega satisfactoriamente un flujo de mensajes que contiene un nodo de proceso de mensajes definido por el usuario, se invoca la función cniEvaluate del nodo para cada mensaje pasado a través del flujo de mensajes.
Los datos de flujo de mensajes se reciben en el terminal de entrada del nodo, es decir el mensaje, el entorno global, el entorno local y la lista de excepciones.
void cniEvaluate( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ){ ... }
El procedimiento siguiente muestra cómo crear instancias del nodo:
Se establecen atributos siempre que se inicia el intermediario o cuando se vuelve a desplegar un flujo de mensajes con valores nuevos. El intermediario establece atributos invocando el código de usuario en la hebra de configuración. El código de usuario necesita almacenar estos atributos en el área de contexto de nodo, para utilizarlos posteriormente al procesar mensajes.
{ const CciChar* ucsAttr = CciString("nodeTraceSetting", BIP_DEF_COMP_CCSID) ; insAttrTblEntry(p, (CciChar*)ucsAttr, CNI_TYPE_INTEGER); _setAttribute(p, (CciChar*)ucsAttr, (CciChar*)constZero); free((void *)ucsAttr) ; } { const CciChar* ucsAttr = CciString("nodeTraceOutfile", BIP_DEF_COMP_CCSID) ; insAttrTblEntry(p, (CciChar*)ucsAttr, CNI_TYPE_STRING); _setAttribute(p, (CciChar*)ucsAttr, (CciChar*)constSwitchTraceLocation); free((void *)ucsAttr) ; }
Cuando el intermediario recupera un mensaje de la cola y dicho mensaje llega al terminal de entrada del nodo de salida o de proceso de mensajes definido por el usuario, el intermediario invoca la función de implementación cniEvaluate. Esta función se invoca en la hebra de proceso de mensajes y debe decidir qué se debe hacer con el mensaje. Es posible que esta función se invoque en varias hebras, específicamente si se utilizan instancias adicionales.
Para suprimir una instancia de un nodo, utilice la función cniDeleteNodeContext. Por ejemplo:
void _deleteNodeContext( CciContext* context ){ static char* functionName = (char *)"_deleteNodeContext()"; return; }
El usuario proporciona la función cniDeleteNodeContext y el intermediario la llama cuando se suprime un flujo de mensajes.