Chapter 3. GCM Components Tutorial

3.1. Introduction

This chapter presents a short user guide which explains how to use the ProActive/GCM implementation. It is composed of two parts: the first one shows how to use components with ADL files and the second one describes how to use them in a programmatic way. If you want more information about GCM Components, please refer to Part II, “Programming With Components”.

As in the active object tutorial, ProActive provides you with an empty tutorial which enables you to fill in code sources and test them easily. To build the tutorial directory, go to the ProActive/compile directory and type:

build tutorials

This command will create a new directory in the ProActive home directory, called tutorials. This directory will be composed of four sub-directories:

  • src - source directory. You will find in this directory all sources to fill in.

  • compile - compilation directory. In this directory, you will be able to compile your code. Type build to know all the available targets. Normally, you will see one target per tutorial example. Targets will be described after each example throughout this chapter.

  • scripts - launch scripts directory. You will find in this directory all scripts to launch your compiled code. Scripts will be described after each example throughout this chapter.

  • dist - library directory. You will find in this directory all libraries needed to compile your code. Normally, you will not have to deal with this directory.

3.2. Create and use components using ADL

3.2.1. Introduction

This first part of the tutorial shows you how to use ADL files in order to construct GCM components. ADL stands for Architecture Description Language and it allows to describe a component assembly thought an XML file. This part is composed of five exercises:

  • Starter - this exercise make you create a simple primitive component called Slave

  • Composite - this exercise make you create a composite component composed of a Master and a Slave component.

  • Interfaces - this exercise make you modify the previous Slave component to have it implement two server interfaces.

  • Multicast - this exercise make you modify the previous Master component so as to have its client interface be a multicast interface binded to the server interface of two different Slave components.

  • Deployment - this exercise make you deploy your component on different nodes located in your local host.

3.2.2. Starter tutorial

3.2.2.1. Tutorial description

This tutorial explains how to create a simple component named Slave using ADL files. This component looks like that:

Slave component

Figure 3.1. Slave component


The interface used for this example is the following one:

package org.objectweb.proactive.examples.userguide.components.adl.starter;

import java.util.List;


/**
 * @author The ProActive Team
 */
public interface Itf1 {
    void compute(List<String> arg);
}

This interface defines a compute() method which is implemented in the following SlaveImpl class:

package org.objectweb.proactive.examples.userguide.components.adl.starter;

import java.util.List;

import org.objectweb.proactive.api.PAActiveObject;


/**
 * @author The ProActive Team
 */
public class SlaveImpl implements Itf1 {

    public void compute(List<String> arg) {
        String str = "\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this + "\n";
        str += "arg: ";
        for (int i = 0; i < arg.size(); i++) {
            str += arg.get(i);
            if (i + 1 < arg.size()) {
                str += " - ";
            }
        }
        System.err.println(str);
    }
}

In order to define the component, we need an ADL file which describes all the interfaces, the component content class as well as potential binding between interfaces. In that case, the file is very simple:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.starter.adl.Slave">
    <interface signature="org.objectweb.proactive.examples.userguide.components.adl.starter.Itf1" role="server" name="i1"/>

    <content class="org.objectweb.proactive.examples.userguide.components.adl.starter.SlaveImpl"/>

    <controller desc="primitive"/>
</definition>

With the interface tag, we can define components interfaces. In our case, there is only one interface whose signature is defined in org.objectweb.proactive.examples.userguide.components.adl.starter.Itf1, which is a server interface and whose name is i1. As for the content tag, it enables to define the component contents. Eventually, the controller tag indicates whether the component is a primitive component or a composite one (component composed of several components).

3.2.2.2. Proposed work

Now that we have created our Slave component, it still remain to instantiate it and to use it. That is our proposed work for this first exercise.

Here is the main class that we want you to fill in:

package org.objectweb.proactive.examples.userguide.components.adl.starter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.proactive.core.component.adl.FactoryFactory;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Get the Factory
        // TODO: Create Component
        // TODO: Start Component
        // TODO: Get the interface i1
        // TODO: Call the compute method
        // TODO: Stop Component

        System.exit(0);
    }
}

Thus, we propose you to:

  1. Get the factory using the org.objectweb.proactive.core.component.adl.FactoryFactory.getFactory() method.

  2. Create the Slave component using the newComponent method of the factory previously retrieved. You will need to put in parameters the name of your component definition (written in the ADL file) as well as a Map<String, Object> defining a context.

  3. Start the component using the GCM.getGCMLifeCycleController() method to get the life cycle controller of your component and then, using the startFc() on this controller, get your component started.

  4. Get the i1 interface using the getFcInterface() method on your component.

  5. Call the compute() method with the parameters you want

  6. Stop the component using a way quite similar to the one you proceed for starting it.

3.2.2.3. Test your work

To build your work, go to the compile directory into the tutorials directory (not the one located into the ProActive directory) and type:

build components.adl.starter

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the adl-starter.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node494021116Slave: org.objectweb.proactive.examples.userguide.components.adl.starter.SlaveImpl@15fa713
arg: hello - bye

3.2.2.4. Solutions and full code

Here is how you should have filled in the main() method:

package org.objectweb.proactive.examples.userguide.components.adl.starter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.proactive.core.component.adl.FactoryFactory;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Get the Factory
        Factory factory = FactoryFactory.getFactory();
        // TODO: Create Component
        Map<String, Object> context = new HashMap<String, Object>();
        Component slave = (Component) factory.newComponent(
                "org.objectweb.proactive.examples.userguide.components.adl.starter.adl.Slave", context);
        // TODO: Start Component
        GCM.getGCMLifeCycleController(slave).startFc();
        // TODO: Get the interface i1
        Itf1 itf1 = (Itf1) slave.getFcInterface("i1");
        // TODO: Call the compute method
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        itf1.compute(arg);
        // TODO: Stop Component
        GCM.getGCMLifeCycleController(slave).stopFc();

        System.exit(0);
    }
}

3.2.3. Composite tutorial

3.2.3.1. Tutorial description

This tutorial shows how to create a composite component composed of a Master and a Slave component. This tutorials aims at making you manipulate ADL files. Java sources are filled in but they will be explain to you however. These explanations will be useful for the next tutorials.

This composite can be represented as follows:

Composite component

Figure 3.2. Composite component


The Slave component is exactly the same as in the previous tutorial. It is defined by the Itf1 interface implemented by the SlaveImpl class and the corresponding ADL file is Slave.fractal.

Concerning the Master component, it is defined by the following Runner interface:

package org.objectweb.proactive.examples.userguide.components.adl.composite;

import java.util.List;


/**
 * @author The ProActive Team
 */
public interface Runner {
    public void run(List<String> arg);
}

which is implemented by the MasterImpl class:

package org.objectweb.proactive.examples.userguide.components.adl.composite;

import java.util.List;

import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;


/**
 * @author The ProActive Team
 */
public class MasterImpl implements Runner, BindingController {
    public static String ITF_CLIENT = "i1";
    private Itf1 i1;

    public void run(List<String> arg) {
        i1.compute(arg);
    }

    public void bindFc(String clientItfName, Object serverItf) throws NoSuchInterfaceException,
            IllegalBindingException, IllegalLifeCycleException {
        if (ITF_CLIENT.equals(clientItfName)) {
            i1 = (Itf1) serverItf;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public String[] listFc() {
        return new String[] { ITF_CLIENT };
    }

    public Object lookupFc(String clientItfName) throws NoSuchInterfaceException {
        if (ITF_CLIENT.equals(clientItfName)) {
            return i1;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public void unbindFc(String clientItfName) throws NoSuchInterfaceException, IllegalBindingException,
            IllegalLifeCycleException {
        if (ITF_CLIENT.equals(clientItfName)) {
            i1 = null;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

}

This class contains an Itf1 member representing the client interface which is used in the BindingController method. These methods are:

  • bindFc() - used to bind interfaces

  • listFc() - used to list interfaces

  • lookupFc() - used to get one of the available interfaces using its name

  • unbindFc() - used to unbind interfaces

The ADL file corresponding to this component is the Master.fractal file which is almost empty since it will be one of your work.

The only things that remain to do now so as to be able to use our composite component are first, to define that composite with an ADL file and then to write our main method to use it. The writing of the composite ADL file is the second work you have to do and the main method, which is quite similar to the one you have written in the previous tutorial, is exposed hereafter.

package org.objectweb.proactive.examples.userguide.components.adl.composite;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.proactive.core.component.adl.FactoryFactory;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {
        Factory factory = FactoryFactory.getFactory();

        Map<String, Object> context = new HashMap<String, Object>();
        Component composite = (Component) factory.newComponent(
                "org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Composite", context);

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

You can notice that the only thing that changed is the first argument of the newComponent() method which is now the name of the ADL file representing the composite component.

3.2.3.2. Proposed work

Here are the two ADL files that you have to fill in:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<!-- TODO: Write the Master Component definition -->
<!-- This Component has 2 interfaces: -->
<!-- Server: org.objectweb.proactive.examples.userguide.components.adl.composite.Runner -->
<!-- Client: org.objectweb.proactive.examples.userguide.components.adl.composite.Itf1 -->
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.composite.Runner" role="server" name="runner"/>

  <!-- TODO: Add the Master Component -->
  <component name="Slave" definition="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Slave"/>

  <!-- TODO: Do the bindings -->

  <!-- TODO: Indicates that this component is a composite component -->
</definition>

We propose you to:

  1. Write the definition of the Master ADL file. Hint: draw your inspiration from the Slave ADL file.

  2. In the Composite ADL file, define the Master component

  3. Write the bindings. There are two bindings: one for the runner interfaces and another one for the i1 interfaces. Hint: use the <binding client="..." server="..."> tag.

  4. Add the controller tag to indicate the type of component

3.2.3.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.adl.composite

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the adl-composite.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node82553583Slave: org.objectweb.proactive.examples.userguide.components.adl.composite.SlaveImpl@50078e
arg: hello - world

3.2.3.4. Solutions and full code

Here is how you should have filled in the two ADL files:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<!-- TODO: Write the Master Component definition -->
<!-- This Component has 2 interfaces: -->
<!-- Server: org.objectweb.proactive.examples.userguide.components.adl.composite.Runner -->
<!-- Client: org.objectweb.proactive.examples.userguide.components.adl.composite.Itf1 -->
<definition name="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Master">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.composite.Runner" role="server" name="runner"/>
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.composite.Itf1" role="client" name="i1"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.composite.MasterImpl"/>

  <controller desc="primitive"/>
</definition>
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.composite.Runner" role="server" name="runner"/>

  <!-- TODO: Add the Master Component -->
  <component name="Master" definition="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Master"/>
  <component name="Slave" definition="org.objectweb.proactive.examples.userguide.components.adl.composite.adl.Slave"/>

  <!-- TODO: Do the bindings -->
  <binding client="this.runner" server="Master.runner"/>
  <binding client="Master.i1" server="Slave.i1"/>

  <!-- TODO: Indicates that this component is a composite component -->
  <controller desc="composite"/>
</definition>

3.2.4. Interface tutorial

3.2.4.1. Tutorial description

In this tutorial, we will add a new server interface to the Slave component and bind it to a new client interface of the master component. Our composite component will therefore look like as follows:

Composite component with the new interface

Figure 3.3. Composite component with the new interface


We introduce a second interface named Itf2 which source code is the following one:

package org.objectweb.proactive.examples.userguide.components.adl.interfaces;

/**
 * @author The ProActive Team
 */
public interface Itf2 {
    void doNothing();
}

The aim of this tutorial is to make you modify all the necessary files to add this new interface.

3.2.4.2. Proposed work

The first thing to do when adding a new interface is to implement it. In our case, it is SlaveImpl class that implements it:

package org.objectweb.proactive.examples.userguide.components.adl.interfaces;

import java.util.List;

import org.objectweb.proactive.api.PAActiveObject;


/**
 * @author The ProActive Team
 */
public class SlaveImpl implements Itf1
//TODO: Add the new interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2
{

    public void compute(List<String> arg) {
        String str = "\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this + "\n";
        str += "arg: ";
        for (int i = 0; i < arg.size(); i++) {
            str += arg.get(i);
            if (i + 1 < arg.size()) {
                str += " - ";
            }
        }
        System.err.println(str);
    }

    public void doNothing() {
        System.err.println("\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this +
            "\nI do nothing");
    }
}

Then, you have to modify the ADL file of the Slave component to add this new interface:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Slave">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf1" role="server" name="i1"/>
  <!-- TODO: Add the server interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2 -->

  <content class="org.objectweb.proactive.examples.userguide.components.adl.interfaces.SlaveImpl"/>

  <controller desc="primitive"/>
</definition>

Now, you have to do the same thing for the Master component, that is, you have to add a new interface. However, in that case, you have to add a client interface and thus, you have to modify the BindingController methods:

package org.objectweb.proactive.examples.userguide.components.adl.interfaces;

import java.util.List;

import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;


/**
 * @author The ProActive Team
 */
public class MasterImpl implements Runner, BindingController {
    public static String ITF_CLIENT_1 = "i1";
    public static String ITF_CLIENT_2 = "i2";
    private Itf1 i1;
    private Itf2 i2;

    public void run(List<String> arg) {
        i1.compute(arg);
        i2.doNothing();
    }

    public void bindFc(String clientItfName, Object serverItf) throws NoSuchInterfaceException,
            IllegalBindingException, IllegalLifeCycleException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            i1 = (Itf1) serverItf;
        }
        // TODO: Bind the new client interface
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public String[] listFc() {
        return new String[] { ITF_CLIENT_1
        //TODO: Add the new client interface name
        };
    }

    public Object lookupFc(String clientItfName) throws NoSuchInterfaceException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            return i1;
        }
        // TODO: Return the interface to which the new client interface is bound
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public void unbindFc(String clientItfName) throws NoSuchInterfaceException, IllegalBindingException,
            IllegalLifeCycleException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            i1 = null;
        }
        // TODO: Unbind the new client interface
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }
}

Then, Master's ADL file needs also to be modified:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Master">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Runner" role="server" name="runner"/>
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf1" role="client" name="i1"/>
  <!-- TODO: Add the new client interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2 -->

  <content class="org.objectweb.proactive.examples.userguide.components.adl.interfaces.MasterImpl"/>

  <controller desc="primitive"/>
</definition>

Finally, you have to add a binding in the Composite's ADL file:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Runner" role="server" name="runner"/>

  <component name="Master" definition="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Master"/>
  <component name="Slave" definition="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Slave"/>

  <binding client="this.runner" server="Master.runner"/>
  <binding client="Master.i1" server="Slave.i1"/>
  <!-- TODO: Do the binding for the new interface -->

  <controller desc="composite"/>
</definition>

Thus, we propose you to:

  1. Make the SlaveImpl class implement the Itf2 interface

  2. Modify the Slave's ADL file to add the new interface

  3. Modify method implementation of the BindingController methods in the MasterImpl class

  4. Modify the Master's ADL file to add the new interface

  5. Modify the Composite's ADL file to add a binding between the two new interfaces

3.2.4.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.adl.interfaces

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the adl-interfaces.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node438557290Slave: org.objectweb.proactive.examples.userguide.components.adl.interfaces.SlaveImpl@97aaa6
arg: hello - world

rmi://kisscool.inria.fr:6618/Node438557290Slave: org.objectweb.proactive.examples.userguide.components.adl.interfaces.SlaveImpl@97aaa6
I do nothing

3.2.4.4. Solutions and full code

Here is the solution:

package org.objectweb.proactive.examples.userguide.components.adl.interfaces;

import java.util.List;

import org.objectweb.proactive.api.PAActiveObject;


/**
 * @author The ProActive Team
 */
public class SlaveImpl implements Itf1
//TODO: Add the new interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2
        , Itf2
{

    public void compute(List<String> arg) {
        String str = "\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this + "\n";
        str += "arg: ";
        for (int i = 0; i < arg.size(); i++) {
            str += arg.get(i);
            if (i + 1 < arg.size()) {
                str += " - ";
            }
        }
        System.err.println(str);
    }

    public void doNothing() {
        System.err.println("\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this +
            "\nI do nothing");
    }
}
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Slave">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf1" role="server" name="i1"/>
  <!-- TODO: Add the server interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2 -->
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2" role="server" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.interfaces.SlaveImpl"/>

  <controller desc="primitive"/>
</definition>
package org.objectweb.proactive.examples.userguide.components.adl.interfaces;

import java.util.List;

import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;


/**
 * @author The ProActive Team
 */
public class MasterImpl implements Runner, BindingController {
    public static String ITF_CLIENT_1 = "i1";
    public static String ITF_CLIENT_2 = "i2";
    private Itf1 i1;
    private Itf2 i2;

    public void run(List<String> arg) {
        i1.compute(arg);
        i2.doNothing();
    }

    public void bindFc(String clientItfName, Object serverItf) throws NoSuchInterfaceException,
            IllegalBindingException, IllegalLifeCycleException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            i1 = (Itf1) serverItf;
        }
        // TODO: Bind the new client interface
        else if (ITF_CLIENT_2.equals(clientItfName)) {
            i2 = (Itf2) serverItf;
        }
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public String[] listFc() {
        return new String[] { ITF_CLIENT_1
        //TODO: Add the new client interface name
                , ITF_CLIENT_2
        };
    }

    public Object lookupFc(String clientItfName) throws NoSuchInterfaceException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            return i1;
        }
        // TODO: Return the interface to which the new client interface is bound
        else if (ITF_CLIENT_2.equals(clientItfName)) {
            return i2;
        }
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public void unbindFc(String clientItfName) throws NoSuchInterfaceException, IllegalBindingException,
            IllegalLifeCycleException {
        if (ITF_CLIENT_1.equals(clientItfName)) {
            i1 = null;
        }
        // TODO: Unbind the new client interface
        else if (ITF_CLIENT_2.equals(clientItfName)) {
            i2 = null;
        }
        else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }
}
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Master">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Runner" role="server" name="runner"/>
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf1" role="client" name="i1"/>
  <!-- TODO: Add the new client interface org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2 -->
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Itf2" role="client" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.interfaces.MasterImpl"/>

  <controller desc="primitive"/>
</definition>
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.interfaces.Runner" role="server" name="runner"/>

  <component name="Master" definition="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Master"/>
  <component name="Slave" definition="org.objectweb.proactive.examples.userguide.components.adl.interfaces.adl.Slave"/>

  <binding client="this.runner" server="Master.runner"/>
  <binding client="Master.i1" server="Slave.i1"/>
  <!-- TODO: Do the binding for the new interface -->
  <binding client="Master.i2" server="Slave.i2"/>

  <controller desc="composite"/>
</definition>

3.2.5. Multicast tutorial

3.2.5.1. Tutorial description

This tutorial will explain you how to create a multicast interface in order to get a component looking like this:

Composite component with a multicast client interface

Figure 3.4. Composite component with a multicast client interface


For this, a new interface called Itf1Multicast will be added and will be used for the client interface of the Master component.

package org.objectweb.proactive.examples.userguide.components.adl.multicast;

import java.util.List;


/**
 * @author The ProActive Team
 */
public interface Itf1Multicast {
    // Optional TODO: Change the dispatch parameters policy to Round Robin
    void compute(List<String> arg);
}

Except this new interface and the replacement of

private Itf1 i1

by

private Itf1Multicast i1

in the MasterImpl class, there is no need of changes in Java code source. Only changes in ADL files are needed.

3.2.5.2. Proposed work

First, you have to change the client interface into the Master's ADL file in order to refer to the Itf1Multicast signature. You also have to change its cardinality to indicate that this interface is now a multicast interface.

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Master">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Runner" role="server" name="runner"/>

  <!-- TODO: Add the client multicast interface org.objectweb.proactive.examples.userguide.components.adl.multicast.Itf1Multicast -->
  <!-- Note: do not forget to set its cardinality -->

  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Itf2" role="client" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.multicast.MasterImpl"/>

  <controller desc="primitive"/>
</definition>

Then, you have to modify the Composite's ADL file to add a new Slave component and to add also some bindings.

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Runner" role="server" name="runner"/>

  <component name="Master" definition="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Master"/>
  <component name="Slave1" definition="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Slave"/>

  <!-- TODO: Add a second Slave Component -->

  <binding client="this.runner" server="Master.runner"/>

  <!-- TODO: Do the binding between the Master Component and the Slave Components on the Multicast Interface -->

  <binding client="Master.i2" server="Slave1.i2"/>

  <controller desc="composite"/>
</definition>

Thus, we propose you to:

  1. Modify the client interface of the Master component

  2. Add a Slave component into the composite

  3. Add bindings to realise the multicast

  4. Optional: Change the dispatch parameter policy in the multicast interface to round robin dispatch mode

3.2.5.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.adl.multicast

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the adl-interfaces.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node1434753324Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@3861e6
arg: hello - world

rmi://kisscool.inria.fr:6618/Node1434753324Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@1132e76
arg: hello - world

rmi://kisscool.inria.fr:6618/Node1434753324Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@3861e6
I do nothing

If you have done the optional work, you should have a display as follows:

rmi://kisscool.inria.fr:6618/Node1653076599Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@789d63
arg: hello

rmi://kisscool.inria.fr:6618/Node1653076599Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@a4ed99
arg: world

rmi://kisscool.inria.fr:6618/Node1653076599Slave: org.objectweb.proactive.examples.userguide.components.adl.multicast.SlaveImpl@789d63
I do nothing
         

3.2.5.4. Solutions and full code

Here are solutions for the ADL files:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Master">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Runner" role="server" name="runner"/>

  <!-- TODO: Add the client multicast interface org.objectweb.proactive.examples.userguide.components.adl.multicast.Itf1Multicast -->
  <!-- Note: do not forget to set its cardinality -->
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Itf1Multicast" role="client" name="i1" cardinality="multicast"/>

  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Itf2" role="client" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.multicast.MasterImpl"/>

  <controller desc="primitive"/>
</definition>
<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Composite">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.multicast.Runner" role="server" name="runner"/>

  <component name="Master" definition="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Master"/>
  <component name="Slave1" definition="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Slave"/>

  <!-- TODO: Add a second Slave Component -->
  <component name="Slave2" definition="org.objectweb.proactive.examples.userguide.components.adl.multicast.adl.Slave"/>

  <binding client="this.runner" server="Master.runner"/>

  <!-- TODO: Do the binding between the Master Component and the Slave Components on the Multicast Interface -->
  <binding client="Master.i1" server="Slave1.i1"/>
  <binding client="Master.i1" server="Slave2.i1"/>

  <binding client="Master.i2" server="Slave1.i2"/>

  <controller desc="composite"/>
</definition>

If you do not want to do the optional work, you do not have to modify other files. Otherwise, if you want to change the dispatch parameter policy, you have to make some little modification in Java code sources. The first one is to change the signature of the compute method in the Itf1Multicast interface. Change the line

void compute(List<String> arg);

by

void compute(@ParamDispatchMetadata(mode = ParamDispatchMode.ROUND_ROBIN) List<String> arg);

Then, you have to change the Itf1 interface since the server interface will no longer receive a list of String but instead, just a String. Thus, in the Itf1 interface, change the line

void compute(List<String> arg);

by

void compute(String arg);

and in the SlaveImpl class, change the implementation of compute so that it returns a String:

public void compute(String arg) {
   String str = "\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this + "\n";
   str += "arg: " + arg;
   System.err.println(str);
}

3.2.6. Deployment tutorial

3.2.6.1. Tutorial description

Now that we know how to use component, we would like to benefit from active object properties. One of these is the deployment on several Java Virtual Machines (JVM). This tutorial will explain you how to deploy our component on 3 differents JVM. For this, we will use GCM deployment model. If you have done the active object tutorials, you should know what this model is and how to use it. If not, please refer to Chapter 21. ProActive Grid Component Model Deployment.

For the deployment, we will use the following application description:

<GCMApplication xmlns="urn:gcm:application:1.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www-sop.inria.fr/oasis/ProActive/schemas http://proactive.inria.fr/schemas/gcm/1.0/ApplicationDescriptorSchema.xsd">

    <environment>
        <javaPropertyVariable name="user.home" />
        <javaPropertyVariable name="user.name" />
        <javaPropertyVariable name="java.home" />
        <javaPropertyVariable name="proactive.home" />
    </environment>

    <application>
        <proactive base="root" relpath="${proactive.home}">
            <configuration>
                <java base="root" relpath="${java.home}/bin/java" />
                <applicationClasspath>
                    <pathElement base="root" relpath="${proactive.home}/classes" />
                </applicationClasspath>
            </configuration>
            <virtualNode id="master-node" capacity="1">
                <nodeProvider refid="MASTER_REMOTE_PROVIDER" />
            </virtualNode>
            <virtualNode id="slave-node" capacity="2">
                <nodeProvider refid="SLAVE_REMOTE_PROVIDER" />
            </virtualNode>
        </proactive>
    </application>

    <resources>
        <nodeProvider id="MASTER_REMOTE_PROVIDER">
            <file path="GCMD_Local.xml" />
        </nodeProvider>
        <nodeProvider id="SLAVE_REMOTE_PROVIDER">
            <file path="GCMD_Local.xml" />
        </nodeProvider>
    </resources>
</GCMApplication>

which refers to the following deployment descriptor, used both for the deployment of the Master component and for the Slave components:

<GCMDeployment xmlns="urn:gcm:deployment:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:gcm:deployment:1.0 http://proactive.inria.fr/schemas/gcm/1.0/ExtensionSchemas.xsd">

    <environment>
        <javaPropertyVariable name="user.home" />
        <javaPropertyVariable name="user.name" />
        <javaPropertyDescriptorDefault name="os" value="windows" />
    </environment>

    <resources>
        <host refid="hLocalhost" />
    </resources>

    <infrastructure>

        <hosts>
            <host id="hLocalhost" os="${os}" hostCapacity="3" vmCapacity="1">
                <homeDirectory base="root" relpath="${user.home}" />
            </host>

        </hosts>

    </infrastructure>
</GCMDeployment>

The main things that change comparing to the previous tutorial are the Main method where deployment has to be loaded and used, and ADL files into which virtual node of the corresponding component deployment has to be added.

3.2.6.2. Proposed work

First, you have to add a virtual-node tag into the Slave's ADL file to indicate where to deploy the Slave components:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.deployment.adl.Slave">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.deployment.Itf1" role="server" name="i1"/>
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.deployment.Itf2" role="server" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.deployment.SlaveImpl"/>

  <controller desc="primitive"/>

  <!-- TODO: Affect this Component to the virtual node "slave-node" -->
</definition>

Then, you have to modify the Main method so as to load and use the application descriptor.

package org.objectweb.proactive.examples.userguide.components.adl.deployment;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.proactive.core.component.adl.FactoryFactory;
import org.objectweb.proactive.extensions.gcmdeployment.PAGCMDeployment;
import org.objectweb.proactive.gcmdeployment.GCMApplication;
import org.objectweb.proactive.gcmdeployment.GCMVirtualNode;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Load the Application Descriptor

        // TODO: Start the deployment

        Factory factory = FactoryFactory.getFactory();

        Map<String, Object> context = new HashMap<String, Object>();

        // TODO: Put the Application Descriptor in the context

        Component composite = (Component) factory
                .newComponent(
                        "org.objectweb.proactive.examples.userguide.components.adl.deployment.adl.Composite",
                        context);

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

Thus, we propose you to:

  1. Add a virtual-node tag in the Slave's ADL file. Hint: draw your inspiration on the Master's ADL file.

  2. Complete the Main method. Hint: Look at the deployment of active objects

3.2.6.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.adl.deployment

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the adl-deployment.[sh|bat] script. You should then see a display looking like this:

--- User Guide: ADL Deployment ---------------------------------------------
30447@kisscool - [INFO oactive.remoteobject] Remote Object Factory provider <pamr, class org.objectweb.proactive.extra.messagerouting.remoteobject.MessageRoutingRemoteObjectFactory> found
30447@kisscool - [INFO    communication.rmi] Created a new registry on port 6618
30447@kisscool - [INFO        proactive.mop] Generating class : pa.stub.org.objectweb.proactive.gcmdeployment._StubGCMVirtualNode
30447@kisscool - [INFO        proactive.mop] Generating class : pa.stub.org.objectweb.lector -Djava.security.policy="/home/ffonteno/proactive-git/programming/tutorials/scripts/proactive.java.policy" org.objectweb.proactive.core.runtime.StartPARuntime -p rmi://kisscool.inria.fr:6618/PA_JVM798723297 -c 1 -i 1 -d 8194810407958514089 -b http://kisscool.inria.fr:49352/classServer/  '
30447@kisscool - [INFO                job.1] executing command=/usr/bin/ssh -l ffonteno localhost '"/home/ffonteno/src/java/jdk1.5.0_17/jre/bin/java" -cp "/home/ffonteno/proactive-git/programming/tutorials/dist/lib/ProActive.jar:/home/ffonteno/proactive-git/programming/tutorials/classes" -Dproactive.log4j.collector=rmi://kisscool.inria.fr:6618/8194810407958514089/logCollector -Djava.security.policy="/home/ffonteno/proactive-git/programming/tutorials/scripts/proactive.java.policy" org.objectweb.proactive.core.runtime.StartPARuntime -p rmi://kisscool.inria.fr:6618/PA_JVM798723297 -c 1 -i 1 -d 8194810407958514089 -b http://kisscool.inria.fr:49352/classServer/  '
30447@kisscool - [INFO      deployment.GCMD] Starting group id=gCluster #commands=1
30447@kisscool - [INFO                job.2] executing command=/usr/bin/ssh -l ffonteno localhost '"/home/ffonteno/src/java/jdk1.5.0_17/jre/bin/java" -cp "/home/ffonteno/proactive-git/programming/tutorials/dist/lib/ProActive.jar:/home/ffonteno/proactive-git/programming/tutorials/classes" -Dproactive.log4j.collector=rmi://kisscool.inria.fr:6618/8194810407958514089/logCollector -Djava.security.policy="/home/ffonteno/proactive-git/programming/tutorials/scripts/proactive.java.policy" org.objectweb.proactive.core.runtime.StartPARuntime -p rmi://kisscool.inria.fr:6618/PA_JVM798723297 -c 1 -i 2 -d 8194810407958514089 -b http://kisscool.inria.fr:49352/classServer/  '
30447@kisscool - [INFO        proactive.mop] Generating class : pa.stub.org.objectweb.proactive.core.util.log.remote._StubProActiveLogCollector
30447@kisscool - [INFO        proactive.mop] Generating class : pa.stub.org.objectweb.proactive.examples.userguide.components.adl.deployment._StubMasterImpl
30447@kisscool - [INFO        proactive.mop] Generating class : pa.stub.org.objectweb.proactive.examples.userguide.components.adl.deployment._StubSlaveImpl
30447@kisscool - [INFO                job.1]
30447@kisscool - [INFO                job.1] rmi://kisscool.inria.fr:6618/PA_JVM539286369_GCMNode-0Slave: org.objectweb.proactive.examples.userguide.components.adl.deployment.SlaveImpl@e931d9
30447@kisscool - [INFO                job.1] arg: hello - world
30447@kisscool - [INFO                job.0]
30447@kisscool - [INFO                job.0] rmi://kisscool.inria.fr:6618/PA_JVM1043221418_GCMNode-0Slave: org.objectweb.proactive.examples.userguide.components.adl.deployment.SlaveImpl@e9a7c2
30447@kisscool - [INFO                job.0] arg: hello - world
30447@kisscool - [INFO                job.0]
30447@kisscool - [INFO                job.0] rmi://kisscool.inria.fr:6618/PA_JVM1043221418_GCMNode-0Slave: org.objectweb.proactive.examples.userguide.components.adl.deployment.SlaveImpl@e9a7c2
30447@kisscool - [INFO                job.0] I do nothing

3.2.6.4. Solutions and full code

Here are the solutions:

<!DOCTYPE definition PUBLIC "-//objectweb.org//DTD Fractal ADL 2.0//EN" "classpath://org/objectweb/proactive/core/component/adl/xml/proactive.dtd">

<definition name="org.objectweb.proactive.examples.userguide.components.adl.deployment.adl.Slave">
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.deployment.Itf1" role="server" name="i1"/>
  <interface signature="org.objectweb.proactive.examples.userguide.components.adl.deployment.Itf2" role="server" name="i2"/>

  <content class="org.objectweb.proactive.examples.userguide.components.adl.deployment.SlaveImpl"/>

  <controller desc="primitive"/>

  <!-- TODO: Affect this Component to the virtual node "slave-node" -->
  <virtual-node name="slave-node"/>
</definition>
package org.objectweb.proactive.examples.userguide.components.adl.deployment;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.adl.Factory;
import org.objectweb.fractal.api.Component;
import org.objectweb.proactive.core.component.adl.FactoryFactory;
import org.objectweb.proactive.extensions.gcmdeployment.PAGCMDeployment;
import org.objectweb.proactive.gcmdeployment.GCMApplication;
import org.objectweb.proactive.gcmdeployment.GCMVirtualNode;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Load the Application Descriptor
        String descriptorPath = "file://" +
            System.getProperty("proactive.home") +
            "/src/Examples/org/objectweb/proactive/examples/userguide/components/adl/deployment/descriptors/application_descriptor.xml";
        // This tricky line enables to use this path in both Linux and Windows OS
        File deploymentFile = new File((new URL(descriptorPath)).toURI().getPath());
        GCMApplication gcma = PAGCMDeployment.loadApplicationDescriptor(deploymentFile);

        // TODO: Start the deployment
        gcma.startDeployment();
        gcma.waitReady();
        GCMVirtualNode vn = gcma.getVirtualNode("slave-node");
        vn.waitReady();

        Factory factory = FactoryFactory.getFactory();

        Map<String, Object> context = new HashMap<String, Object>();

        // TODO: Put the Application Descriptor in the context
        context.put("deployment-descriptor", gcma);

        Component composite = (Component) factory
                .newComponent(
                        "org.objectweb.proactive.examples.userguide.components.adl.deployment.adl.Composite",
                        context);

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

3.3. Create and use components using the API

3.3.1. Introduction

This second part of the tutorial shows you how to use the API in order to construct GCM components. This part is composed of three exercises:

  • Starter - this exercise make you create a simple primitive component called Slave

  • Composite - this exercise make you create a composite component composed of a Master and a Slave component.

  • Interfaces - this exercise make you modify the previous Slave component to have it implement two server interfaces.

3.3.2. Starter tutorial

3.3.2.1. Tutorial description

This tutorial explains how to create a simple component named Slave using the API. This component looks like that:

Slave component

Figure 3.5. Slave component


The interface used for this example is the following one:

package org.objectweb.proactive.examples.userguide.components.api.starter;

import java.util.List;


/**
 * @author The ProActive Team
 */
public interface Itf1 {
    void compute(List<String> arg);
}

This interface defines a compute() method which is implemented in the following SlaveImpl class:

package org.objectweb.proactive.examples.userguide.components.api.starter;

import java.util.List;

import org.objectweb.proactive.api.PAActiveObject;


/**
 * @author The ProActive Team
 */
public class SlaveImpl implements Itf1 {

    public void compute(List<String> arg) {
        String str = "\n" + PAActiveObject.getBodyOnThis().getNodeURL() + "Slave: " + this + "\n";
        str += "arg: ";
        for (int i = 0; i < arg.size(); i++) {
            str += arg.get(i);
            if (i + 1 < arg.size()) {
                str += " - ";
            }
        }
        System.err.println(str);
    }

}

These two classes are strictly the same as the ones used in the Starter tutorial using ADL files. In this tutorial, instead of describing the component into an ADL file, we will describe it directly in the main() method.

3.3.2.2. Proposed work

Here is the main() method that you have to complete:

package org.objectweb.proactive.examples.userguide.components.api.starter;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Get the Bootstrap Component
        // TODO: Get the TypeFactory
        // TODO: Get the GenericFactory
        // TODO: Create the i1 Interface Type (org.objectweb.proactive.examples.userguide.components.api.starter.Itf1)
        // TODO: Create the Slave Component type
        // TODO: Create the Slave Component

        GCM.getGCMLifeCycleController(slave).startFc();

        Itf1 itf1 = (Itf1) slave.getFcInterface("i1");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        itf1.compute(arg);

        GCM.getGCMLifeCycleController(slave).stopFc();

        System.exit(0);
    }
}

Thus, we propose you to:

  1. Get the Bootstrap component using the org.objectweb.proactive.core.component.Utils.getBootstrapComponent() method

  2. Get the GCMTypeFactory using the GCM.getGCMTypeFactory() method

  3. Get the GenericFactory using the GCM.getGenericFactory() method

  4. Create the i1 Interface Type (org.objectweb.proactive.examples.userguide.components.api.starter.Itf1) using the createFcItfType() method of the GCMTypeFactory class

  5. Create the Slave Component type using the createFcType() method of the GCMTypeFactory class

  6. Create the Slave Component instance using the newFcInstance() method of the GenericFactory class

3.3.2.3. Test your work

To build your work, go to the compile directory into the tutorials directory (not the one located into the ProActive directory) and type:

build components.api.starter

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the api-starter.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node564429316Slave: org.objectweb.proactive.examples.userguide.components.api.starter.SlaveImpl@109da93
arg: hello - world

3.3.2.4. Solutions and full code

Here is how you should have filled in the main() method:

package org.objectweb.proactive.examples.userguide.components.api.starter;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {

        // TODO: Get the Bootstrap Component
        Component boot = Utils.getBootstrapComponent();
        // TODO: Get the TypeFactory
        GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
        // TODO: Get the GenericFactory
        GenericFactory gf = GCM.getGenericFactory(boot);
        // TODO: Create the i1 Interface Type (org.objectweb.proactive.examples.userguide.components.api.starter.Itf1)
        InterfaceType itf1Slave = tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.SERVER,
                TypeFactory.MANDATORY, TypeFactory.SINGLE);
        // TODO: Create the Slave Component type
        ComponentType tSlave = tf.createFcType(new InterfaceType[] { itf1Slave });
        // TODO: Create the Slave Component
        Component slave = gf.newFcInstance(tSlave, new ControllerDescription("slave", Constants.PRIMITIVE),
                SlaveImpl.class.getName());

        GCM.getGCMLifeCycleController(slave).startFc();

        Itf1 itf1 = (Itf1) slave.getFcInterface("i1");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        itf1.compute(arg);

        GCM.getGCMLifeCycleController(slave).stopFc();

        System.exit(0);
    }
}

3.3.3. Composite tutorial

3.3.3.1. Tutorial description

This tutorial shows how to create a composite component composed of a Master and a Slave component.

This composite can be represented as follows:

Composite component

Figure 3.6. Composite component


The Slave component is exactly the same as in the previous tutorial. It is defined by the Itf1 interface implemented by the SlaveImpl class.

Concerning the Master component, it is defined by the following Runner interface:

package org.objectweb.proactive.examples.userguide.components.api.composite;

import java.util.List;


/**
 * @author The ProActive Team
 */
public interface Runner {
    public void run(List<String> arg);
}

which is implemented by the MasterImpl class:

package org.objectweb.proactive.examples.userguide.components.api.composite;

import java.util.List;

import org.objectweb.fractal.api.NoSuchInterfaceException;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.IllegalBindingException;
import org.objectweb.fractal.api.control.IllegalLifeCycleException;


/**
 * @author The ProActive Team
 */
public class MasterImpl implements Runner, BindingController {
    public static String ITF_CLIENT = "i1";
    private Itf1 i1;

    public void run(List<String> arg) {
        i1.compute(arg);
    }

    public void bindFc(String clientItfName, Object serverItf) throws NoSuchInterfaceException,
            IllegalBindingException, IllegalLifeCycleException {
        if (ITF_CLIENT.equals(clientItfName)) {
            i1 = (Itf1) serverItf;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public String[] listFc() {
        return new String[] { ITF_CLIENT };
    }

    public Object lookupFc(String clientItfName) throws NoSuchInterfaceException {
        if (ITF_CLIENT.equals(clientItfName)) {
            return i1;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }

    public void unbindFc(String clientItfName) throws NoSuchInterfaceException, IllegalBindingException,
            IllegalLifeCycleException {
        if (ITF_CLIENT.equals(clientItfName)) {
            i1 = null;
        } else {
            throw new NoSuchInterfaceException(clientItfName);
        }
    }
}

This class contains an Itf1 member representing the client interface which is used in the BindingController method. These methods are:

  • bindFc() - used to bind interfaces

  • listFc() - used to list interfaces

  • lookupFc() - used to get one of the available interfaces using its name

  • unbindFc() - used to unbind interfaces

The only things that remain to do now so as to be able to use our composite component are first, to define all the three components (Slave, Master and Composite) in our main() method using the Java API and then, to add the two sub-components (Master and Slave) to the Composite component and to write the two bindings.

3.3.3.2. Proposed work

Here is the Main class that you have to fill in:

package org.objectweb.proactive.examples.userguide.components.api.composite;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {
        Component boot = Utils.getBootstrapComponent();
        GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
        GenericFactory gf = GCM.getGenericFactory(boot);
        ComponentType tComposite = tf.createFcType(new InterfaceType[] { tf.createFcItfType("runner",
                Runner.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });

        // TODO: Create the Master Component type

        ComponentType tSlave = tf.createFcType(new InterfaceType[] { tf.createFcItfType("i1", Itf1.class
                .getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });

        Component slave = gf.newFcInstance(tSlave, new ControllerDescription("slave", Constants.PRIMITIVE),
                SlaveImpl.class.getName());

        // TODO: Create the Master Component

        Component composite = gf.newFcInstance(tComposite, new ControllerDescription("composite",
            Constants.COMPOSITE), null);

        // TODO: Add slave and master components to the composite component

        // TODO: Do the bindings

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

We propose you to:

  1. Create the Master component type as you created the Slave component type in the previous tutorial. Hint: in that case, there are two interfaces (one client and one server interface)

  2. Instantiate the Master component

  3. Add the two sub-components (Master and Slave) to the Composite component. Hint: use the GCM.getContentController() static method to get a ContentController and use it to add these sub-components.

  4. Do the bindings. Hint: For doing a binding, you should first get the BindingController of the component containing the client interface you want to bind and then, call the bindFc() method on it. To get the BindingController, use the GCM.getBindingController() method.

3.3.3.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.api.composite

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the api-composite.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node480011239Slave: org.objectweb.proactive.examples.userguide.components.api.composite.SlaveImpl@c62080
arg: hello - world

3.3.3.4. Solutions and full code

Here is how you should have filled in the Main class:

package org.objectweb.proactive.examples.userguide.components.api.composite;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.control.ContentController;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {
        Component boot = Utils.getBootstrapComponent();
        GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
        GenericFactory gf = GCM.getGenericFactory(boot);
        ComponentType tComposite = tf.createFcType(new InterfaceType[] { tf.createFcItfType("runner",
                Runner.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });

        // TODO: Create the Master Component type
        ComponentType tMaster = tf.createFcType(new InterfaceType[] {
                tf.createFcItfType("runner", Runner.class.getName(), TypeFactory.SERVER,
                        TypeFactory.MANDATORY, TypeFactory.SINGLE),
                tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.CLIENT, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE) });

        ComponentType tSlave = tf.createFcType(new InterfaceType[] { tf.createFcItfType("i1", Itf1.class
                .getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });

        Component slave = gf.newFcInstance(tSlave, new ControllerDescription("slave", Constants.PRIMITIVE),
                SlaveImpl.class.getName());

        // TODO: Create the Master Component
        Component master = gf.newFcInstance(tMaster,
                new ControllerDescription("master", Constants.PRIMITIVE), MasterImpl.class.getName());

        Component composite = gf.newFcInstance(tComposite, new ControllerDescription("composite",
            Constants.COMPOSITE), null);

        // TODO: Add slave and master components to the composite component
        ContentController cc = GCM.getContentController(composite);
        cc.addFcSubComponent(slave);
        cc.addFcSubComponent(master);

        // TODO: Do the bindings
        BindingController bcMaster = GCM.getBindingController(master);
        bcMaster.bindFc("i1", slave.getFcInterface("i1"));
        BindingController bcComposite = GCM.getBindingController(composite);
        bcComposite.bindFc("runner", master.getFcInterface("runner"));

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

3.3.4. Interface tutorial

3.3.4.1. Tutorial description

In this tutorial, we will add a new server interface to the Slave component and bind it to a new client interface of the Master component. Our composite component will therefore look like as follows:

Composite component with the new interface

Figure 3.7. Composite component with the new interface


We introduce a second interface named Itf2 which source code is the following one:

package org.objectweb.proactive.examples.userguide.components.api.interfaces;

/**
 * @author The ProActive Team
 */
public interface Itf2 {
    void doNothing();
}

The aim of this tutorial is to make you modify the previous code in order to add this new interface using the API. All the necessary modification are made into the Main class.

3.3.4.2. Proposed work

Here is the main() method that you have to complete:

package org.objectweb.proactive.examples.userguide.components.api.interfaces;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {
        Component boot = Utils.getBootstrapComponent();
        GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
        GenericFactory gf = GCM.getGenericFactory(boot);
        ComponentType tComposite = tf.createFcType(new InterfaceType[] { tf.createFcItfType("runner",
                Runner.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });
        ComponentType tMaster = tf.createFcType(new InterfaceType[] {
                tf.createFcItfType("runner", Runner.class.getName(), TypeFactory.SERVER,
                        TypeFactory.MANDATORY, TypeFactory.SINGLE),
                tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.CLIENT, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                //TODO: Add the new client interface
                });
        ComponentType tSlave = tf.createFcType(new InterfaceType[] {
                tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                //TODO: Add the new server interface
                });
        Component slave = gf.newFcInstance(tSlave, new ControllerDescription("slave", Constants.PRIMITIVE),
                SlaveImpl.class.getName());
        Component master = gf.newFcInstance(tMaster,
                new ControllerDescription("master", Constants.PRIMITIVE), MasterImpl.class.getName());
        Component composite = gf.newFcInstance(tComposite, new ControllerDescription("composite",
            Constants.COMPOSITE), null);

        BindingController bcComposite = GCM.getBindingController(composite);
        bcComposite.bindFc("runner", master.getFcInterface("runner"));
        BindingController bcMaster = GCM.getBindingController(master);
        bcMaster.bindFc("i1", slave.getFcInterface("i1"));

        // TODO: Do the binding for the new interface

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}

Thus, we propose you to:

  1. Add the new client interface in the Master component type

  2. Add the new server interface in the Slave component type

  3. Add a new binding between these two interfaces

3.3.4.3. Test your work

To build your work, go to the compile directory into the tutorials directory and type:

build components.api.interfaces

Once you get a successful compilation, go to the scripts/Components directory located into the tutorials one and launch the api-interfaces.[sh|bat] script. You should then see a display looking like this:

rmi://kisscool.inria.fr:6618/Node275638725Slave: org.objectweb.proactive.examples.userguide.components.api.interfaces.SlaveImpl@3aa791
arg: hello - world

rmi://kisscool.inria.fr:6618/Node275638725Slave: org.objectweb.proactive.examples.userguide.components.api.interfaces.SlaveImpl@3aa791
I do nothing

3.3.4.4. Solutions and full code

Here is the solution:

package org.objectweb.proactive.examples.userguide.components.api.interfaces;

import java.util.ArrayList;
import java.util.List;

import org.etsi.uri.gcm.api.type.GCMTypeFactory;
import org.etsi.uri.gcm.util.GCM;
import org.objectweb.fractal.api.Component;
import org.objectweb.fractal.api.control.BindingController;
import org.objectweb.fractal.api.factory.GenericFactory;
import org.objectweb.fractal.api.type.ComponentType;
import org.objectweb.fractal.api.type.InterfaceType;
import org.objectweb.fractal.api.type.TypeFactory;
import org.objectweb.proactive.core.component.Constants;
import org.objectweb.proactive.core.component.ControllerDescription;
import org.objectweb.proactive.core.component.Utils;


/**
 * @author The ProActive Team
 */
public class Main {

    public static void main(String[] args) throws Exception {
        Component boot = Utils.getBootstrapComponent();
        GCMTypeFactory tf = GCM.getGCMTypeFactory(boot);
        GenericFactory gf = GCM.getGenericFactory(boot);
        ComponentType tComposite = tf.createFcType(new InterfaceType[] { tf.createFcItfType("runner",
                Runner.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY, TypeFactory.SINGLE) });
        ComponentType tMaster = tf.createFcType(new InterfaceType[] {
                tf.createFcItfType("runner", Runner.class.getName(), TypeFactory.SERVER,
                        TypeFactory.MANDATORY, TypeFactory.SINGLE),
                tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.CLIENT, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                //TODO: Add the new client interface
                ,
                tf.createFcItfType("i2", Itf2.class.getName(), TypeFactory.CLIENT, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                });
        ComponentType tSlave = tf.createFcType(new InterfaceType[] {
                tf.createFcItfType("i1", Itf1.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                //TODO: Add the new server interface
                ,
                tf.createFcItfType("i2", Itf2.class.getName(), TypeFactory.SERVER, TypeFactory.MANDATORY,
                        TypeFactory.SINGLE)
                });
        Component slave = gf.newFcInstance(tSlave, new ControllerDescription("slave", Constants.PRIMITIVE),
                SlaveImpl.class.getName());
        Component master = gf.newFcInstance(tMaster,
                new ControllerDescription("master", Constants.PRIMITIVE), MasterImpl.class.getName());
        Component composite = gf.newFcInstance(tComposite, new ControllerDescription("composite",
            Constants.COMPOSITE), null);

        BindingController bcComposite = GCM.getBindingController(composite);
        bcComposite.bindFc("runner", master.getFcInterface("runner"));
        BindingController bcMaster = GCM.getBindingController(master);
        bcMaster.bindFc("i1", slave.getFcInterface("i1"));

        // TODO: Do the binding for the new interface
        bcMaster.bindFc("i2", slave.getFcInterface("i2"));

        GCM.getGCMLifeCycleController(composite).startFc();

        Runner runner = (Runner) composite.getFcInterface("runner");
        List<String> arg = new ArrayList<String>();
        arg.add("hello");
        arg.add("world");
        runner.run(arg);

        GCM.getGCMLifeCycleController(composite).stopFc();

        System.exit(0);
    }
}