A message processing node is used to process a message in some way, and an output node is used to produce a message as a bit stream.
When you code a message processing node or an output node, the nodes provide essentially the same services. You can perform message processing in an output node, and you can send a message to a bit stream by using a message processing node. For simplicity, this topic refers mainly to the node as a message processing node but it does also contain information about the functions of both types of node.
A loadable implementation library (LIL), is the implementation module for a C node. A LIL is implemented as a shared or dynamic link library (DLL), but has the file extension .lil not .dll.
For more information about the C node implementation functions that you write for the node, see C node implementation functions. You can call C node utility functions, implemented in the runtime integration node, to help with the node operation; see C node utility functions.
IBM® Integration Bus provides the source for two sample user-defined nodes called SwitchNode and TransformNode. You can use these nodes in their current state, or you can modify them.
To declare and define a user-defined node to the integration node, include an initialization function, bipGetMessageflowNodeFactory, in your LIL. The following steps take place on the configuration thread and outline how the integration node calls your initialization function and how your initialization function declares and defines the user-defined node:
To instantiate your node:
Attributes are set whenever you start the integration node, or when you redeploy a message flow with new values. Attributes are set by the integration node calling user code on the configuration thread. Your code needs to store these attributes in its node context area, for later use when processing messages.
{
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) ;
}
When the integration node retrieves a message from the queue, and that message arrives at the input terminal of your user-defined message processing or output node, the integration node calls the implementation function cniEvaluate. This function is called on the message processing thread and it must decide what to do with the message. This function might be called on multiple threads, especially if additional instances are used.
If a node is deleted, the integration node calls the cniDeleteNodeContext function. This function is started on the same thread as cniCreateNodeContext. Use this function to release resources used by your user-defined node. For example:
void _deleteNodeContext(
CciContext* context
){
static char* functionName = (char *)"_deleteNodeContext()";
free ((void*) context);
return;
}