시작하기 전에
LIL(Loadable Implementation Library)는 C 노드(또는 구문 분석기)용 구현 모듈입니다. LIL은 DLL(Dynamic Link Library)로 구현되며 파일 확장자 .dll이 아닌 .lil을 가집니다.
개발자가 작성해야 하는 구현 함수는 C 노드 구현 함수에 나열되어 있습니다. 이 프로세스를 돕기 위해 WebSphere Message Broker가 제공하는 유틸리티 함수는 C 노드 유틸리티 함수에 나열되어 있습니다.
WebSphere Message Broker에서는 두 개의 샘플 사용자 정의 노드, 즉 SwitchNode 및 TransformNode의 소스를 제공합니다. 현재 상태에서 이 노드를 사용하거나 수정할 수 있습니다.
사용자 정의 노드는 cniRun 구현 함수를 구현하여 입력 노드의 성능을 제공할 때 자체적으로 식별합니다. 사용자 정의 입력 노드는 cniRun 함수를 구현해야 합니다. 아니면, 브로커는 사용자 정의 노드를 로드하지 못하고 cniDefineNodeClass 유틸리티 함수가 실패하면서 CCI_MISSING_IMPL_FUNCTION이 리턴됩니다. 사용자 정의 입력 노드가 포함된 메시지 플로우가 정상적으로 전개될 때, 브로커는 노드의 cniRun 구현 함수를 정기적 간격으로 호출합니다.
int cniRun( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ){ ... /* Get data from external source */ return CCI_SUCCESS_CONTINUE; }리턴 값은 정기적으로 브로커로 제어를 리턴하는 데 사용됩니다.
사용자 정의 입력 노드가 포함된 메시지 플로우가 정상적으로 전개될 때, 메시지 플로우를 통해 전달된 각 메시지마다 노드의 cniRun 함수가 호출됩니다.
또한 입력 노드는 cniEvaluate를 구현할 수 있지만 이는 권장되지 않습니다.
브로커를 시작할 때마다 또는 메시지 플로우를 새 값으로 재전개할 때 속성이 설정됩니다.
{ 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) ; }
브로커가 입력 노드를 가지고 있음을 알고 있을 때는 이 노드의 cniRun 함수를 정기적으로 호출합니다. cniRun 함수는 취해야 할 조치를 결정합니다. 데이터가 처리 가능한 경우, cniRun 함수는 cniDispatchThread를 호출하여 메시지를 처리하거나 CCI_TIMEOUT을 리턴하여 브로커가 다른 스레드의 다른 메시지를 계속 처리하도록 합니다. 스레드가 디스패치되지 않은 경우, 브로커는 이 스레드 내부에 모든 시간을 소비하게 되어 다른 작업을 수행하지 못하게 됩니다.
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;
일반적으로 입력 노드 구현은 초기에 입력 메시지를 구문 분석하는 메시지 구문 분석기가 어떤 것인지 판별합니다. 예를 들어, 기본 MQInput 노드는 MQMD 구문 분석기가 MQMD 헤더를 구문 분석하도록 지시합니다. 사용자 정의 입력 노드는 디폴트로 포함된 다음 속성을 사용하여 적절한 헤더나 메시지 구문 분석기, 구문 분석이 제어되는 모드를 선택할 수 있습니다. 이 속성을 대체할 수 있습니다.
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) ; }
메시지 플로우가 재전개될 때 또는 실행 그룹 프로세스가 정지될 때 노드가 폐기됩니다(mqsistop 명령 사용). 노드가 폐기될 때는 사용된 모든 메모리를 비우고 보유 자원을 모두 해제해야 합니다. cniDeleteNodeContext 함수를 사용하여 이 작업을 수행할 수 있습니다. 예를 들면, 다음 코드와 같습니다.
void _deleteNodeContext( CciContext* context ){ static char* functionName = (char *)"_deleteNodeContext()"; return; }