Previous

Compilation and deployment

Compilation

Once all the code has been written, compilation of the code would be the next step.
MPC is used in order to create the Makefiles and projects files. All MPC files that are needed for this tutorial are in the same directory as the accompanying IDL and executor files.
In order to make the GNU make files or the Visual Studio project files, the following steps should be performed :

If all went well, all libraries are in the Shapes_asm/lib directory.

Deployment

Once all binaries are compiled, they're ready to be deployed. In this tutorial we are using DAnCE to deploy our system.
DAnCE starts a system in two phases :

  1. configuration_complete
  2. ccm_activate
DAnCE shuts down a system again in two phases :
  1. passivate
  2. ccm_remove
Each component should have these four methods implemented. The business logic implemented in each step depends on you implementation.
There're several processes taking care of the total deployment process. See the DAnCE documentation for more information about which processes there are and what their responsibilities are.
DAnCE will start and shutdown a system with the aid of a deployment plan. A deployment plan describes which artifacts must run on which nodes and which components are connected to eachother via which interface (more on this later). All connections between components are made before 'configuration_complete' is called.

The deployment plan will be generated by the modelling tools but we take a brief look at the most important items of a deployment plan. A deployment plan is a XML based file which is devided into the following (main) sections:

All deployment code fragments mentioned in the rest of this tutorial are *NO* exports of any modelling tool.

Implementations and Entry Points

This defines which executor and servant artifacts (binaries) should be used. Implementations also defines which entry points in the binaries should be used. This file shows the implementation section of the controller.
Beware that artifacts and entry points are exact otherwise deployment will fail.

Instances

Instances define which artifacts run on which node. Every fysical artifact in the system results in one instance. The <node> section refers to the fysical node on which this instance will be deployed.
An instance always refers to an implementation. It's possible that more than one instance refers to the same implementation.
The instance section also provide the initial values of all attributes defined on the component.
This file shows the instance section of the controller.

Connections

A connection section defines which components are connected together. To define a connection one should know which type of DDS4CCM connector is used.

Example
The sender component is connected to a DDS4CCM connector via the DDS_Write extented port of the DDS_Event basic port. The DDS_Write port for the DDS_Event connector is called 'supplier' and the Writer interface on this extented port is called 'data' (see ccm_dds.idl). In Shapes_Sender_comp.idl, the DDS_Write port is called 'info_write'. The DDS4CCM connector provide the writer interface, the Sender component uses this.
The connection is 'local' since a connector and a component are always running in the same process.
Now that we have got all the data we need to know to make a connection between the Sender and DDS4CCM connector regarding the writer port.

<connection>
  <name>writer_connection</name> //unique name of the connection
  <deployRequirement>
    <name>edu.dre.vanderbilt.DAnCE.ConnectionType</name>
    <resourceType>Local_Interface</resourceType> //The connection between the Sender and the DDS4CCM connector is 'local'
  <deployRequirement>
  <internalEndpoint> //First endpoint (the Sender component).
    //PortName is defined as follows
    //<name_of_port_in_sender_component_idl>_< name_of_interface_in_extended_port>(see ccm_dds.idl)
    <portName>info_write_data</portName>
    <provider>false</provider> //The Sender component doens't provide the interface
    <kind>SimplexReceptacle</kind>
    <instance xmi:idref="SenderComponentInstance" /> //Reference to the artifact (the Sender component instance in this case)
  </internalEndpoint>
  <internalEndpoint> //First endpoint (the Sender component).
    //PortName is defined as follows
    //<name_of_port_in_dds4ccm_connector>_< name_of_interface_in_extended_port>(see ccm_dds.idl)
    <portName>supplier_data</portName>
    <provider>true</provider> //The DDS4CCM connector provides this interface
    <kind>Facet</kind>
    <instance xmi:idref="Shapes_SenderConnectorInstance" /> //The reference to the connector instance.
  </internalEndpoint>
</connection>

Take a look at this file to see which connection should be made by DAnCE in order to run the shapes system properly. Also take a look at the connection between the Controller and the Sender. This one is different because no DDS4CCM connector is used.

When the deployment tools (in this case DAnCE) deploys this system, it'll connect all defined connectors before the system is started (i.e. before configuration_complete is called on a component).

Coding connections

Every component has got a context. The context is set by DAnCE and is the 'gateway' to all other component your component is connected to. The context caches all these connections so that the user doesn't need to cache those in his/her component.

Sender
The Sender uses the writer connection of the DDS_Write extented port of the DDS_Event basic port. The following code retrieves the connection to the Writer interface from the context.
::Shapes::ShapeType_conn::Writer_var writer = this->context_->get_connection_info_write_data ();

Controller
The Controller uses the 'Control_obj' interface of the Sender component. Since this isn't a connection to a DDS4CCM connector, the code is rather simple. Looking at the IDL of the sender and receiver, the following code can be constructed in order to get the connection the Control_obj interface:
::Shapes::Control_obj_var control = this->context_->get_connection_control ();

Receiver
The Receiver 'listens' to DDS and thus should provide a callback for the DDS4CCM connector. Please take a look at the generated code of the executor code of the receiver to see how this can be done.
By default, a DDS4CCM connector is not listening so one should instruct the DDS4CCM connector to start listening to samples. Therefor a DataListenerControl interface (data_control) is available. The following code ensures that the DDS4CCM connector starts listening to the desired samples.
::CCM_DDS::DataListenerControl_var lc = this->context_->get_connection_info_out_data_control ();
lc->mode (::CCM_DDS::ONE_BY_ONE);

This ensures that 'on_one_data' is gets invoked by the DDS4CCM connector for each sample.
It's also possible to use ::CCM_DDS::MANY_BY_MANY. This will make sure that on_many_data on the listeners callback gets invoked by the DDS4CCM connector.
To turn off listening, just call lc->mode (::CCM_DDS::NOT_ENABLED);

Artifacts

Artifacts sections contains the names of the binaries. See this files for an overview of all artifacts in the shapes system.

Complete plan

This file shows the complete deployment plan.

Previous