Vorbereitungen
Eine ladbare Implementierungsbibliothek (Loadable Implementation Library, LIL) ist das Implementierungsmodul für einen C-Knoten (oder -Parser). Eine LIL ist als DLL-Datei implementiert. Sie hat jedoch nicht die Dateierweiterung .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. Sie können diese Knoten in ihrem aktuellen Zustand verwenden, oder Sie können sie ändern.
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:
Im Folgenden wird die Vorgehensweise bei der Erstellung einer Instanz des Knotens beschrieben:
Attribute werden festgelegt, wenn Sie den Broker starten oder wenn Sie den Nachrichtenfluss mit neuen Werten erneut implementieren.
{ 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 weiß, dass er über einen Empfangsknoten verfügt, ruft er die Funktion cniRun dieses Knotens in regelmäßigen Abständen auf. Die Funktion cniRun muss dann entscheiden, welche Maßnahme ergriffen werden soll. 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;
Eine Empfangsknotenimplementierung bestimmt normalerweise, welcher Nachrichtenparser eine Eingabenachricht anfangs analysiert. Der primitive MQEmpfangsknoten gibt beispielsweise vor, dass für die Syntaxanalyse des MQMD-Headers ein MQMD-Parser erforderlich ist. Ein benutzerdefinierter Empfangsknoten kann einen geeigneten Header oder Nachrichtenparser und den Modus, in dem die Syntaxanalyse gesteuert wird, mit Hilfe der folgenden Attribute auswählen, die standardmäßig enthalten sind und die Sie überschreiben 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 gelöscht, wenn ein Nachrichtenfluss erneut implementiert wird oder wenn der Ausführungsgruppenprozess gestoppt wird (mit dem Befehl mqsistop). Wenn ein Knoten gelöscht wird, sollte der gesamte verwendete Speicher und die verwendeten Ressourcen freigegeben werden. Dazu verwenden Sie die Funktion cniDeleteNodeContext. Beispiel:
void _deleteNodeContext( CciContext* context ){ static char* functionName = (char *)"_deleteNodeContext()"; return; }