Introduction
Components are software objects that provide implementations of a set
of standard behaviors. These behaviors are defined by the component
framework to ensure that components can be composed and interoperate
efficiently and without conflict. The framework that we have developed
conforms to the specification provided by the
CCA
Forum . The framework implementation uses
HPC++
as its runtime mechanism. We hereby explain the process of
"componentizing" (converting to a component) your code by means
of a simple example.
A Simple Example
I believe the best way to explain the CCAT component structure is by
way of a simple example. As I walk through the process of developing
this component, you will be introduced to some fundamental
concepts in component based distributed computing like ports ,
port-compatibility , naming , events ,
stubs and skeletons . Please make sure you understand these
before proceeding further. Lets assume you need to develop two
components: Newstring and Concat . As the names
suggest, Newstring component generates a new string and
Concat concatenates the strings that it receives. The aim of this
example is to develop these two into CCA compliant CCAT components so
that we can connect the two and steer the process of
string-generation and concatenation. In order to tie these two
components together we need to connect their
ports .
Ports
The Port is a fundamental CCA concept. A port represents the
connection endpoint for a component. Two ports that are
compatible can be connected
and serve as the communication channel between components.
A port could be either a provides port or a uses
port .
A provides port can be viewed as a service that is provided to
other components. A uses port can be thought of as a connection to
the surface of the component. To a component developer a uses port
provides the interface that the component wants to use.
Ports are specified in Interface Definition Language (IDL) . The
CCAT-team is working towards adopting the Scientific Interface
Definition Language (SIDL) for port specification.
IDL Specification
IDL is a high-level language used to specify the interfaces that a
component wants to expose to the outer world.
We now introduce you to the actual IDL specification that we need for the
NewString component. However to add an epsilon amount of complexity to
the example, our string churner spits out MyString object in each iteration
instead of just a string. MyString object holds some mundane information
apart from a character string, details of which aren't relevant to our purpose of
illustrating the componentizing process.
// File: MyString.idl
// This is a specification in IDL
// for the port of type MyString
interface MyString : Port {
int replyValue sendString(MyString myOwnString);
};
// End of file MyString.idl
Stub Compiler
The object oriented paradigm of the high performance class library, HPC++,
makes it ideal for use as the underlying run time system for our framework.
The remote method invocations need to be marshalled on the client side and
appropriately unmarshalled on the server side. The user should not be
bogged down by the low level details of the wire protocol and different run
time systems that (s)he plans to interact with. This motivated us to develop a
stub compiler that can parse the IDL specification as above and automatically
generate the necessary code to facilitate in the efficient use of the
elegant runtime system lying underneath the framework. A user may intend to
connect the ports of the NewString and
Concat components. We use HPC++ as the middleware to establish a
communication channel between these two components. Towards this goal,
stubs and skeletons need to be generated. The concept of stubs and skeletons
is endemic to the distributed computing community. It is a design mechanism
by which the low level details are hidden from an end user. The end user is
presented with a single interface for local and remote component instantiation.
However, please note that the stub compiler is *not* included with the CCAT
release. We are still working on it. As of now, these stubs and skeletons
need to be generated by hand. We are waiting for Livermore's CASC
SIDL to be released so that we can replace our IDL with it. Please continue to
monitor our CCAT web page to learn about latest developments on this
front.
The code to be generated by the stub compiler looks as follows:
// Do not modify. This file has been automatically
// generated from the IDL file MyString.idl
// File: MyString_idl.h
#ifndef _MY_STRING_IDL_H__
#define _MY_STRING_IDL_H__
#include "MyString.h"
#include "../InterfaceType.h"
class MyString_idl : public InterfaceType {
public:
virtual int sendMyString(MyString *myString) = 0;
};
#endif // _MY_STRING_IDL_H__
The complexity of the low level details are hidden in the following files
that are generated by the stub compiler:
- ProvidesMyString.h
- ProvidesMyStringSkel.h
- ProvidesMyStringSkel.C
- UsesMyString.h
- UsesMyStringSkel.h
- UsesMyStringSkel.C
- PORTS_REGISTRATION_ID.h
Port Compatibility
Two ports are said to be compatible if they are generated from the same
idl. The IDLs used by the CCAT are retrieved from a central database of
IDLs and as such are guaranteed to be unique across the CCAT users-community.
Parameter Ports
Ports are the traditional way of channeling data in the world of component
based computing. The CCAT design however believes in providing the user
additional tools to steer the computation. Parameter Ports are
designed as provides ports for components that need run time settings for
their computations. The CCAT composition gui component is equipped to detect
that a component needs parameter ports by parsing the XML specification for
the component. This composition engine generates a parameter gui for so
that a user can specify some parameters to model the computation according
to her needs. In our contrived NewString-Concat example, lets
assume that a user wants the Concat component to take in two
parameters, a long and a string . The long will specify the
number of times the concatenation needs to be done and the string
will be used to concatenate with the string generated by the NewString
component.
Since this parameter setting needs to be done via a port, it needs to be
specified in an IDL and the stub compiler has to be used to generate the
necessary code to glue it with the framework.
The IDL for the parameter port can be as follows:
// File: Concat.idl
// This is a specification in IDL
// for the port of type MyString
interface ConcatParms : Port {
int replyValue sendConcatParms(ConcatParms concatParms);
int start();
int stop();
int kill();
};
// End of file Concat.idl
The extra methods start , stop and kill seem to
imposing centralized control over the execution flow in CCAT. This notion
is partially true. CCAT doesn't impose this design but provides it as an
additional tool for use in some special cases. When an end user decides to
steer the computation in a different direction by providing some parameters
via the parameter port , CCAT sends a stop signal to the
component. The component is expected (not bound) to stop after its current
iteration on receiving this signal. CCAT then sends the new parameter
setting via the sendConcatParms remote method call. Once the data
structures of the component have been modified to the user's satisfaction,
a start signal is sent to the component to resume its
computation. The kill signal is used by the user when she
wants to free the resources held by the component.
- ConcatParms_idl.h
- ConcatParms.h
- ProvidesConcatParmsSkel.h
- ProvidesConcatParmsSkel.C
- UsesConcatParms.h
- UsesConcatParmsSkel.h
- UsesConcatParmsSkel.C
- PORTS_REGISTRATION_ID.h
Component Initialization
Component Initialization is the process of initializing some data structures
so that a component can co-exist in peace with the other components in the
CCAT federation. Components are created using the singleton model from the
creational pattern school of design. Each component is provided with a home,
a concept inspired from EJB. We even provide each component with a thin
HPC++ wrapper so that it can be instantiated via gram .
Code in the following files explains the process of initialization for the
Concat Component. Since these files are expected to be generated by the
stub compiler, the code for the NewString component can be
developed similarly.
- ConcatComponentHome.h
- ConcatComponentHome.C
- ConcatServer.C
Component Interface Implementatation
Since the stubs and skeletons handle all the communication and framework
details, the component developers are expected to abide by a strict
inheritance pattern in their code so as to be able to receive method
invocations from remote processes. The following files provide the
template that component developers must follow in order to be
CCAT compliant. Please mark the comments (yes ! in a stunning display of
software engineering, I have included some documentation here) or else you
will greeted by core dumps at the time of execution.
- ConcatComponent.h
- ConcatComponent.C
Provides Port Implementatation
The end user is supposed to provide an implementation of the provides port
that (s)he registered in the setServices() method while
implementing the component interface implementation. The inheritance
structure *has* to conform to what the CCAT stubs and skeletons expect as
illustrated in the code presented in the following files:
- MyString_impl.h
- MyString_impl.C
- ConcatParms_impl.h
- ConcatParms_impl.C
Uses Port Interface Implementatation
The CCA design mandates that the framework manufacture the uses port for
all the IDL specifications presented by the user. The user is provided with
a handle to the uses port implementation whenever he asks for it.
// Typically the NewSystem component upon generation of a
// new string will propagate it to the Concat component
// via its uses port for MyString_idl
// UsesMyString: type of the output port
// m_core: pointer to the services object
// "outputMyString": name given to the port in registerUsesPort() call
UsesMyString *up = dynamic_cast(m_core->getPort("outputMyString"));
up->sendMyString(pointerToNewString);
m_core->releasePort("outputMyString");
Flow of Control
The CCA specification does not specify the flow of control of the system of
connected components. CCAT provides the user with an option of starting,
stopping and killing components via the parameter ports. This, we belive,
will be the most common way to kick off any execution cycle.
XML specification
The components are described using XML technology. We provide the XML
description for NewString and Concat as examples. These XMLs conform to
this DTD .
- XML for Concat
- XML for NewString
Incorporating into CCAT
All these new files that we have talked about so far need to be placed into
specific places in the CCAT hierarchy.
(More details on this soon).
Installing components
(More details on this soon)
mgovinda@cs.indiana.edu
Last modified: Wed Jan 26 20:08:21 EST 2000