Introduction
On this day we will focus on preparing the initial implementation of our first component. By the end of the day, we expect the groups to:
- Go through "HelloComponent" implementation for the assigned programming language
- Inheritance from IDL interface to be implemented
- Basic implementation of the methods
- Modifying CDB configuration in your test directory
- Exercising your component implementation from objexp and/or a PySimpleClient instance
...
As a guide, we're going to show you a very simple component implementation.
The UML description for our component is:
Image Added
First we create the directory for the IDL:
Code Block |
---|
|
> getTemplateForDirectory MODROOT_WS idlHelloComp
> cd idlHelloComp/src
> touch ../idl/HelloComponent.idl |
...
Code Block |
---|
language | cpp |
---|
title | idlHelloComp/idl/HelloComponent.idl |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _HELLOCOMPONENT_IDL_
#define _HELLOCOMPONENT_IDL_
#pragma prefix "acsws"
#include <acscomponent.idl>
module workshop {
interface HelloComponent : ACS::ACSComponent {
voidstring printHello();
};
};
#endif |
...
Code Block |
---|
title | idlHelloComponent/src/Makefile |
---|
|
...
IDL_FILES = HelloComponent
HelloComponentStubs_LIBS = acscomponentStubs
...
COMPONENT_HELPERS=on
... |
We then compile and install the IDL definitions:
Code Block |
---|
language | bash |
---|
title | Compilation |
---|
|
make -j> make all install |
Configuration
The following image depicts the deployment configuration needed:
Image Added
Add the following configuration in the $ACS_CDB/CDB/MACI/Components/Components.xml:
Code Block |
---|
language | xml |
---|
title | Components.xml |
---|
linenumbers | true |
---|
collapse | true |
---|
|
...
<e Name="CPP_HELLO_COMP"
Code="HelloComponentImpl"
Type="IDL:acsws/workshop/HelloComponent:1.0"
Container="bilboContainer"
ImplLang="cpp"/>
<e Name="JAVA_HELLO_COMP"
Code="acsws.workshop.HelloComponentHelperHelloComponentImpl.HelloComponentComponentHelper"
Type="IDL:acsws/workshop/HelloComponent:1.0"
Container="frodoContainer"
ImplLang="java"/>
<e Name="PY_HELLO_COMP"
Code="workshopws.HelloComponentImpl"
Type="IDL:acsws/workshop/HelloComponent:1.0"
Container="aragornContainer"
ImplLang="py"/>
... |
...
Implementation
Python
Code Block |
---|
language | bash |
---|
title | pyHelloComp |
---|
|
> getTemplateForDirectory MODROOT_WS pyHelloComp
> cd pyHelloComp/src
> mkdir workshopws
> touch ws/__init__.py
touch workshopws/HelloComponentImpl.py |
We modify the Makefile for this component:
Code Block |
---|
title | pyHelloComponentpyHelloComp/src/Makefile |
---|
|
...
PY_PACKAGEPACKAGES = workshopws
... |
We fill the component code as follows:
Code Block |
---|
language | py |
---|
title | pyHelloComponentpyHelloComp/src/workshopws/HelloComponentImpl.py |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#Client# Client stubs and definitions, such as structs, enums, etc.
import workshop
#Skeleton# Skeleton infrastructure for server implementation
import workshop__POA
#Base# Base component implementation
from Acspy.Servants.ACSComponent import ACSComponent
#Services# Services provided by the container to the component
from Acspy.Servants.ContainerServices import ContainerServices
#Basic# Basic component lifecycle (initialize, execute, cleanUp and aboutToAbort methods)
from Acspy.Servants.ComponentLifecycle import ComponentLifecycle
class HelloComponentImpl(<Module>workshop__POA.HelloComponent, ACSComponent, ContainerServices, ComponentLifecycle):
def __init__(self):
ACSComponent.__init__(self)
ContainerServices.__init__(self)
self._logger = self.getLogger()
def printHello(self):
print("Just printing 'Hello World!'")
return "Hello World!" |
Java
Code Block |
---|
language | bash |
---|
title | jHelloComp |
---|
|
getTemplateForDirectory MODROOT_WS jHelloComp
cd jHelloComp/src
mkdir -p acsws/workshop/HelloComponentImpl
touch acsws/workshop/HelloComponentImpl/HelloComponentImpl.java
cp ../../idlHelloComp/src/acsws/workshop/HelloComponentImpl/HelloComponentComponentHelper.java.tpl acsws/workshop/HelloComponentImpl/HelloComponentComponentHelper.java |
We modify the Makefile for this component:
Code Block |
---|
title | jHelloComp/src/Makefile |
---|
|
...
JARFILES = HelloComponentImpl
HelloComponentImpl_DIRS = acsws
... |
We fill the component code as follows:
Code Block |
---|
language | java |
---|
title | jHelloComp/src/acsws/workshop/HelloComponentImpl/HelloComponentImpl.java |
---|
linenumbers | true |
---|
collapse | true |
---|
|
//Suggested: import alma.<Module>.<Interface>Impl; //But anything, really
package acsws.workshop.HelloComponentImpl;
//Base component implementation, including container services and component lifecycle printinfrastructure
import alma.acs.component.ComponentImplBase;
//Skeleton interface for server implementation
import acsws.workshop.HelloComponentOperations;
//ClassName usually is <Interface>Impl, but can be anything
public class HelloComponentImpl extends ComponentImplBase implements HelloComponentOperations {
public HelloComponentImpl() {
}
public String printHello() {
System.out.println("Just printing 'Hello World!'") |
...
");
return new String("Hello World!");
}
} |
C++
We create the needed directories:
Code Block |
---|
language | bash |
---|
title | cppHelloComp |
---|
|
> getTemplateForDirectory MODROOT_WS cppHelloComp
> cd cppHelloComp/src
> touch HelloComponentImpl.cpp
> touch ../include/HelloComponentImpl.h |
We modify the Makefile for this component:
Code Block |
---|
title | cppHelloComponentcppHelloComp/src/Makefile |
---|
|
...
INCLUDES = HellowComponentImplHelloComponentImpl.h
...
LIBRARIES = HelloComponentImpl
HelloComponentImpl_OBJECTS = HelloComponentImpl
HelloComponentImpl_LIBS = HelloComponentStubs acscomponent
... |
...
Code Block |
---|
language | cpp |
---|
title | cppHelloComponentcppHelloComp/include/HelloComponentImpl.h |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#ifndef _HELLO_COMPONENT_IMPL_H
#define _HELLO_COMPONENT_IMPL_H
#ifndef __cplusplus
#error This is a C++ include file and cannot be used from plain C
#endif
//Base component implementation, including container services and component lifecycle infrastructure
#include <acscomponentImpl.h>
//Skeleton interface for server implementation
#include <HelloComponentS.h>
//Error definitions for catching and raising exceptions
class HelloComponentImpl : public virtual acscomponent::ACSComponentImpl, public virtual POA_workshop::HelloComponent {
public:
HelloComponentImpl(const ACE_CString& name, maci::ContainerServices * containerServices);
virtual ~HelloComponentImpl();
voidchar* printHello();
};
#endif |
Code Block |
---|
language | cpp |
---|
title | cppHelloComponentcppHelloComp/src/HelloComponentImpl.cpp |
---|
linenumbers | true |
---|
collapse | true |
---|
|
#include <HelloComponentImpl.h>
HelloComponentImpl::HelloComponentImpl(const ACE_CString& name, maci::ContainerServices * containerServices) : ACSComponentImpl(name, containerServices) {
}
HelloComponentImpl::~HelloComponentImpl() {
}
voidchar* HelloComponentImpl::printHello() {
std::cout << "Just printing 'Hello World!'" << std::endl;
return CORBA::string_dup("Hello World!");
}
/* --------------- [ MACI DLL support functions ] -----------------*/
#include <maciACSComponentDefines.h>
MACI_DLL_SUPPORT_FUNCTIONS(HelloComponentImpl)
/* ----------------------------------------------------------------*/ |
With this information we are ready to compile our first component that will print the "Hello World" message.
Client
First launch your acs container with the modified ACS CDB
Code Block |
---|
language | bash |
---|
title | Start container |
---|
|
acsStartContainer -py aragornContainer
acsStartContainer -java frodoContainer
acsStartContainer -cpp bilboContainer |
For simplicity, we implement a simple client in Python to communicate with the 3 programming languages:
Code Block |
---|
language | py |
---|
linenumbers | true |
---|
collapse | true |
---|
|
from Acspy.Clients.SimpleClient import PySimpleClient
client = PySimpleClient()
hc_py = client.getComponent("PY_HELLO_COMP")
print(hc_py.printHello())
hc_java = client.getComponent("JAVA_HELLO_COMP")
print(hc_java.printHello())
hc_cpp = client.getComponent("CPP_HELLO_COMP")
print(hc_cpp.printHello())
|
Output
The output is seen on each container:
Py
Code Block |
---|
...
2020-07-28T21:14:29.850 aragornContainer run - Calling maci::CBComponentInfo::done with descOut.id_tag = 2 for 'PY_HELLO_COMP'
2020-07-28T21:14:29.858 aragornContainer run - Call to maci::CBComponentInfo::done with descOut.id_tag = 2 for 'PY_HELLO_COMP' completed
Just printing 'Hello World!'
... |
Java
Code Block |
---|
...
2020-07-28T21:09:13.385 DELOUSE [frodoContainer] Calling maci::CBComponentInfo::done with descOut.id_tag = %d.1 for 'JAVA_HELLO_COMP'
2020-07-28T21:09:13.411 DELOUSE [frodoContainer] Call to maci::CBComponentInfo::done with descOut.id_tag = %d.1 for 'JAVA_HELLO_COMP' completed
2020-07-28T21:09:16.598 DELOUSE [frodoContainer] intercepted a call to 'JAVA_HELLO_COMP#printHello'.
Just printing 'Hello World!'
2020-07-28T21:09:16.599 DELOUSE [frodoContainer] returning from JAVA_HELLO_COMP#printHello after 0 ms.
... |
C++
Code Block |
---|
...
2020-07-28T21:19:53.080 [Container-ActivationMethod - maci::ActivationMethod::call] Calling maci::CBComponentInfo::done with descOut.id_tag = 4.
2020-07-28T21:19:53.082 [Container-ActivationMethod - maci::ActivationMethod::call] Call to maci::CBComponentInfo::done with descOut.id_tag = 4 completed.
Just saying 'Hello World!'
... |
PySimpleClient
Code Block |
---|
...
Hello World!
Hello World!
Hello World!
... |