1 CDK Design and Concepts

This chapter provides background information required for creating custom Oracle Communications Offline Mediation Controller nodes.

Overview

It is recommended that nodes perform tasks that are relatively small in scope to aid in faster processing. Two custom nodes (such as a CC node and an EP node) chained together may yield better throughput, flexibility, and validity, rather than writing a single node to achieve the same results. The most commonly customized nodes are CC and DC nodes.

The "generic" nodes that can be modified using the Cartridge Development Kit (CDK) are in the Offline Mediation Controller GUI in the "Cartridge Kit" market segment.

Life cycle of a node

Once the Offline Mediation Controller system is running, all nodes run within the Node Manager's VM. For debugging purposes, nodes can be run from the command line, provided that a main() method is implemented.

The Offline Mediation Controller system provides a mechanism for adding a node to the Node Manager and configuring and starting the node to process data via a Graphical User Interface (GUI). This process is described in more detail later in this document.

A node (object) is officially created when the user adds it to a Node Manager's node list and starts it. All necessary configuration information is captured and stored in the configuration file when the user creates the node. However, the node's constructor is not invoked until the user clicks the Start button in the Administration Client GUI.

Data flow diagram

Figure 1-1 shows the flow of data through any given node chain.

DCNode class hierarchy

Figure 1-2 and Figure 1-3 illustrate the class hierarchy of the base DCNode classes. Details of individual node components are included in later sections of this document. Methods that should be overridden are in italics.

Note:

All derivations of DCNode should provide a default (i.e., no-argument) constructor, which initializes the information necessary to implement DCNodeTypeIfc.

Figure 1-2 DCNode Class Hierarchy

Description of Figure 1-2 follows
Description of "Figure 1-2 DCNode Class Hierarchy"

Note:

The StateManagement and NodeStateManagement interfaces are currently not supported.

Figure 1-3 DCNode Class Hierarchy

Description of Figure 1-3 follows
Description of "Figure 1-3 DCNode Class Hierarchy"

DCNode class diagram

Figure 1-4 illustrates the DCNode classes.

Figure 1-4 DCNode Class Diagram

Description of Figure 1-4 follows
Description of "Figure 1-4 DCNode Class Diagram"

DCNode class hierarchy

Figure 1-5 DCNode Class Hierarchy

Description of Figure 1-5 follows
Description of "Figure 1-5 DCNode Class Hierarchy"

DataProvider and DataReceiver

The object-level representation of the data flow through a node can be expressed as a Data Provider and/or a Data Receiver.

DataProvider

A Data Provider is a component that provides data to another component within the node. The DataProviderIfc interface defines this component, which provides methods that allow data to flow to another component within the node.

DataReceiver

A Data Receiver accepts data from another component within the node. A Data Receiver is defined by the DataReceiverIfc interface which provides methods that allow data to be obtained from another component within the node.

Relationship between DataProvider and DataReceiver

Data may flow through a node using either a "push" or "pull" algorithm. It is up to the individual node developer to determine which algorithm is used within the node. If data comes in very slowly, the developer may want to"push" the data from the DataProvider to the DataReceiver, as it becomes available. Conversely, a DataReceiver may "pull" data from its DataProvider by periodically asking the DataProvider if data is available and retrieving it for processing. Both of these situations are illustrated below.

DataProvider Push

First, the DataProvider's DataReceiver must be set. In this case, transport (an EITransport) is the DataProvider and fp (NPLFieldProcessor) is the DataReceiver.

·// Set up the DataReceiver/DataProvider mappings
·transport.setDataReceiver( fp );

Then, the DataProvider calls the DataReceiver's processData() method directly.

·    MyEIRecord eiRecord = new MyEIRecord( data );
·
·    try
·    {
·        // Give this record to the data provider for
·        // further processing.
·        getDataReceiver().processData( eiRecord );
·    }
·    catch( Exception e )
·    {
·        System.out.println( "Processing error: " + e.getMessage() );
·        getLogger().logError( "Error processing record: " + e, false );
·    }

Another option would be for the DataProvider to call the DataReceiver's dataIsAvailable() method, and then the DataReceiver would make a call back to the DataProvider's getData() method to retrieve the data. Again, the setDataReceiver() method would need to be called first.

Example 1-1 Push using getData()

·    public void dataIsAvailable()
·    {
·        dataAvailable = true;
·
·        DataProviderIfc provider = getDataProvider();
·
·        if( provider != null )
·        {
·            DCFieldContainer data = getDataProvider().getData();
·
·            while( data != null )
·            {
·                try
·                {
·                    processData( data );
·                }
·                catch( NodeProcessingException npe )
·                {
·                    // Do something…
·                }
·                data = provider.getData();
·            }
·        }
·
·        dataAvailable = false;
·    }
DataReceiver Pull

In a “pull" scenario, it is likely that the data is coming in quickly and that the DataProvider will utilize some sort of queue in order to store the data temporarily until the DataReceiver is ready for it. This setup is particularly useful for CCs which are using real-time (or near real-time) transports, such as UDP or TCP, and need to be able to collect the data as it comes in “off the line".

The DataProvider must first be set using the setDataProvider() method, similar to the above call to setDataReceiver() in the “push" scenario.

The DataReceiver would probably be running in a thread, and do the following as part of the run() method:

Example 1-2 Implementing DataReceiver Pull

·    while( running )
·    {
·        while( getDataProvider().isDataAvailable() )
·        {
·            DCFieldContainer data = getDataProvider().getData();
·            try
·            {
·                processData( data );
·            }
·            catch( NodeProcessingException npe )
·            {
·                System.out.println( "NodeProcessingException caught while " +
·                             "processing record.\n    " + npe.getMessage() );
·            }
·        }
·        if( running )
·        {
·            try
·            {
·                Thread.currentThread().sleep( 2000 );
·            }
·            catch( InterruptedException ie ) { }
·        }
·    }

Transport

A Transport is responsible for moving data into and out of the Offline Mediation Controller system. Transports are only associated with CC or DC nodes.

EITransport

An EITransport is a DataProvider that accepts data from outside of the Offline Mediation Controller system and creates the appropriate EIRecord objects for that data. Therefore, the EITransport needs to know the record delimiter, as well as the EIRecord object to be populated from each raw data record. An EITransport may contain a factory (described later), which would be responsible for creating the appropriate EIRecord objects when needed, or receive this class type information as a parameter. In cases where data may be coming in rapidly (for example, via UDP packets in a CC node), the EITransport could utilize a revolving queue to store the incoming records until the DataReceiver is ready for them.

OITransport

An OITransport is a DataReceiver that receives OIRecord objects specific to the destination of the data and is responsible for transmitting that data to the desired destination. The OITransport will extract the formatted data from the OIRecord and send the data out of the Offline Mediation Controller system via the appropriate medium. The OITransport will typically receive its data from a “push". It is bound by the frequency of the incoming data and the speed of its DataProvider.

DCRecordFactoryIfc

The DCRecordFactoryIfc is a generic interface that can be used which will accept data and generate the appropriate EIRecord or OIRecord objects. This allows a Transport or FieldProcessor to behave in a generic way without having to explicitly know what type of EIRecord or OIRecord object that needs to be created based on the incoming or outgoing data.

The only time a user of the CDK would need to write their own DCRecordFactoryIfc would be if they intended to use an existing transport with a custom EIRecord.

Figure 1-6 shows the DCRecordFactoryIfc interface.

Transport class hierarchy

Figure 1-7 shows the hierarchy of the Transport class.

Figure 1-7 Transport Class Hierarchy

Description of Figure 1-7 follows
Description of "Figure 1-7 Transport Class Hierarchy"

FieldProcessor

There is an NPLFieldProcessor provided, which should be used by all nodes. This class uses information contained in an ASCII text file, which contains NPL commands. (See the NPL Reference Guide for more information). The FieldProcessor utilizes the information in the NPL file to transform, translate, enhance, and/or route information from the incoming DCFieldContainer object into the appropriate outgoing DCFieldContainer object. A FieldProcessor is both a DataProvider and a DataReceiver.

FieldProcessor class hierarchy

Figure 1-8 shows the FieldProcessor class hierarchy.

Figure 1-8 FieldProcessor Class Hierarchy

Description of Figure 1-8 follows
Description of "Figure 1-8 FieldProcessor Class Hierarchy"

DCFieldContainer

The DCFieldContainer is a generic interface that is used for passing the data within and between nodes. A DCFieldContainer represents a single record of data. It is responsible for converting data from its raw format (for example from UDP packets, ASCII, or binary files) and extracting specific pieces as fields for use by the DataReceiver.

The DCFieldContainer is where most of the work is done for a particular node. This class is responsible for knowing the format and order of the incoming (or outgoing) data, and how to extract (or assemble) that data on a per field basis.

Adapter classes are provided (DCEIRecordAdapter and DCOIRecordAdapter), which “no-op" those methods that are not needed based on the type of DCFieldContainer. That is, a DCFieldContainer in a CC node would most likely use only the get… methods from DCFieldContainer for extracting data fields. Conversely, a DCFieldContainer in a DC node would most likely use only the set… methods.

EIRecord

EIRecord is derived from DCEIRecordAdapter and is the class that developers should derive from when developing a DCFieldContainer object for use in a CC node.

OIRecord

OIRecord is derived from DCOIRecordAdapter and is the class that developers should derive from when developing a DCFieldContainer object for use in a DC node. Note that derivations of OIRecord should include a default (i.e. no-argument) constructor in order to be utilized properly by the NPLFieldProcessor.

EIRecord and OIRecord Storage

Both the EIRecord and OIRecord classes are responsible for storing attributes. The various field functions will pass attribute IDs to distinguish between the attributes. These IDs originate from the NPL, and may be either the attribute values or names, depending on which is used in the NPL. The EIRecord and OIRecord should refrain from hard coding the possible values, as the NPL can be independently changed. Instead, more generic means, such as hash tables, should be used for storage and retrieval of these values.

NAR

As mentioned previously, the NAR is the DCFieldContainer object that is used internally within the Offline Mediation Controller system. The FieldProcessor of a CC node generates a NAR, which then may be passed through one or more processor nodes for further modification and is received by the FieldProcessor in an DC node.

A Data Dictionary provides definitions for the type of data in the fields (potentially) within a NAR. This information is currently available in a text file, located at OMC_Home/datadict/Data_Dictionary, where OMC_Home is the directory in which you installed Offline Mediation Controller.

DCFieldContainer class hierarchy

Figure 1-9 shows the DCFieldContainer class hierarchy.

Figure 1-9 DCFieldContainer Class Hierarchy

Description of Figure 1-9 follows
Description of "Figure 1-9 DCFieldContainer Class Hierarchy"

DCField

A DCField is an object that represents the attributes (fields) of a particular record. DCField objects are stored in a DCFieldContainer. Most data types can be represented with the DCField classes that are provided.

Figure 1-10 shows the DCField object and attributes.

DCField class hierarchy

Figure 1-11 shows DCField class hierarchy.

Figure 1-11 DCField Class Hierarchy

Description of Figure 1-11 follows
Description of "Figure 1-11 DCField Class Hierarchy"

DCStreamHandler

The DCStreamHandler provides functionality to move data records from one node to the next in the node chain. The current implementation of the Offline Mediation Controller system utilizes a NARFileManager. The base node classes provide this object, and the moving of the data is transparent to the user and developer. In other words, a node developer (in general) does not need to be concerned about getting data from one node to another, this is all handled by the system. Developers only need to be concerned with moving data inside the node.

DCStreamHandler class hierarchy

Figure 1-12 shows the DCStreamHandler class hierarchy.

Figure 1-12 DCStreamHandler Class Hierarchy

Description of Figure 1-12 follows
Description of "Figure 1-12 DCStreamHandler Class Hierarchy"
DCStreamHandler class hierarchy (continued)

Figure 1-13 shows the NARStreamHandler class.