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 'TransformNode' bereit. Sie können diese Knoten in ihrem aktuellen Zustand verwenden, oder Sie können sie ändern.
Im Folgenden wird die Vorgehensweise bei der Initialisierung des Knotens beschrieben:
Ein benutzerdefinierter Knoten identifiziert sich selbst als Empfangsknoten, indem er die Implementierungsfunktion cniRun implementiert. Benutzerdefinierte Empfangsknoten müssen eine cniRun-Funktion implementieren, ansonsten lädt der Broker den benutzerdefinierten Knoten nicht, und die Dienstprogrammfunktion cniDefineNodeClass schlägt mit dem Rückkehrcode CCI_MISSING_IMPL_FUNCTION fehl. Wenn ein Nachrichtenfluss, der einen benutzerdefinierten Empfangsknoten enthält, erfolgreich implementiert wird, ruft der Broker die Implementierungsfunktion cniRun in regelmäßigen Abständen auf.
int cniRun( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ){ ... /* Get data from external source */ return CCI_SUCCESS_CONTINUE; }Der Rückgabewert sollte zur regelmäßigen Rückgabe der Steuerung an den Broker verwendet werden.
Wenn ein Nachrichtenfluss, der einen benutzerdefinierten Empfangsknoten enthält, erfolgreich implementiert wird, wird die Funktion cniRun des Knotens für jede Nachricht, die den Nachrichtenfluss durchläuft, aufgerufen.
Empfangsknoten können auch cniEvaluate implementieren, dies wird jedoch nicht empfohlen.
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 verfügbar sind, sollte die FunktioncniRun cniDispatchThread aufrufen und die Nachricht verarbeiten oder mit CCI_TIMEOUT zurückgeben, so dass der Broker mit der Verarbeitung anderer Nachrichten in anderen Threads fortfahren kann. Wenn ein Thread nicht zugeteilt wird, verbringt der Broker seine gesamte Zeit in diesem Thread, was ihn daran hindert, etwas anderes zu tun.
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 Nachrichten-Parser 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 Nachrichten-Parser 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) ; }
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; }