Connector generation demo – CPlayer

To show the importance of connectors in our component model and demonstrate how the generation of different connector types works we provide a simple demo application (depicted on figure 1). It consists of four components which together form a kind of player. There is a reading unit which read data, sends the sound stream to speaker and displays the current status (track, time, etc.) on display. The reading unit is controlled by a controller. There can be several displays and several controllers (e.g. local and remote).

Figure 1. CPlayer application structure

The connectors on the picture are drawn as arrows between components. Each arrow encapsulates an interaction which is suitable for the specific connection. Our demo application employs all three basic SOFA connectors (procedure call, messaging and pipe).

The basic concept of connectors seen from the component developer's side is described in user's manual. Further details concerning how the generation is implemented as well as threoretical foundations can be found in [trcon].

This document provides a brief overview of how to start the demo, and shows where are the connectors situated and how they are configured. As a convenience, the full source code of the demo is available bellow.

The full source code of the cplayer-demo as well as its ready-to-run compiled form is is available in the binary distribution of the SOFA implementation. After successful installation of the distribution, this application is immediately ready to run.

Steps for executing of the cplayer-demo

The commands used in the following text suppose that the bin directories of JDK and the SOFA distribution are included in the PATH environment variable. The executables in the bin directory of the SOFA distribution are written in the Perl; on UNIX-like machines it can be executed directly, on Windows machines it can be executed in the form perl nameOfTheScript argumentsOfTheScript ... - this way is presented in the following examples, it suppose the perl executable in your PATH variable and the bin directory of the SOFA distribution as your current working directory. If you are using the Active Perl distribution for Windows, you can use the program pl2bat to create batch files for launching perl scripts.

  1. Run rmiregistry.

    The rmiregistry is part of the JDK. It starts a remote object registry (for JAVA RMI) on the specified port on the current host. The registry default port is 1099 (the SOFA default configuration assume the port 2000). The rmiregistry command produces no output and is typically run in the background. The rmiregistry must not have the CLASSPATH environment variable set.

    Starting rmiregistry on UNIX-like machines:

    $ unset CLASSPATH
    $ rmiregistry 2000 &
    

    Starting rmiregistry on Windows machines:

    C:\> set CLASSPATH=
    C:\> start rmiregistry 2000
    

  2. Run orbd.

    The orbd is part of the JDK. It is used to enable clients to transparently locate and invoke objects on servers in the CORBA environment. You must provide the port number where the orbd will listen for incoming requests (the SOFA default configuration assume the port 2001). The orbd command produces no output and is typically run in the background.

    Starting orbd on UNIX-like machines:

    $ orbd -ORBInitialPort 2001 &
    

    Starting orbd on Windows machines:

    C:\> start orbd -ORBInitialPort 2001
    

  3. Run TIR.

    TIR (Type Information Repository) is part of the SOFA distribution. TIR serves as a storage for component's specifications. The command tir produce output with information about launching progress.

    Starting TIR on UNIX-like machines:

    $ tir &
    

    Starting TIR on Windows machines:

    C:\> start perl tir
    

  4. Run the deployment dock registry.

    The deployment dock registry is part of the SOFA distribution. It is used to enable locate the SOFA deployment docks. The produced output in the case of successful launching is DeplDockRegistry is running.

    Starting deployment dock registry on UNIX-like machines:

    $ ddockreg &
    

    Starting deployment dock registry on Windows machines:

    C:\> start perl ddockreg
    

  5. Run the deployment dock.

    The deployment dock is part of the SOFA distribution. It is the basic entity of SOFA runtime environment. The produced output in the case of successful launching is DeplDock NameOfDock is registered and running.

    Starting deployment dock on UNIX-like machines:

    $ ddock NameOfDock
    

    Starting deployment dock on Windows machines:

    C:\> perl ddock NameOfDock
    

  6. Generate the specfile for the application.

    On UNIX-like machines:

    $ genspecfile ::CUNI::SOFA::demos::cplayer::Main[0.0.1] nameOfGeneratedSpecFile
    

    On Windows machines:

    C:\> perl genspecfile ::CUNI::SOFA::demos::cplayer::Main[0.0.1] nameOfGeneratedSpecFile
    

    In the specfile, you can change the middleware used in the connector and/or specify, how the application should be distributed over the deployment docks. For now, do not change anything, i.e. the connector will be local and all components of the application will be launched in the single deployment dock.

    (Examples of specfiles: everything is local, the Display component in another dock and uses an RMI-based connector.)

    Note: If you set up the components to be launched in several docks, you must run all docks.

  7. Prepare application for launching.

    On UNIX-like machines:

    $ makeAppl nameOfGeneratedSpecFile.ssf
    

    On Windows machines:

    C:\> perl makeAppl nameOfGeneratedSpecFile.ssf
    

    You can see how the connector is generated.

    Loading EEG plugins:
      Loading plugin (SOFA.Connector.EEG.EEM.Maker):
        Loading Maker actions & elements:
          Action (SOFA.Connector.EEG.EEM.Actions.Install) loaded
    ...
    ...
          Action (SOFA.Connector.EEG.EEM.Actions.IDLIface) loaded
          Element description CRoleImpl (CRoleImpl.xml) loaded
    ...
    ...
          Element description DataStreamLocalReceiver (DataStreamLocalReceiver.xml) loaded
        Connecting to Connector Cache Name Server.
      Plugin EEM (SOFA.Connector.EEG.EEM.Maker) loaded.
    Loading ECG plugins:
      Loading plugin (SOFA.Connector.ECG.SGenerator.SGenerator):
        Loading connectors specification:
    ...
    ...
          Connector 'EventPassingImpl' (EventPassing)
            Unit 'Supplier'
              Element 'sRole' (SOFA.Connector.EEG.Types.CRole)
              Element 'sInterceptor' (SOFA.Connector.EEG.Types.Interceptor)
              Element 'distributor' (SOFA.Connector.EEG.Types.Distributor)
              Element 'stub' (SOFA.Connector.EEG.Types.Stub)
            Unit 'Consumer'
              Element 'cRole' (SOFA.Connector.EEG.Types.SRole)
              Element 'cInterceptor' (SOFA.Connector.EEG.Types.Interceptor)
              Element 'skeleton' (SOFA.Connector.EEG.Types.Skeleton)
    ...
    ...
      Plugin SGenerator (SOFA.Connector.ECG.SGenerator.SGenerator) loaded.
    
    Reading input descriptor for 'display' [Consumer] ... OK
    Generating connector 'SGenerator:EventPassingImpl':
      Generating element 'EEM:SRoleImpl'
      Generating element 'EEM:RMISkeleton'
    Connector generated.
    
    ...
    ...
    
    Reading input descriptor for 'display' [Supplier] ... OK
    Generating connector 'SGenerator:EventPassingImpl':
      Generating element 'EEM:CRoleImpl'
      Generating element 'EEM:DistributorImpl'
      Generating element 'EEM:RMIStub'
    Connector generated.
    

    First, the generator is initialized. The generator loads a description of all available connectors and internal elements (entities representing basic connector functinalities). Then it processes specfile and for each declared connector generates an implementation.

    A connector consists of several parts, depending on type of the connector. For example the EventDelivery connector has one Supplier part and several Consumer parts. The example above shows generation of both Consumer and Supplier part of the connector to the Display component.

  8. Run SOFA application (in this case application cplayer).

    The SOFA applications are launched by command lanchAppl, which is part of the SOFA distribution. It takes two arguments: 1st the full name of the application, 2nd name of the deployment dock in which the application should be launched. The command produce output with information about launching progress.

    Launching application on UNIX-like machines:

    $ launchAppl ::CUNI::SOFA::demos::cplayer::Main[0.0.1] NameOfDock
    

    Launching application on Windows machines:

    C:\> perl launchAppl ::CUNI::SOFA::demos::cplayer::Main[0.0.1] NameOfDock
    

Connector configuration

First of all when creating SOFA component application, the developer has to provide a CDL specification. For us, there is important that the specification also contains prescription how the components are connected together and what type of connector is used for the interconnection. That is described by a component or system architecture section. Following example was taken from cplayer.cdl.

system architecture CUNI ::SOFA::demos::cplayer::Main implements ::SOFA::libs::Application {

  inst ::SOFA::demos::cplayer::Display     display;
  inst ::SOFA::demos::cplayer::Controller  controller;
  inst ::SOFA::demos::cplayer::Speaker     speaker;
  inst ::SOFA::demos::cplayer::ReadingUnit readingUnit;

  bind controller:control to readingUnit:control using CSProcCall;
  bind readingUnit:display to display:display using EventPassing;
  bind readingUnit:audio to speaker:audio using DataStream;

};

In SOFA there are three basic types of connectors: CSProcCall (local/remote procedure call), EventDelivery (one way messaging), DataStream (unidirectional pipe). The example shows how they are used to interconnect different components. Additionaly to the basic connector types, there is possible to add new connector types if none of the basic connectors suits the requirements (see [trcon]).

Being the CDL specification finished, the cdl-tools (compiler and code generator) are used to create component interfaces and implementation skeletons. Bussiness logic is then added to the generated code. After compilation, the component implementations are imported into the Template Repository. (For further details see steps for creating a SOFA application.)

The connectors in SOFA are tailored to particular deployment dock and its underlying platform. Thus, they are configured and generated in deployment phase, when all the characteristics of the used deployment docks are known. This configuration is located in the specfile (the result of the 6th step). The following example shows the CPlayer demo with the Display component located in another deployment dock. RMI-based EventDelivery connector is used here to deliver messages to the remote Display component.

<?xml version="1.0" encoding="UTF-8"?>
<sofa_system name="Main">
     <architecture_ref>::CUNI::SOFA::demos::cplayer::Main?nenya.ms.mff.cuni.cz!0</architecture_ref>
     <frame_ref>::SOFA::libs::Application?nenya.ms.mff.cuni.cz!0</frame_ref>
     <version>0.0.1</version>
     <unit><location>sofa://LOCAL/SecondDock</location>
     <sofa_component name="display">

          <architecture_ref>::CUNI::SOFA::demos::cplayer::Display?nenya.ms.mff.cuni.cz!0</architecture_ref>
          <frame_ref>::SOFA::demos::cplayer::Display?nenya.ms.mff.cuni.cz!0</frame_ref>
          <version>0.0.1</version>
          <connector name="display" requires="::SOFA::demos::cplayer::DisplayInterface?nenya.ms.mff.cuni.cz!0" frame="SGenerator:EventPassingImpl">
               <transport type="RMI"/>
          </connector>
     </sofa_component>
     </unit>
     <sofa_component name="controller">
          <architecture_ref>::CUNI::SOFA::demos::cplayer::Controller?nenya.ms.mff.cuni.cz!0</architecture_ref>
          <frame_ref>::SOFA::demos::cplayer::Controller?nenya.ms.mff.cuni.cz!0</frame_ref>
          <version>0.0.1</version>
          <connector name="control" provides="::SOFA::demos::cplayer::ControlInterface?nenya.ms.mff.cuni.cz!0" frame="SGenerator:CSProcCallImpl">
               <transport type="LOCAL"/>
          </connector>
     </sofa_component>
     <sofa_component name="speaker">
          <architecture_ref>::CUNI::SOFA::demos::cplayer::Speaker?nenya.ms.mff.cuni.cz!0</architecture_ref>
          <frame_ref>::SOFA::demos::cplayer::Speaker?nenya.ms.mff.cuni.cz!0</frame_ref>
          <version>0.0.1</version>
          <connector name="audio" requires="::SOFA::Connector::EEG::Types::DataStream::OutputStream?nenya.ms.mff.cuni.cz!0" frame="SGenerator:DataStreamImpl">
               <transport type="LOCAL"/>
          </connector>
     </sofa_component>
     <sofa_component name="readingUnit">
          <architecture_ref>::CUNI::SOFA::demos::cplayer::ReadingUnit?nenya.ms.mff.cuni.cz!0</architecture_ref>
          <frame_ref>::SOFA::demos::cplayer::ReadingUnit?nenya.ms.mff.cuni.cz!0</frame_ref>
          <version>0.0.1</version>
          <connector name="control" requires="::SOFA::demos::cplayer::ControlInterface?nenya.ms.mff.cuni.cz!0" frame="SGenerator:CSProcCallImpl">
               <transport type="LOCAL"/>
          </connector>
          <connector name="audio" provides="::SOFA::Connector::EEG::Types::DataStream::OutputStream?nenya.ms.mff.cuni.cz!0" frame="SGenerator:DataStreamImpl">
               <transport type="LOCAL"/>
          </connector>
          <connector name="display" provides="::SOFA::demos::cplayer::DisplayInterface?nenya.ms.mff.cuni.cz!0" frame="SGenerator:EventPassingImpl">
               <transport type="RMI"/>
          </connector>
     </sofa_component>
</sofa_system>

Source code of the cplayer application

References

[trcon] Lubomir Bulej and Tomas Bures. A Connector Model Suitable for Automatic Generation of Connectors, Tech. Report, Dep. of SW Engineering, Charles University, Prague, Jan 2003

[CORBA] Object Management Group. The Common Object Request Broker: Architecture and Specification. version 3.0. document formal/02-06-33. 2002.

[EJB] Enterprise JavaBeans Specification. Version 2.0. Sun Microsystems. 2001.

[JOnAS] JOnAS. http://www.objectweb.org/jonas/index.html