시작하기 전에
LIL(Loadable Implementation Library)는 C 노드(또는 구문 분석기)용 구현 모듈입니다. LIL은 DLL(Dynamic Link Library)로 구현되며 파일 확장자 .dll이 아닌 .lil을 가집니다.
개발자가 작성해야 하는 구현 함수는 C 노드 구현 함수에 나열되어 있습니다. 이 프로세스를 돕기 위해 WebSphere Message Broker가 제공하는 유틸리티 함수는 C 노드 유틸리티 함수에 나열되어 있습니다.
WebSphere Message Broker에서는 두 개의 샘플 사용자 정의 노드, 즉 SwitchNode 및 TransformNode의 소스를 제공합니다. 현재 상태에서 이 노드를 사용하거나 수정할 수 있습니다.
브로커에 사용자 정의 노드를 선언 및 정의하려면 초기화 함수인 bipGetMessageflowNodeFactory를 LIL에 반드시 포함해야 합니다. 다음 단계는 브로커가 초기화 함수를 호출하는 방법 및 초기화 함수가 사용자 정의 노드를 선언하고 정의하는 방법을 간략히 설명합니다.
브로커를 시작할 때마다 또는 메시지 플로우를 새 값으로 재전개할 때 속성이 설정됩니다.
{ 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 함수는 메시지 전달을 시도해야 합니다. 데이터가 처리 가능하지 않은 경우, cniRun 함수는 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) ; }위의 코드 예제에서는 insAttrTblEntry 메소드가 호출됩니다. 이 메소드는 SwitchNode 및 TransformNode 샘플 사용자 정의 노드에서 선언됩니다.
메시지 플로우가 재전개될 때 또는 실행 그룹 프로세스가 정지될 때 노드가 폐기됩니다(mqsistop 명령 사용). 노드가 폐기될 때는 사용된 모든 메모리를 비우고 보유 자원을 모두 해제해야 합니다. cniDeleteNodeContext 함수를 사용하여 이 작업을 수행할 수 있습니다. 예를 들면, 다음 코드와 같습니다.
void _deleteNodeContext( CciContext* context ){ static char* functionName = (char *)"_deleteNodeContext()"; return; }