Skip to Main Content U.S. Department of Energy

MIF Hello World

The helloWorld sample demonstrates a simple two module pipeline. In subsequent samples, we demonstrate more complex pipelines. Before starting, please review the sample code prerequisites.

The following describes:

  1. An overview of the helloWorld sample included with MIF.
  2. How to run the helloWorld sample.
  3. A walkthrough of the code used to construct this sample.

Overview of helloWorld

Basic Definitions

Here are some basic definitions of MIF concepts needed to understand this example. More detailed descriptions can be found in the Base Component Model.

  • Pipeline: A MeDICI application consists of a series of processing modules contained in a processing pipeline. The MifPipeline object is used to control the state of the pipeline as well as to add and register all objects contained in the pipeline.
  • Implementation code: This is the code (e.g., a java class or C program) which performs the actual processing at a given step.
  • Module: Wraps the functionality of implementation code.
  • Endpoint: Connects a module to other modules in the pipeline by using one of several standard communication protocols.

Description

When the pipeline starts, the user is prompted to enter a name. The name is sent to the helloNameModule which calls the helloNameProcessor implementation to add “Hey” to the front of the string, then passes the whole string to the helloHalModule which calls the helloHalProcessor to add “what are you doing” to the end of the string, which is returned to the user via the console.

In this diagram, the blue rectangles are modules and the black squares are endpoints. The path of data is represented by blue dotted lines, which are annotated with the data strings that are passed between each step.

Diagram of Hello World Sample

Running helloWorld

This (and all other) samples can be run from your IDE or from the command line. We provide an example of each below, using Eclipse for the IDE environment.

From the command line

Note: MIF_HOME refers to the MIF installation directory

Follow these steps:

  • Open a console, navigate to MIF_HOME
  • Execute the following (the -c option means run the specified class)
bin/mif.sh -c gov.pnnl.mif.samples.hello.stdio.HelloStdioDriver

From Eclipse

  • Locate the following class, right click on it, then choose “Run as –> Java Application”
gov.pnnl.mif.samples.hello.stdio.HelloStdioDriver

Program output

MeDICI has fully started when the console displays something similar to:

2010-05-19 16:13:28,750 INFO  [MifManagerImpl]  -- MIF has started --
enter name:

Enter a name when prompted and press return. The console output will then look like:

Enter name:Dave
HelloNameProcessor: Hey, Dave
HelloHalProcessor: Hey, Dave, what are you doing?
Hey, Dave, what are you doing?

Code Walkthrough

Getting The Sample Code

The code used to create this sample can be found online and in your MIF installation in MIF_HOME/sources/mif-samples. The following code snippets demonstrate the pertinent portions of the code. The code is presented in a “top-down” manner where we present the higher level code first and move progressively down to the implementation details.

You can work with the samples by running them from the command line or by importing them into into a project in your IDE, such as Eclipse.

Create the Pipeline Object

First, we need to create a MifPipeline object which is needed to start and stop the processing pipeline. This object is also used to create and register all the objects that run within the pipeline.

MifPipeline pipeline = new MifPipeline();

Create the Modules

Next, add the HelloNameModule which prepends “Hello” to the entered name, and sends the new string to the next processing module. The first argument is a string representing the full class name of the implementation class. The second and third arguments are the the inbound and outbound endpoints which allow our HelloNameModule to receive and send data.

pipeline.addMifModule(HelloNameProcessor.class.getName(), "stdio://stdin?promptMessage=enter name: ", "vm://hal.queue");

Lastly, we add the HelloHalModule (and its endpoints). This calls the HelloHalProcessor to add another sentence fragment on the end of the string and prints it to the user's console.

pipeline.addMifModule(HelloHalProcessor.class.getName(), "vm://hal.queue", "stdio://stdout");

Endpoints

This is a brief introduction to endpoints. For a full explanation of endpoints, see the page on Transports and Endpoints

Endpoints are an abstraction which enable the communication protocols between modules to be swapped in and out. This allows the implementation logic encapsulated by a module to not have to worry about how to “talk” to each other. In fact, a module may be communicating over JMS now, then be changed to send data over UDP without any change to the module's implementation code.

In this example, the HelloNameModule's inbound endpoint, “stdio://stdin”, reads user input from the console. That is, “stdio” is a special protocol that reads from and outputs data to the console. The outbound endpoint, “vm://hal.queue”, uses the virtual machine to call the next module's service method. Note that the modules are able to communicate because the outbound endpoint of the first matches the inbound endpoint of the second.

Start the application

We start the application by calling the method MifPipeline.start(). This starts MIF with the pipeline configuration we provided and starts it's modules listening for data.

pipeline.start();

Implementation code

Implementation code is written by the user to perform some kind of processing on the data flowing through a pipeline. This code is then wrapped by a module to form the smallest unit which may be placed into a pipeline. Implementation code can be written in Java or any other language. When using Java, the code is integrated directly into the pipeline while it is treated as an external executable for other languages. For now, we will concentrate on creating Java implementation classes. Implementation code created in other languages is covered in the programmer's guide under “Remote Modules and Components”.

Java implementation classes

Implementation classes can become part of a pipeline by implementing the interface MifProcessor. These classes must implement a listen method with the following signature:

public Serializable listen(Serializable input);

This method is called when a message arrives for the module the implementation class is wrapped by. So, the input argument is the data received from the previous module in the pipeline and the return value is the message which is send to the next module in the pipeline. Once such an implementation class is added to the pipeline, a check is made to ensure that it implements the appropriate interface.

Implementation classes for helloWorld example

Now let's take a look at the implementation of one of the modules from this example. The HelloNameProcessor implements the functionality for the HelloNameModule. When this module receives data, its listen() method is called, and the data is passed in as the method argument. The method then processes the data in some way, then returns the result, which is passed on to the next module in the pipeline. In this case, the listen method simply adds the string “Hey” to the front of the received string and returns the new string.

public class HelloNameProcessor implements MifProcessor {

  public Serializable listen(Serializable name) {
    String str = "Hey, " + name;
    System.out.println("HelloNameProcessor: " + str);
    return str;
  }     
}
 
hello_world_example.txt · Last modified: 2010/06/01 11:33 by adamw