Skip to Main Content U.S. Department of Energy

Base Component Model


In the Hello World Example we showed how to create a most basic MIF pipeline. In this document we will expand on that example to demonstrate:

  • MIF Components
  • An example of a pipeline created with MIF components.
  • Other integration constructs inherited by Mule.

MIF Components

Definition

In MIF, a component is a well-defined architectural construct, as opposed to a general term used to refer to system elements.

A component wraps one or more modules to perform a given task and represents the largest unit of code re-usability in MIF. In a sense, a component is like a mini-pipeline in itself. Once a set of components has been created, the end user (e.g., a domain expert) can arrange the components to form a distributed application. The end user is not aware of the modules that are internal to the component. In Service Oriented Architecture (SOA), this process of manipulating a set of pre-existing high level constructs to form new applications is known as orchestration.

Component endpoints

Components are linked together to form a processing pipeline in a similar way as modules. The output of one component serves as the input for the next component in the pipeline. Components, like modules, use endpoints to connect to each other and communicate over various protocols. However, in the case of a component the inbound and outbound endpoints are set and modified by the end user, as opposed to the creator of the component. This allows for maximum flexibility: the same two components may be connected by a VM endpoint for one application and JMS for another application.

Component Endpoints

This means that components have two different types of endpoints: internal and external. Internal endpoints are set by the programmer who created the component and are not modifiable by the end user. External endpoints may be changed from application to application with respect to protocol and URI. The above diagram illustrates a MIF component and the difference between internal and external endpoints.

Adding a component to helloWorld

The helloComponent example demonstrates implementing the helloWorld example with a component. This example also uses JMS to communicate with the component in order to demonstrate using different endpoint types. The sample code for this example is included in $MIF_HOME/samples.

A JMS publisher program is used to publish a string (name) to a JMS topic which the HelloComponent is listening on. The HelloComponent uses two modules to build up the string as in the Hello World Example. The HelloComponent sends the final string to a JMS topic where a listener program is waiting to receive the string.

Diagram of HelloComponent Sample

The helloComponent example

Prerequisites

Running the example

This example requires you to start three processes: The JMS publisher, a JMS listener, and the MIF pipeline containing the HelloComponent. Follow these steps (Note: Only the Windows batch scripts are named, there are comparably named scripts for UNIX platforms). These instructions explain how to run the sample from the command line, the sample can also be run from Eclipse by finding the appropriate classes and choosing: “Run As –> Java Application”.

  • Open three shells and navigate to $MIF_HOME in each.
  • In the first shell window, start the MIF example by running
bin\run-mif.bat -c gov.pnnl.mif.samples.hello.component.HelloComponentDriver
  • In the second shell window, start the JMS listener
bin\run-mif.bat -c gov.pnnl.mif.samples.hello.component.Listener
  • In the third window, run the JMS publisher
bin\run-mif.bat -c gov.pnnl.mif.samples.hello.component.Publisher

The publisher will send the string “Dave” into HelloComponent. HelloComponent modifies the string twice (once per module) and sends it back to the listener. So, after running the publisher you should see the following in the MIF window as it logs what it is doing:

2007-09-10 16:57:48,845 INFO  [MifPipeline]  -- MeDICI has started --
HelloNameProcessor: Hey, Dave
HelloHalProcessor: Hey, Dave, what are you doing?

The listener should have received the final string and printed something similar to the following:

2007-09-10 17:01:02,403 INFO  [RunSift] -------------------------
2007-09-10 17:01:02,404 INFO  [RunSift] Running on command line: RunSift -g helloListener 
2007-09-10 17:01:02,404 INFO  [RunSift] -------------------------
Listener received: Hey, Dave, what are you doing?

Building a pipeline using a pre-existing component

First, we will take a look at the code needed to create a MIF pipeline using components. This is a task that can be performed by an end user who doesn't need to, or want to, understand the inner workings of the component.

First we create a pipeline object as in the hello world example.

MifPipeline pipeline = new MifPipeline();

Next, add a JMS connector, which allows us to use and configure JMS endpoints. We give the connector the address of our server (first argument) in the first argument and tell it to use the ActiveMQ server in the second.

pipeline.addMifJmsConnector("tcp://localhost:61616", JmsProvider.ACTIVEMQ);

Each endpoint type has its own connector, but most connectors are created automatically with a default configuration when you create an endpoint of a given type. So you usually don't need to create a connector unless you need special configuration. The exception to this is a JmsConnector which needs to be explicitly created so that the user can specify a URI where the JMS server is listening.

Next, create a new HelloWorldComponent and add it to the pipeline. The configuration of this component should be taken care of inside its respective class.

HelloWorldComponent hello = new HelloWorldComponent();
pipeline.addMifComponent(hello);

After the component has been created and added, set the inbound and outbound endpoints by specifying the type (JMS) and topic names.

hello.setInNameEndp("jms://topic:NameTopic")
hello.setOutHalEndp("jms://topic:HalTopic")

Finally, start the pipeline to begin receiving messages.

pipeline.start();

Creating the HelloWorldComponent

In the previous section we illustrated how to build a pipeline using an existing component. In this section we show how to create a MIF component. Basically, the modules used in the hello world example are re-used along with their implementation classes.

A component object is created by extending the java class AbstractMifComponent and implementing the configure() method. This method is responsible for creating and connecting all the modules required to implement the component and is called by MIF when the component is added to a pipeline. The following code snippet illustrates a fully functional MifComponent.

public class HelloWorldComponent extends AbstractMifComponent {
  
  public void configure(MifPipeline pipeline) throws MifException {
    pipeline.addMifModule(HelloNameProcessor.class.getName(), inNameEndp, "vm://hal.queue");
    pipeline.addMifModule(HelloHalProcessor.class.getName(), "vm://hal.queue", outHalEndp);
  }
   
  public void setInNameEndp(String inNameEndp) {
    this.inNameEndp = inNameEndp;
  }

  public void setOutHalEndp(String outHalEndp) {
    this.outHalEndp = outHalEndp;
  }
}

Note in the above code snippet that the inbound and outbound endpoints are retreived from the mapping using their tags.

Mule integration constructs

MIF takes advantage of Mule's integration constructs which are based in Enterprise Integration best practices. Mule concepts such as endpoints have already been introduced. Other important concepts are aggregators and transformers. Note that although the examples we have presented so far utilize only one inbound and one outbound endpoint per component, it is actually possible to have any number of endpoints in your modules and components.

Below is a representation of (almost) all the entities that can be combined to create a MIF Component.

MIF Entities

The new concepts in this diagram are:

  • Aggregator: Combines individual pieces of data into chunks depending on application-specific criteria. An aggregator is attached to the inbound data path on a module so that the data directed at a processing module are first processed by the aggregator. More details are contained in Using Aggregators.
  • Transformer: Object which converts from one data type to another. Zero or more transformers are attached to an endpoint, depending on the needs of the module. An example of creating a transformer can be found in Using Transformers.

Summary

This document has shown how to use components to create MIF applications. Mule aggregators, transformers, endpoints, and MIF modules are configured within MIF components to create complex applications from reusable software elements. In this example, we created the HelloComponent and added it to a MIF pipeline programmatically. It is also possible to instantiate components and create a processing pipeline using a configuration file. This is done by writing the Component as a Java Bean and launnching it by specifying a Spring configuration file.

 
base_component_model.txt · Last modified: 2010/05/19 14:05 by adamw