Skip to content
/ celix Public

Apache Celix is a framework for C and C++14 to develop dynamic modular software applications using component and in-process service-oriented programming.

License

Notifications You must be signed in to change notification settings

apache/celix

Apache Celix

License Celix Ubuntu Celix MacOS codecov Coverity Scan Build Status Gitpod ready-to-code

Apache Celix is a framework for C and C++14 to develop dynamic modular software applications using component and in-process service-oriented programming. Apache Celix is inspired by theOSGi specificationadapted for C and C++.

Documentation

C++ Usage

Hello World Bundle

Modularity in Celix is achieved by runtime installable bundles and dynamic - in process - services.
A Celix bundle is set of resources packed in a zip containing at least a manifest and almost always some shared library containing the bundle functionality. A Celix bundle can be created using the Celix CMake functionadd_celix_bundle. A Celix bundle is activated by executing the bundle entry points. For C++ bundles these bundle entry points are generated using theCELIX_GEN_CXX_BUNDLE_ACTIVATORmacro.

Celix applications (Celix containers) can be created with the Celix CMake functionadd_celix_container. This function generates a C++ main function and is also used to configure default installed bundles. This can be bundles provided by Celix, an other project or build by the project self.

//src/MyBundleActivator.cc
#include<iostream>
#include"celix/BundleActivator.h"

classMyBundleActivator{
public:
explicitMyBundleActivator(conststd::shared_ptr<celix::BundleContext>& ctx) {
std::cout <<"Hello world from bundle with id"<< ctx->getBundleId() << std::endl;
}

~MyBundleActivator()noexcept{
std::cout <<"Goodbye world"<< std::endl;
}
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(MyBundleActivator)
#CMakeLists.txt
find_package(CelixREQUIRED)

add_celix_bundle(MyBundle
SOURCESsrc/MyBundleActivator.cc
)

add_celix_container(MyContainer
BUNDLES
Celix::ShellCxx
Celix::shell_tui
MyBundle
)
#bash
#goto project dir
cdcmake-build-debug#assuming clion cmake-build-debug dir
cddeploy/MyContainer
./MyContainer
#Celix shell
->lb -a
#list of all installed bundles
->help
#list of all available Celix shell commands
->helpcelix::lb
#Help info about the shell command `celix::lb`
->stop 3
#stops MyBundle
->start 3
#starts MyBundle
->stop 0
#stops the Celix framework

Register a service

In the Celix framework, a service is a C++ object or C struct registered in the Celix framework service registry under one interface together with properties (meta information). Services can be discovered and used by bundles.

//include/ICalc.h
#pragmaonce
classICalc{
public:
virtual~ICalc()noexcept=default;
virtualintadd(inta,intb) = 0;
};
//src/CalcProviderBundleActivator.cc
#include"ICalc.h"
#include"celix/BundleActivator.h"

classCalcProvider:publicICalc{
public:
~CalcProvider()noexceptoverride=default;
intadd(inta,intb)override{returna + b; }
};

classCalcProviderBundleActivator{
public:
explicitCalcProviderBundleActivator(conststd::shared_ptr<celix::BundleContext>& ctx) {
reg = ctx->registerService<ICalc>(std::make_shared<CalcProvider>())
.build();
}
private:
std::shared_ptr<celix::ServiceRegistration> reg{};
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcProviderBundleActivator)
#CMakeLists.txt
find_package(CelixREQUIRED)

add_celix_bundle(CalcProviderBundle
SOURCESsrc/CalcProviderBundleActivator.cc
)
target_include_directories(CalcProviderBundlePRIVATEinclude)

add_celix_container(CalcProviderContainer
BUNDLES
Celix::ShellCxx
Celix::shell_tui
CalcProviderBundle
)
#bash
#goto project dir
cdcmake-build-debug#assuming clion cmake-build-debug dir
cddeploy/CalcProviderBundle
./CalcProviderBundle

Use a service (ad hoc)

//include/ICalc.h
#pragmaonce
classICalc{
public:
virtual~ICalc()noexcept=default;
virtualintadd(inta,intb) = 0;
};
//src/CalcUserBundleActivator.cc
#include<iostream>
#include"ICalc.h"
#include"celix/BundleActivator.h"

classCalcUserBundleActivator{
public:
explicitCalcUserBundleActivator(conststd::shared_ptr<celix::BundleContext>& ctx) {
ctx->useService<ICalc>()
.addUseCallback([](ICalc& calc) {
std::cout <<"result is"<< calc.add(2,3) << std::endl;
})
.setTimeout(std::chrono::seconds{1})//wait for 1 second if a service is not directly found
.build();
}
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcUserBundleActivator)
#CMakeLists.txt
find_package(CelixREQUIRED)

add_celix_bundle(CalcUserBundle
SOURCESsrc/CalcUserBundleActivator.cc
)
target_include_directories(CalcUserBundlePRIVATEinclude)

add_celix_container(CalcUserContainer
BUNDLES
Celix::ShellCxx
Celix::shell_tui
CalcProviderBundle
CalcUserBundle
)
#bash
#goto project dir
cdcmake-build-debug#assuming clion cmake-build-debug dir
cddeploy/CalcUserContainer
./CalcUserContainer

Track services

//include/ICalc.h
#pragmaonce
classICalc{
public:
virtual~ICalc()noexcept=default;
virtualintadd(inta,intb) = 0;
};
//src/CalcTrackerBundleActivator.cc
#include<mutex>
#include"ICalc.h"
#include"celix/BundleActivator.h"

classCalcTrackerBundleActivator{
public:
explicitCalcTrackerBundleActivator(conststd::shared_ptr<celix::BundleContext>& ctx) {
tracker = ctx->trackServices<ICalc>()
.build();
for(auto& calc: tracker->getServices()) {
std::cout <<"result is"<<std::to_string(calc->add(2,3)) << std::endl;
}
}

private:
std::shared_ptr<celix::ServiceTracker<ICalc>> tracker{};
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(CalcTrackerBundleActivator)
find_package(CelixREQUIRED)

add_celix_bundle(CalcTrackerBundle
SOURCESsrc/CalcTrackerBundleActivator.cc
)
target_include_directories(CalcTrackerBundlePRIVATEinclude)

add_celix_container(CalcTrackerContainer
BUNDLES
Celix::ShellCxx
Celix::shell_tui
CalcProviderBundle
CalcTrackerBundle
)
#bash
#goto project dir
cdcmake-build-debug#assuming clion cmake-build-debug dir
cddeploy/CalcTrackerContainer
./CalcTrackerContainer

Service properties and filters

//src/FilterExampleBundleActivator.cc
#include<iostream>
#include"celix/BundleActivator.h"
#include"celix/IShellCommand.h"

classHelloWorldShellCommand:publiccelix::IShellCommand {
public:
voidexecuteCommand(conststd::string&/*commandLine*/,conststd::vector<std::string>&/*commandArgs*/,FILE* outStream, FILE*/*errorStream*/) {
fprintf(outStream,"Hello World\n");
}
};

classFilterExampleBundleActivator{
public:
explicitFilterExampleBundleActivator(conststd::shared_ptr<celix::BundleContext>& ctx) {
autoreg1 = ctx->registerService<celix::IShellCommand>(std::make_shared<HelloWorldShellCommand>())
.addProperty(celix::IShellCommand::COMMAND_NAME,"command1")
.build();
autoreg2 = ctx->registerService<celix::IShellCommand>(std::make_shared<HelloWorldShellCommand>())
.addProperty(celix::IShellCommand::COMMAND_NAME,"command2")
.build();
regs.push_back(reg1);
regs.push_back(reg2);

autoserviceIdsNoFilter = ctx->findServices<celix::IShellCommand>();
autoserviceIdsWithFilter = ctx->findServices<celix::IShellCommand>(std::string{"("} + celix::IShellCommand::COMMAND_NAME +"="+"command1)");
std::cout <<"Found"<<std::to_string(serviceIdsNoFilter.size()) <<"IShelLCommand services and found";
std::cout <<std::to_string(serviceIdsWithFilter.size()) <<"IShellCommand service with name command1"<< std::endl;
}
private:
std::vector<std::shared_ptr<celix::ServiceRegistration>> regs{};
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(FilterExampleBundleActivator)
#CMakeLists.txt
find_package(CelixREQUIRED)

add_celix_bundle(FilterExampleBundle
SOURCESsrc/FilterExampleBundleActivator.cc
)
target_link_libraries(FilterExampleBundlePRIVATECelix::shell_api)#adds celix/IShellCommand.h to the include path

add_celix_container(FilterExampleContainer
BUNDLES
Celix::ShellCxx
Celix::shell_tui
FilterExampleBundle
)
#bash
#goto project dir
cdcmake-build-debug#assuming clion cmake-build-debug dir
cddeploy/FilterExampleContainer
./FilterExampleContainer
#Celix shell
->command1
->command2
->help

About

Apache Celix is a framework for C and C++14 to develop dynamic modular software applications using component and in-process service-oriented programming.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published