Vorbereitungen
Eine ladbare Implementierungsbibliothek (Loadable Implementation Library, LIL) ist das Implementierungsmodul für einen C-Knoten (oder -Parser). Eine LIL-Datei wird als DLL-Datei (Dynamic Link Library) implementiert. Die Dateierweiterung ist dabei nicht DLL, sondern LIL.
Die Implementierungsfunktionen, die vom Entwickler geschrieben werden müssen, sind unter Implementierungsfunktionen für C-Knoten aufgelistet. Die Dienstprogrammfunktionen, die von WebSphere Message Broker bereitgestellt werden, um diesen Prozess zu unterstützen, sind unter Dienstprogrammfunktionen für C-Knoten aufgelistet.
WebSphere Message Broker stellt die Quelle für die zwei benutzerdefinierten Beispielknoten 'Umschaltungsknoten' und 'Umsetzungsknoten' bereit. Diese Knoten können in ihrem aktuellen Zustand verwendet oder von Ihnen angepasst werden.
Sie müssen zum Deklarieren und Definieren eines benutzerdefinierten Knotens für den Broker eine Initialisierungsfunktion, bipGetMessageflowNodeFactory, in Ihrer LIL einfügen. Im Folgenden wird erläutert, wie die Initialisierungsfunktion vom Broker aufgerufen wird und wie durch diese Funktion der benutzerdefinierte Knoten deklariert und definiert wird:
In der folgenden Prozedur wird beschrieben, wie Sie für Ihren Knoten eine Instanz erstellen können:
Attribute werden festgelegt, wenn Sie den Broker starten oder den Nachrichtenfluss mit neuen Werten erneut einsetzen.
{ 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) ; }
Wenn der Broker einen Empfangsknoten entdeckt, ruft er in regelmäßigen Intervallen die Funktion cniRun dieses Knotens auf. Durch die Funktion cniRun wird die weitere Vorgehensweise entschieden. Wenn Daten zur Verarbeitung vorhanden sind, sollte die cniRun-Funktion versuchen, die Nachricht weiterzugeben. Wenn keine Daten zur Verarbeitung vorhanden sind, sollte von der cniRun-Funktion CCI_TIMEOUT zurückgegeben werden, damit der Broker mit den Konfigurationsänderungen fortfahren kann.
If ( anything to do ) CniDispatchThread; /* do the work */ If ( work done O.K.) Return CCI_SUCCESS_CONTINUE; Else Return CCI_FAILURE_CONTINUE; Else Return CCI_TIMEOUT;
Die Implementierung eines Empfangsknotens bestimmt normalerweise, durch welchen Nachrichtenparser eine Eingabenachricht anfangs syntaktisch analysiert wird. Beispiel: Der Primitive-Knoten MQInput gibt an, dass ein MQMD-Parser für die Syntaxanalyse des MQMD-Headers erforderlich ist. Durch einen benutzerdefinierten Empfangsknoten können ein entsprechender Header oder Nachrichtenparser sowie der Modus ausgewählt werden, durch den die Syntaxanalyse gesteuert wird, indem die folgenden, standardmäßig enthaltenen Attribute verwendet werden, die überschrieben werden können:
CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix bipGetMessageflowNodeFactory() { .... CciFactory* factoryObject; .... factoryObject = cniCreateNodeFactory(0, (unsigned short *)constPluginNodeFactory); ... vftable.iFpCreateNodeContext = _createNodeContext; vftable.iFpSetAttribute = _setAttribute; vftable.iFpGetAttribute = _getAttribute; ... cniDefineNodeClass(&rc, factoryObject, (CciChar*)constSwitchNode, &vftable); ... return(factoryObject); }
CciContext* _createNodeContext( CciFactory* factoryObject, CciChar* nodeName, CciNode* nodeObject ){ NODE_CONTEXT_ST* p; ... /* Allocate a pointer to the local context */ p = (NODE_CONTEXT_ST *)malloc(sizeof(NODE_CONTEXT_ST)); /* Create attributes and set default values */ { const CciChar* ucsAttrName = CciString("firstParserClassName", BIP_DEF_COMP_CCSID) ; const CciChar* ucsAttrValue = CciString("MYPARSER", BIP_DEF_COMP_CCSID) ; insAttrTblEntry(p, (CciChar*)ucsAttrName, CNI_TYPE_INTEGER); /*see sample BipSampPluginNode.c for implementation of insAttrTblEntry*/ _setAttribute(p, (CciChar*)ucsAttrName, (CciChar*)ucsAttrValue); free((void *)ucsAttrName) ; free((void *)ucsAttrValue) ; }Im Codebeispiel oben wird die Methode insAttrTblEntry aufgerufen. Sie ist in den benutzerdefinierten Beispielknoten 'Umschaltungsknoten' und 'Umsetzungsknoten' deklariert.
Knoten werden beim erneuten Einsetzen eines Nachrichtenflusses oder beim Stoppen des Prozesses der Ausführungsgruppe mit Hilfe des Befehls mqsistop gelöscht. Durch das Löschen des Knotens sollte der verwendete Speicher und darin enthaltene Ressourcen freigegeben werden. Verwenden Sie dazu die Funktion cniDeleteNodeContext. Beispiel:
void _deleteNodeContext( CciContext* context ){ static char* functionName = (char *)"_deleteNodeContext()"; return; }