This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/cxx_rsa_update
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/feature/cxx_rsa_update by this
push:
new 9cbbdc5 Adds initial integration gtest for remote services
9cbbdc5 is described below
commit 9cbbdc5b85741ff147b6d6e077ce818bc4f2d4bc
Author: Pepijn Noltes <[email protected]>
AuthorDate: Tue May 11 19:37:27 2021 +0200
Adds initial integration gtest for remote services
---
bundles/cxx_remote_services/CMakeLists.txt | 4 +-
.../admin/include/RemoteServiceAdmin.h | 10 +-
.../admin/src/RemoteServiceAdmin.cc | 2 +
bundles/cxx_remote_services/common/CMakeLists.txt | 32 ---
.../common/include/ExportedServiceFactory.h | 105 ---------
.../common/include/IExportedService.h | 25 ---
.../common/include/ImportedServiceFactory.h | 98 ---------
bundles/cxx_remote_services/common/src/common.cc | 2 -
.../discovery_configured/CMakeLists.txt | 1 +
.../cxx_remote_services/examples/CMakeLists.txt | 108 ----------
.../examples/HardcodedExampleProvider.cc | 142 ------------
.../examples/HardcodedExampleSerializer.cc | 239 ---------------------
.../examples/HardcodedExampleSerializer.h | 91 --------
.../examples/HardcodedExampleSubscriber.cc | 207 ------------------
.../examples/IHardcodedService.h | 34 ---
.../examples/discovery/endpoint.json | 26 ---
.../pubsub_properties/IHardcodedService.properties | 27 ---
.../cxx_remote_services/integration/CMakeLists.txt | 9 +-
.../integration/gtest/CMakeLists.txt | 67 ++++++
.../src/RemoteServicesIntegrationTestSuite.cc | 78 +++++++
.../integration/src/CalculatorConsumer.cc | 58 ++---
.../logging/log_helper/include/celix/LogHelper.h | 2 +
cmake/cmake_celix/Generic.cmake | 25 +++
libs/framework/include/celix/Bundle.h | 3 +-
libs/framework/include/celix/Constants.h | 8 +
25 files changed, 225 insertions(+), 1178 deletions(-)
diff --git a/bundles/cxx_remote_services/CMakeLists.txt
b/bundles/cxx_remote_services/CMakeLists.txt
index 06bbd6b..30f3d3c 100644
--- a/bundles/cxx_remote_services/CMakeLists.txt
+++ b/bundles/cxx_remote_services/CMakeLists.txt
@@ -18,7 +18,6 @@
celix_subproject(REMOTE_SERVICE_ADMIN "Option to enable building the C++17
Remote Service Admin Service bundles" OFF)
if (REMOTE_SERVICE_ADMIN)
message(WARNING "The C++ Remote Service Admin is still experimental; The
API, SPI and implementation is not stable and will change")
- #add_subdirectory(common)
add_subdirectory(rsa_spi)
add_subdirectory(admin)
add_subdirectory(discovery_configured)
@@ -28,7 +27,6 @@ if (REMOTE_SERVICE_ADMIN)
endif()
- #NOTE the toplogy manager is not yet used. The discovery and RSA need to
be refactor for this
+ #NOTE the topology manager is not yet used. The discovery and RSA need to
be refactor for this
#add_subdirectory(topology_manager)
- #add_subdirectory(examples)
endif()
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/admin/include/RemoteServiceAdmin.h
b/bundles/cxx_remote_services/admin/include/RemoteServiceAdmin.h
index 454ff90..969a095 100644
--- a/bundles/cxx_remote_services/admin/include/RemoteServiceAdmin.h
+++ b/bundles/cxx_remote_services/admin/include/RemoteServiceAdmin.h
@@ -17,10 +17,13 @@
* under the License.
*/
-#include "celix/rsa/EndpointDescription.h"
-#include <celix_api.h>
+
#include <mutex>
+
#include "celix/LogHelper.h"
+#include "celix/rsa/EndpointDescription.h"
+#include <celix/rsa/IImportServiceFactory.h>
+#include <celix/rsa/IExportServiceFactory.h>
#if defined(__has_include) && __has_include(<version>)
#include <version>
@@ -28,9 +31,6 @@
#if __cpp_lib_memory_resource
#include <memory_resource>
-#include <celix/rsa/IImportServiceFactory.h>
-#include <celix/rsa/IExportServiceFactory.h>
-
#endif
namespace celix::rsa {
diff --git a/bundles/cxx_remote_services/admin/src/RemoteServiceAdmin.cc
b/bundles/cxx_remote_services/admin/src/RemoteServiceAdmin.cc
index 9a1e09e..207feec 100644
--- a/bundles/cxx_remote_services/admin/src/RemoteServiceAdmin.cc
+++ b/bundles/cxx_remote_services/admin/src/RemoteServiceAdmin.cc
@@ -18,6 +18,8 @@
*/
#include "RemoteServiceAdmin.h"
+#include "celix/BundleContext.h"
+#include "celix/BundleActivator.h"
#include "celix/rsa/RemoteConstants.h"
#include "celix/rsa/IImportServiceFactory.h"
#include "celix/rsa/IExportServiceFactory.h"
diff --git a/bundles/cxx_remote_services/common/CMakeLists.txt
b/bundles/cxx_remote_services/common/CMakeLists.txt
deleted file mode 100644
index 42888bd..0000000
--- a/bundles/cxx_remote_services/common/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-add_library(async_rsa_common INTERFACE)
-target_include_directories(async_rsa_common INTERFACE
- $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
- $<INSTALL_INTERFACE:include/celix/async_rsa_common>
- )
-target_compile_options(async_rsa_common INTERFACE -std=c++17)
-target_link_libraries(async_rsa_common INTERFACE Celix::pubsub_spi
Celix::pubsub_api Celix::rsa_spi)
-#set_target_properties(async_rsa_common PROPERTIES OUTPUT_NAME
"celix_async_rsa_common")
-#target_include_directories(async_rsa_common PRIVATE src)
-#target_link_libraries(async_rsa_common INTERFACE Celix::framework)
-
-#Setup target aliases to match external usage
-add_library(Celix::async_rsa_common ALIAS async_rsa_common)
-install(TARGETS async_rsa_common EXPORT celix DESTINATION
${CMAKE_INSTALL_LIBDIR} COMPONENT async_rsa_common)
-install(DIRECTORY include/ DESTINATION include/celix/async_rsa_common
COMPONENT async_rsa_common)
diff --git
a/bundles/cxx_remote_services/common/include/ExportedServiceFactory.h
b/bundles/cxx_remote_services/common/include/ExportedServiceFactory.h
deleted file mode 100644
index 1db4bae..0000000
--- a/bundles/cxx_remote_services/common/include/ExportedServiceFactory.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#pragma once
-
-#include <celix/dm/DependencyManager.h>
-#include <pubsub_endpoint.h>
-#include <IExportedService.h>
-#include "celix/rsa/EndpointDescription.h"
-
-namespace celix::async_rsa {
- /// Service factory interface.
- struct IExportedServiceFactory {
- virtual ~IExportedServiceFactory() = default;
-
- virtual celix::dm::BaseComponent& create(void* svc, std::string
endpointId) = 0;
- };
-
- /// Default templated Exported service factory. If more than a simple
creation is needed, please create your own factory derived from
IExportedServiceFactory
- /// \tparam Interface
- /// \tparam Implementation
- template <typename SvcInterfaceT, typename WrapperT>
- struct DefaultExportedServiceFactory final : public
IExportedServiceFactory {
- static_assert(std::is_constructible_v<WrapperT, SvcInterfaceT*>,
"Wrapper needs to be constructible from a pointer to the type of svc it wraps");
- static_assert(std::is_base_of_v<celix::async_rsa::IExportedService,
WrapperT>, "Wrapper needs to implement the IExportedService interface");
-
- explicit DefaultExportedServiceFactory(const
std::shared_ptr<celix::dm::DependencyManager> &mng) noexcept : _mng(mng),
_topic(SvcInterfaceT::NAME) {
- std::cout <<
"[DefaultExportedServiceFactory::DefaultExportedServiceFactory]" << std::endl;
- }
- explicit DefaultExportedServiceFactory(const
std::shared_ptr<celix::dm::DependencyManager> &mng, std::string topic) noexcept
: _mng(mng), _topic(std::move(topic)) {
- std::cout <<
"[DefaultExportedServiceFactory::DefaultExportedServiceFactory]" << std::endl;
- }
-
- ~DefaultExportedServiceFactory() noexcept final {
- std::cout <<
"[DefaultExportedServiceFactory::~DefaultExportedServiceFactory]" << std::endl;
- for (auto &[id, cmp] : _subCmps) {
- celix_bundleContext_unregisterService(_mng->bundleContext(),
id);
- }
- _subCmps.clear();
- _mng = nullptr;
- }
-
- celix::dm::BaseComponent& create(void* svc, std::string endpointId)
final {
- std::cout << "[DefaultExportedServiceFactory::create]" <<
std::endl;
-
- auto &cmp = _mng->template
createComponent<WrapperT>(std::make_unique<WrapperT>(static_cast<SvcInterfaceT*>(svc)),
std::string{WrapperT::NAME})
- .template
addInterface<celix::async_rsa::IExportedService>(std::string{SvcInterfaceT::VERSION},
Properties{{celix::rsa::Endpoint::EXPORTS, std::string{SvcInterfaceT::NAME}},
{celix::rsa::Endpoint::IMPORTED, "false"}, {celix::rsa::Endpoint::IDENTIFIER,
endpointId}});
-
- cmp.template
createCServiceDependency<pubsub_publisher_t>(PUBSUB_PUBLISHER_SERVICE_NAME)
- .setVersionRange("[3.0.0,4)")
-
.setFilter(std::string{"(topic="}.append(_topic).append("Ret_").append(endpointId).append(")"))
- .setCallbacks([&cmp](const pubsub_publisher_t * pub,
Properties&&){ cmp.getInstance().setPublisher(pub); })
- .setRequired(true)
- .build();
- cmp.template
createCServiceDependency<pubsub_subscriber_t>(PUBSUB_SUBSCRIBER_SERVICE_NAME)
- .setVersionRange("[3.0.0,4)")
-
.setFilter(std::string{"(topic="}.append(_topic).append("Args_").append(endpointId).append(")"))
- .setRequired(true)
- .build();
-
- auto sub = std::make_unique<pubsub_subscriber_t>();
- sub->handle = &cmp.getInstance();
- sub->init = [](void *) -> int {
- return 0;
- };
- sub->receive = [](void *handle, const char *msgType, unsigned int
msgTypeId, void *msg, const celix_properties_t *metadata, bool *){ return
static_cast<WrapperT*>(handle)->receiveMessage(msgType, msgTypeId, msg,
metadata); };
-
- auto *props = celix_properties_create();
- celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,
std::string{""}.append(_topic).append("Args_").append(endpointId).c_str());
-
- celix_service_registration_options_t opts{};
- opts.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME;
- opts.serviceVersion = PUBSUB_SUBSCRIBER_SERVICE_VERSION;
- opts.svc = sub.get();
- opts.properties = props;
-
- long id =
celix_bundleContext_registerServiceWithOptions(_mng->bundleContext(), &opts);
-
- _subCmps.emplace_back(id, std::move(sub));
- cmp.build();
-
- return cmp;
- }
-
- private:
- std::shared_ptr<celix::dm::DependencyManager> _mng{};
- std::string _topic{};
- std::vector<std::pair<long, std::unique_ptr<pubsub_subscriber_t>>>
_subCmps{};
- };
-}
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/common/include/IExportedService.h
b/bundles/cxx_remote_services/common/include/IExportedService.h
deleted file mode 100644
index 104427a..0000000
--- a/bundles/cxx_remote_services/common/include/IExportedService.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#pragma once
-
-namespace celix::async_rsa {
- struct IExportedService {
- virtual ~IExportedService() = default;
- };
-}
diff --git
a/bundles/cxx_remote_services/common/include/ImportedServiceFactory.h
b/bundles/cxx_remote_services/common/include/ImportedServiceFactory.h
deleted file mode 100644
index 6a342f7..0000000
--- a/bundles/cxx_remote_services/common/include/ImportedServiceFactory.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-#pragma once
-
-#include <celix/dm/DependencyManager.h>
-
-namespace celix::async_rsa {
- /// Service factory interface.
- struct IImportedServiceFactory {
- virtual ~IImportedServiceFactory() = default;
-
- virtual celix::dm::BaseComponent& create(std::string endpointId) = 0;
- };
-
- /// Default templated imported service factory. If more than a simple
creation is needed, please create your own factory derived from
IImportedServiceFactory
- /// \tparam Interface
- /// \tparam Implementation
- template <typename Interface, typename Implementation>
- struct DefaultImportedServiceFactory final : public
IImportedServiceFactory {
- static_assert(std::is_base_of_v<Interface, Implementation>,
"Implementation needs to implement Interface");
-
- explicit DefaultImportedServiceFactory(const
std::shared_ptr<celix::dm::DependencyManager> &mng) noexcept : _mng(mng),
_topic(Interface::NAME) {
- }
- explicit DefaultImportedServiceFactory(const
std::shared_ptr<celix::dm::DependencyManager> &mng, std::string topic) noexcept
: _mng(mng), _topic(std::move(topic)) {
- std::cout <<
"[DefaultExportedServiceFactory::DefaultExportedServiceFactory]" << std::endl;
- }
-
- ~DefaultImportedServiceFactory() noexcept final {
- std::cout << "~DefaultImportedServiceFactory" << std::endl;
- for (auto &[id, cmp] : _subCmps) {
- celix_bundleContext_unregisterService(_mng->bundleContext(),
id);
- }
- _subCmps.clear();
- _mng = nullptr;
- }
-
- celix::dm::BaseComponent& create(std::string endpointId) final {
- auto &cmp = _mng->template
createComponent<Implementation>(std::string{Interface::NAME})
- .template
addInterface<Interface>(std::string{Interface::VERSION});
-
- cmp.template
createCServiceDependency<pubsub_publisher_t>(PUBSUB_PUBLISHER_SERVICE_NAME)
- .setVersionRange("[3.0.0,4)")
-
.setFilter(std::string{"(topic="}.append(_topic).append("Args_").append(endpointId).append(")"))
- .setCallbacks([&cmp](const pubsub_publisher_t * pub,
Properties&&){ cmp.getInstance().setPublisher(pub); })
- .setRequired(true)
- .build();
- cmp.template
createCServiceDependency<pubsub_subscriber_t>(PUBSUB_SUBSCRIBER_SERVICE_NAME)
- .setVersionRange("[3.0.0,4)")
-
.setFilter(std::string{"(topic="}.append(_topic).append("Ret_").append(endpointId).append(")"))
- .setRequired(true)
- .build();
-
- auto sub = std::make_unique<pubsub_subscriber_t>();
- sub->handle = &cmp.getInstance();
- sub->init = [](void *) -> int {
- return 0;
- };
- sub->receive = [](void *handle, const char *msgType, unsigned int
msgTypeId, void *msg, const celix_properties_t *metadata, bool *){ return
static_cast<Implementation*>(handle)->receiveMessage(msgType, msgTypeId, msg,
metadata); };
-
- auto *props = celix_properties_create();
- celix_properties_set(props, PUBSUB_SUBSCRIBER_TOPIC,
std::string{""}.append(_topic).append("Ret_").append(endpointId).c_str());
-
- celix_service_registration_options_t opts{};
- opts.serviceName = PUBSUB_SUBSCRIBER_SERVICE_NAME;
- opts.serviceVersion = PUBSUB_SUBSCRIBER_SERVICE_VERSION;
- opts.svc = sub.get();
- opts.properties = props;
-
- long id =
celix_bundleContext_registerServiceWithOptions(_mng->bundleContext(), &opts);
-
- _subCmps.emplace_back(id, std::move(sub));
- cmp.build();
-
- return cmp;
- }
-
- private:
- std::shared_ptr<celix::dm::DependencyManager> _mng{};
- std::string _topic{};
- std::vector<std::pair<long, std::unique_ptr<pubsub_subscriber_t>>>
_subCmps{};
- };
-}
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/common/src/common.cc
b/bundles/cxx_remote_services/common/src/common.cc
deleted file mode 100644
index 723bd5e..0000000
--- a/bundles/cxx_remote_services/common/src/common.cc
+++ /dev/null
@@ -1,2 +0,0 @@
-
-// empty
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/discovery_configured/CMakeLists.txt
b/bundles/cxx_remote_services/discovery_configured/CMakeLists.txt
index 833b718..39850ef 100644
--- a/bundles/cxx_remote_services/discovery_configured/CMakeLists.txt
+++ b/bundles/cxx_remote_services/discovery_configured/CMakeLists.txt
@@ -22,6 +22,7 @@ add_library(RsaConfiguredDiscovery_api INTERFACE)
target_include_directories(RsaConfiguredDiscovery_api INTERFACE
include
)
+add_library(Celix::RsaConfiguredDiscovery_api ALIAS RsaConfiguredDiscovery_api)
add_celix_bundle(RsaConfiguredDiscovery
VERSION 0.9.0
diff --git a/bundles/cxx_remote_services/examples/CMakeLists.txt
b/bundles/cxx_remote_services/examples/CMakeLists.txt
deleted file mode 100644
index 3aa8ee4..0000000
--- a/bundles/cxx_remote_services/examples/CMakeLists.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-add_celix_bundle(hardcoded_example_provider
- SOURCES
- HardcodedExampleProvider.cc
- HardcodedExampleSerializer.cc
- SYMBOLIC_NAME "apache_celix_hardcoded_example_service_provider"
- VERSION 0.0.1
- )
-add_celix_bundle(hardcoded_example_subscriber
- SOURCES
- HardcodedExampleSubscriber.cc
- HardcodedExampleSerializer.cc
- SYMBOLIC_NAME "apache_celix_hardcoded_example_service_subscriber"
- VERSION 0.0.1
- )
-
-celix_bundle_files(hardcoded_example_provider
-
${CMAKE_CURRENT_SOURCE_DIR}/pubsub_properties/IHardcodedService.properties
- DESTINATION "META-INF/topics/pub"
- )
-celix_bundle_files(hardcoded_example_provider
-
${CMAKE_CURRENT_SOURCE_DIR}/pubsub_properties/IHardcodedService.properties
- DESTINATION "META-INF/topics/sub"
- )
-
-celix_bundle_files(hardcoded_example_subscriber
-
${CMAKE_CURRENT_SOURCE_DIR}/pubsub_properties/IHardcodedService.properties
- DESTINATION "META-INF/topics/pub"
- )
-celix_bundle_files(hardcoded_example_subscriber
-
${CMAKE_CURRENT_SOURCE_DIR}/pubsub_properties/IHardcodedService.properties
- DESTINATION "META-INF/topics/sub"
- )
-
-target_link_libraries(hardcoded_example_provider PRIVATE Celix::framework
Celix::async_rsa_common)
-target_link_libraries(hardcoded_example_subscriber PRIVATE Celix::framework
Celix::async_rsa_common)
-target_compile_options(hardcoded_example_provider INTERFACE -std=c++17)
-target_compile_options(hardcoded_example_subscriber INTERFACE -std=c++17)
-
-set(PUBSUB_CONTAINER_LIBS
- Jansson
- ZMQ::lib
- CZMQ::lib
- Celix::pubsub_api
- Celix::pubsub_spi
- Celix::async_rsa_common
- Celix::Promises)
-
-find_package(ZMQ REQUIRED)
-find_package(CZMQ REQUIRED)
-find_package(Jansson REQUIRED)
-add_celix_container(hardcoded_example_provider_cnt
- GROUP async_rsa
- BUNDLES
- Celix::log_admin
- Celix::shell
- Celix::shell_tui
- Celix::pubsub_serializer_json
- Celix::pubsub_discovery_etcd
- Celix::pubsub_topology_manager
- Celix::pubsub_admin_zmq_v2
- Celix::pubsub_protocol_wire_v2
- Celix::async_rsa_discovery_configured
- Celix::async_topology_manager
- Celix::RemoteServiceAdmin
- hardcoded_example_provider
- PROPERTIES
- "org.osgi.framework.storage=.publisherCache"
-
"CELIX_ASYNC_RSA_CONFIGURED_DISCOVERY_FILE=/home/oipo-unencrypted/Programming/celix/bundles/async_remote_services/examples/discovery/endpoint.json"
- )
-target_link_libraries(hardcoded_example_provider PRIVATE
${PUBSUB_CONTAINER_LIBS})
-
-add_celix_container(hardcoded_example_subscriber_cnt
- GROUP async_rsa
- BUNDLES
- Celix::log_admin
- Celix::shell
- Celix::shell_tui
- Celix::pubsub_serializer_json
- Celix::pubsub_discovery_etcd
- Celix::pubsub_topology_manager
- Celix::pubsub_admin_zmq_v2
- Celix::pubsub_protocol_wire_v2
- Celix::async_rsa_discovery_configured
- Celix::async_topology_manager
- Celix::RemoteServiceAdmin
- hardcoded_example_subscriber
- PROPERTIES
- "org.osgi.framework.storage=.subscriberCache"
-
"CELIX_ASYNC_RSA_CONFIGURED_DISCOVERY_FILE=/home/oipo-unencrypted/Programming/celix/bundles/async_remote_services/examples/discovery/endpoint.json"
- )
-target_link_libraries(hardcoded_example_subscriber PRIVATE
${PUBSUB_CONTAINER_LIBS})
diff --git a/bundles/cxx_remote_services/examples/HardcodedExampleProvider.cc
b/bundles/cxx_remote_services/examples/HardcodedExampleProvider.cc
deleted file mode 100644
index 4cbbc11..0000000
--- a/bundles/cxx_remote_services/examples/HardcodedExampleProvider.cc
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <celix_api.h>
-#include <string>
-#include <celix/Deferred.h>
-#include <pubsub/api.h>
-#include "HardcodedExampleSerializer.h"
-#include "IHardcodedService.h"
-#include <IExportedService.h>
-#include <celix/PromiseFactory.h>
-#include <ExportedServiceFactory.h>
-
-struct HardcodedService final : public IHardcodedService {
- HardcodedService() {
- std::cout << "started HardcodedService" << std::endl;
- }
- ~HardcodedService() final = default;
-
- celix::Promise<int> add(int a, int b) noexcept final {
- std::cout << "[HardcodedService] add " << a << " + " << b << std::endl;
- auto deferred = _factory.deferred<int>();
- deferred.resolve(a + b);
- return deferred.getPromise();
- }
-
- celix::Promise<int> subtract(int a, int b) noexcept final {
- std::cout << "[HardcodedService] subtract " << a << " + " << b <<
std::endl;
- auto deferred = _factory.deferred<int>();
- deferred.resolve(a - b);
- return deferred.getPromise();
- }
-
- celix::Promise<std::string> toString(int a) noexcept final {
- std::cout << "[HardcodedService] toString " << a << std::endl;
- auto deferred = _factory.deferred<std::string>();
- deferred.resolve(std::to_string(a));
- return deferred.getPromise();
- }
-
-private:
- celix::PromiseFactory _factory{};
-};
-
-struct ExportedHardcodedService final : public
celix::async_rsa::IExportedService {
-
- static constexpr std::string_view VERSION = "1.0.0";
- static constexpr std::string_view NAME = "ExportedHardcodedService";
-
- ExportedHardcodedService(IHardcodedService *svc) noexcept : _svc(svc) {};
- ~ExportedHardcodedService() final = default;
-
- ExportedHardcodedService(ExportedHardcodedService const &) = delete;
- ExportedHardcodedService(ExportedHardcodedService &&) = default;
- ExportedHardcodedService& operator=(ExportedHardcodedService const &) =
delete;
- ExportedHardcodedService& operator=(ExportedHardcodedService &&) = default;
-
- void setPublisher(pubsub_publisher_t const * publisher) {
- _publisher = publisher;
- }
-
- int receiveMessage(const char *, unsigned int msgTypeId, void *msg, const
celix_properties_t *) {
- std::cout << "[ExportedHardcodedService] receiveMessage" << std::endl;
- if(msgTypeId == 1) {
- auto response = static_cast<AddArgs*>(msg);
-
- if(response->ret) {
- return 0;
- }
-
- response->ret = _svc->add(response->a, response->b).getValue();
- _publisher->send(_publisher->handle, 1, response, nullptr);
- } else if(msgTypeId == 2) {
- auto response = static_cast<SubtractArgs*>(msg);
-
- if(response->ret) {
- return 0;
- }
-
- response->ret = _svc->subtract(response->a,
response->b).getValue();
- _publisher->send(_publisher->handle, 1, response, nullptr);
- } else if(msgTypeId == 3) {
- auto response = static_cast<ToStringArgs*>(msg);
-
- if(response->ret) {
- return 0;
- }
-
- response->ret = _svc->toString(response->a).getValue();
- _publisher->send(_publisher->handle, 1, response, nullptr);
- }
-
- return 0;
- }
-
-private:
- IHardcodedService *_svc{};
- pubsub_publisher_t const *_publisher{};
-};
-
-class ExampleActivator {
-public:
- explicit ExampleActivator(const
std::shared_ptr<celix::dm::DependencyManager>& mng) {
- std::cout << "[ExampleActivator::ExampleActivator]" << std::endl;
- _addArgsSerializer.emplace(mng);
- _subtractArgsSerializer.emplace(mng);
- _toStringSerializer.emplace(mng);
-
-
mng->createComponent<HardcodedService>().addInterfaceWithName<IHardcodedService>(std::string{IHardcodedService::NAME},
std::string{IHardcodedService::VERSION}, Properties{{"remote", "true"},
{celix::rsa::Endpoint::IDENTIFIER, "id-01"}, {celix::rsa::Endpoint::EXPORTS,
"IHardcodedService"}}).build();
- auto& factory =
mng->createComponent(std::make_unique<celix::async_rsa::DefaultExportedServiceFactory<IHardcodedService,
ExportedHardcodedService>>(mng))
-
.addInterface<celix::async_rsa::IExportedServiceFactory>("1.0.0",
Properties{{celix::rsa::Endpoint::EXPORTS, "IHardcodedService"}}).build();
-
- _factory = &factory;
- }
-
- ExampleActivator(const ExampleActivator &) = delete;
- ExampleActivator &operator=(const ExampleActivator &) = delete;
-
-private:
- std::optional<AddArgsSerializer> _addArgsSerializer{};
- std::optional<SubtractArgsSerializer> _subtractArgsSerializer{};
- std::optional<ToStringArgsSerializer> _toStringSerializer{};
-
Component<celix::async_rsa::DefaultExportedServiceFactory<IHardcodedService,
ExportedHardcodedService>> *_factory{};
-};
-
-CELIX_GEN_CXX_BUNDLE_ACTIVATOR(ExampleActivator)
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.cc
b/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.cc
deleted file mode 100644
index a0452e2..0000000
--- a/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-//
-// Created by oipo on 01-03-21.
-//
-
-#include "HardcodedExampleSerializer.h"
-#include <rapidjson/document.h>
-#include <rapidjson/writer.h>
-
-AddArgsSerializer::AddArgsSerializer(std::shared_ptr<celix::dm::DependencyManager>
mng) : _mng(std::move(mng)) {
- _svc.deserialize = [](void*, const struct iovec* input, size_t, void**
out) -> celix_status_t {
- rapidjson::Document d{};
- d.Parse(static_cast<char*>(input->iov_base));
-
- if(d.HasParseError()) {
- return CELIX_ILLEGAL_ARGUMENT;
- }
-
- int id = d["id"].GetInt();
- int a = d["a"].GetInt();
- int b = d["b"].GetInt();
- decltype(AddArgs::ret) ret = d.HasMember("ret") ? d["ret"].GetInt() :
decltype(AddArgs::ret){};
-
- *out = new AddArgs{id, a, b, ret};
-
- return CELIX_SUCCESS;
- };
- _svc.freeDeserializedMsg = [](void*, void* msg) {
- delete static_cast<AddArgs*>(msg);
- };
-
- _svc.serialize = [](void*, const void* input, struct iovec** output,
size_t* outputIovLen) -> celix_status_t {
- auto *args = static_cast<AddArgs const *>(input);
-
- if (*output == nullptr) {
- *output = static_cast<iovec *>(calloc(1, sizeof(struct iovec)));
- if (outputIovLen){
- *outputIovLen = 1;
- }
- }
-
- rapidjson::StringBuffer sb;
- rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
-
- writer.StartObject();
-
- writer.String("id");
- writer.Int(args->id);
-
- writer.String("a");
- writer.Int(args->a);
-
- writer.String("b");
- writer.Int(args->b);
-
- if(args->ret) {
- writer.String("ret");
- writer.Int(args->ret.value());
- }
-
- writer.EndObject();
-
- (*output)->iov_base = strndup(sb.GetString(), sb.GetSize() + 1);
- (*output)->iov_len = sb.GetSize() + 1;
-
- return CELIX_SUCCESS;
- };
-
- _svc.freeSerializedMsg = [](void*, struct iovec* input, size_t) {
- free(input->iov_base);
- free(input);
- };
-
- celix_properties_t* props = celix_properties_create();
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, "AddArgs");
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, "1.0.0");
- celix_properties_setLong(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, 1LL);
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, "json");
-
- celix_service_registration_options_t opts{};
- opts.svc = &_svc;
- opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME;
- opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION;
- opts.properties = props;
- _svcId =
celix_bundleContext_registerServiceWithOptions(_mng->bundleContext(), &opts);
-}
-
-SubtractArgsSerializer::SubtractArgsSerializer(std::shared_ptr<celix::dm::DependencyManager>
mng) : _mng(std::move(mng)) {
- _svc.handle = this;
- _svc.deserialize = [](void*, const struct iovec* input, size_t, void**
out) -> celix_status_t {
- rapidjson::Document d{};
- d.Parse(static_cast<char*>(input->iov_base));
-
- if(d.HasParseError()) {
- return CELIX_ILLEGAL_ARGUMENT;
- }
-
- int id = d["id"].GetInt();
- int a = d["a"].GetInt();
- int b = d["b"].GetInt();
- decltype(SubtractArgs::ret) ret = d.HasMember("ret") ?
d["ret"].GetInt() : decltype(SubtractArgs::ret){};
-
- *out = new SubtractArgs{id, a, b, ret};
-
- return CELIX_SUCCESS;
- };
- _svc.freeDeserializedMsg = [](void*, void* msg) {
- delete static_cast<SubtractArgs*>(msg);
- };
-
- _svc.serialize = [](void*, const void* input, struct iovec** output,
size_t* outputIovLen) -> celix_status_t {
- auto *args = static_cast<SubtractArgs const *>(input);
-
- if (*output == nullptr) {
- *output = static_cast<iovec *>(calloc(1, sizeof(struct iovec)));
- if (outputIovLen){
- *outputIovLen = 1;
- }
- }
-
- rapidjson::StringBuffer sb;
- rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
-
- writer.StartObject();
-
- writer.String("id");
- writer.Int(args->id);
-
- writer.String("a");
- writer.Int(args->a);
-
- writer.String("b");
- writer.Int(args->b);
-
- if(args->ret) {
- writer.String("ret");
- writer.Int(args->ret.value());
- }
-
- writer.EndObject();
-
- (*output)->iov_base = strndup(sb.GetString(), sb.GetSize() + 1);
- (*output)->iov_len = sb.GetSize() + 1;
-
- return CELIX_SUCCESS;
- };
-
- _svc.freeSerializedMsg = [](void*, struct iovec* input, size_t) {
- free(input->iov_base);
- free(input);
- };
-
- celix_properties_t* props = celix_properties_create();
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, "SubtractArgs");
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, "1.0.0");
- celix_properties_setLong(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, 2LL);
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, "json");
-
- celix_service_registration_options_t opts{};
- opts.svc = &_svc;
- opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME;
- opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION;
- opts.properties = props;
- _svcId =
celix_bundleContext_registerServiceWithOptions(_mng->bundleContext(), &opts);
-}
-
-ToStringArgsSerializer::ToStringArgsSerializer(std::shared_ptr<celix::dm::DependencyManager>
mng) : _mng(std::move(mng)) {
- _svc.handle = this;
- _svc.deserialize = [](void*, const struct iovec* input, size_t, void**
out) -> celix_status_t {
- rapidjson::Document d{};
- d.Parse(static_cast<char*>(input->iov_base));
-
- if(d.HasParseError()) {
- return CELIX_ILLEGAL_ARGUMENT;
- }
-
- int id = d["id"].GetInt();
- int a = d["a"].GetInt();
- decltype(ToStringArgs::ret) ret = d.HasMember("ret") ?
d["ret"].GetString() : decltype(ToStringArgs::ret){};
-
- *out = new ToStringArgs{id, a, ret};
-
- return CELIX_SUCCESS;
- };
- _svc.freeDeserializedMsg = [](void*, void* msg) {
- delete static_cast<ToStringArgs*>(msg);
- };
-
- _svc.serialize = [](void*, const void* input, struct iovec** output,
size_t* outputIovLen) -> celix_status_t {
- auto *args = static_cast<ToStringArgs const *>(input);
-
- if (*output == nullptr) {
- *output = static_cast<iovec *>(calloc(1, sizeof(struct iovec)));
- if (outputIovLen){
- *outputIovLen = 1;
- }
- }
-
- rapidjson::StringBuffer sb;
- rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
-
- writer.StartObject();
-
- writer.String("id");
- writer.Int(args->id);
-
- writer.String("a");
- writer.Int(args->a);
-
- if(args->ret) {
- writer.String("ret");
- writer.String(args->ret.value().c_str(), args->ret.value().size());
- }
-
- writer.EndObject();
-
- (*output)->iov_base = strndup(sb.GetString(), sb.GetSize() + 1);
- (*output)->iov_len = sb.GetSize() + 1;
-
- return CELIX_SUCCESS;
- };
-
- _svc.freeSerializedMsg = [](void*, struct iovec* input, size_t) {
- free(input->iov_base);
- free(input);
- };
-
- celix_properties_t* props = celix_properties_create();
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_FQN_PROPERTY, "ToStringArgs");
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_VERSION_PROPERTY, "1.0.0");
- celix_properties_setLong(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_MSG_ID_PROPERTY, 3LL);
- celix_properties_set(props,
PUBSUB_MESSAGE_SERIALIZATION_SERVICE_SERIALIZATION_TYPE_PROPERTY, "json");
-
- celix_service_registration_options_t opts{};
- opts.svc = &_svc;
- opts.serviceName = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_NAME;
- opts.serviceVersion = PUBSUB_MESSAGE_SERIALIZATION_SERVICE_VERSION;
- opts.properties = props;
- _svcId =
celix_bundleContext_registerServiceWithOptions(_mng->bundleContext(), &opts);
-}
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.h
b/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.h
deleted file mode 100644
index 9a34fb6..0000000
--- a/bundles/cxx_remote_services/examples/HardcodedExampleSerializer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#pragma once
-
-#include <celix/dm/DependencyManager.h>
-#include <pubsub_message_serialization_service.h>
-#include <sys/uio.h>
-#include <pubsub_constants.h>
-
-#include <utility>
-
-struct AddArgs {
- int id{};
- int a{};
- int b{};
- std::optional<int> ret{};
-};
-
-struct SubtractArgs {
- int id{};
- int a{};
- int b{};
- std::optional<int> ret{};
-};
-
-struct ToStringArgs {
- int id{};
- int a{};
- std::optional<std::string> ret{};
-};
-
-struct AddArgsSerializer {
- explicit AddArgsSerializer(std::shared_ptr<celix::dm::DependencyManager>
mng);
-
- ~AddArgsSerializer() {
- celix_bundleContext_unregisterService(_mng->bundleContext(), _svcId);
- }
-
-private:
- std::shared_ptr<celix::dm::DependencyManager> _mng{};
- pubsub_message_serialization_service _svc{};
- long _svcId{};
-};
-
-struct SubtractArgsSerializer {
- explicit
SubtractArgsSerializer(std::shared_ptr<celix::dm::DependencyManager> mng);
-
- ~SubtractArgsSerializer() {
- celix_bundleContext_unregisterService(_mng->bundleContext(), _svcId);
- }
-
-private:
- std::shared_ptr<celix::dm::DependencyManager> _mng{};
- pubsub_message_serialization_service _svc{};
- long _svcId{};
-};
-
-struct ToStringArgsSerializer {
- explicit
ToStringArgsSerializer(std::shared_ptr<celix::dm::DependencyManager> mng);
-
- ToStringArgsSerializer(ToStringArgsSerializer const &) = delete;
- ToStringArgsSerializer(ToStringArgsSerializer&&) = default;
- ToStringArgsSerializer& operator=(ToStringArgsSerializer const &) = delete;
- ToStringArgsSerializer& operator=(ToStringArgsSerializer &&) = default;
-
- ~ToStringArgsSerializer() {
- celix_bundleContext_unregisterService(_mng->bundleContext(), _svcId);
- }
-
-private:
- std::shared_ptr<celix::dm::DependencyManager> _mng{};
- pubsub_message_serialization_service _svc{};
- long _svcId{};
-};
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/examples/HardcodedExampleSubscriber.cc
b/bundles/cxx_remote_services/examples/HardcodedExampleSubscriber.cc
deleted file mode 100644
index da96839..0000000
--- a/bundles/cxx_remote_services/examples/HardcodedExampleSubscriber.cc
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <celix_api.h>
-#include <string>
-#include <mutex>
-#include <ImportedServiceFactory.h>
-#include <pubsub/api.h>
-#include <celix/Deferred.h>
-#include <celix/PromiseFactory.h>
-#include <ConfiguredEndpoint.h>
-#include "IHardcodedService.h"
-#include "HardcodedExampleSerializer.h"
-
-#if defined(__has_include) && __has_include(<version>)
-#include <version>
-#endif
-
-#if __cpp_lib_memory_resource
-#include <memory_resource>
-#endif
-
-struct ImportedHardcodedService final : public IHardcodedService {
- ImportedHardcodedService() = default;
- ~ImportedHardcodedService() final = default;
-
- ImportedHardcodedService(const ImportedHardcodedService&) = delete;
- ImportedHardcodedService(ImportedHardcodedService&&) = delete;
- ImportedHardcodedService& operator=(const ImportedHardcodedService&) =
delete;
- ImportedHardcodedService& operator=(ImportedHardcodedService&&) = delete;
-
- celix::Promise<int> add(int a, int b) noexcept final {
- std::cout << "[ImportedHardcodedService] add " << a << " + " << b <<
std::endl;
- std::unique_lock l(_m);
- AddArgs args{_idCounter++, a, b, {}};
- _publisher->send(_publisher->handle, 1, &args, nullptr);
-
- auto deferred = _factory.deferred<int>();
- auto it = _intPromises.emplace(args.id, std::move(deferred));
- return it.first->second.getPromise();
- }
-
- celix::Promise<int> subtract(int a, int b) noexcept final {
- std::cout << "[ImportedHardcodedService] subtract " << a << " + " << b
<< std::endl;
- std::unique_lock l(_m);
- SubtractArgs args{_idCounter++, a, b, {}};
- _publisher->send(_publisher->handle, 2, &args, nullptr);
-
- auto deferred = _factory.deferred<int>();
- auto it = _intPromises.emplace(args.id, std::move(deferred));
- return it.first->second.getPromise();
- }
-
- celix::Promise<std::string> toString(int a) noexcept final {
- std::cout << "[ImportedHardcodedService] toString " << a << std::endl;
- std::unique_lock l(_m);
- ToStringArgs args{_idCounter++, a, {}};
- _publisher->send(_publisher->handle, 3, &args, nullptr);
-
- auto deferred = _factory.deferred<std::string>();
- auto it = _stringPromises.emplace(args.id, std::move(deferred));
- return it.first->second.getPromise();
- }
-
- void setPublisher(pubsub_publisher_t const * publisher) {
- _publisher = publisher;
- }
-
- int receiveMessage(const char *, unsigned int msgTypeId, void *msg, const
celix_properties_t *) {
- std::cout << "[ImportedHardcodedService] receiveMessage" << std::endl;
- std::unique_lock l(_m);
- if(msgTypeId == 1) {
- auto response = static_cast<AddArgs*>(msg);
-
- if(!response->ret) {
- return 0;
- }
-
- auto deferred = _intPromises.find(response->id);
- if(deferred == end(_intPromises) || !response->ret) {
- return 1;
- }
- deferred->second.resolve(response->ret.value());
- _intPromises.erase(deferred);
- } else if(msgTypeId == 2) {
- auto response = static_cast<SubtractArgs*>(msg);
-
- if(!response->ret) {
- return 0;
- }
-
- auto deferred = _intPromises.find(response->id);
- if(deferred == end(_intPromises) || !response->ret) {
- return 1;
- }
- deferred->second.resolve(response->ret.value());
- _intPromises.erase(deferred);
- } else if(msgTypeId == 3) {
- auto response = static_cast<ToStringArgs*>(msg);
-
- if(!response->ret) {
- return 0;
- }
-
- auto deferred = _stringPromises.find(response->id);
- if(deferred == end(_stringPromises) || !response->ret) {
- return 1;
- }
- deferred->second.resolve(response->ret.value());
- _stringPromises.erase(deferred);
- }
-
- return 0;
- }
-
-private:
- std::mutex _m{};
- pubsub_publisher_t const *_publisher{};
-#if __cpp_lib_memory_resource
- std::pmr::unsynchronized_pool_resource _resource{};
- std::pmr::unordered_map<int, celix::Deferred<int>>
_intPromises{&_resource};
- std::pmr::unordered_map<int, celix::Deferred<std::string>>
_stringPromises{&_resource};
-#else
- std::unordered_map<int, celix::Deferred<int>> _intPromises{};
- std::unordered_map<int, celix::Deferred<std::string>> _stringPromises{};
-#endif
- static std::atomic<int> _idCounter;
- celix::PromiseFactory _factory{};
-};
-
-std::atomic<int> ImportedHardcodedService::_idCounter = 0;
-
-struct UsingHardcodedServiceService {
-
- void setService(IHardcodedService * svc, Properties&&) {
- _svc = svc;
- }
-
- void start() {
- _t = std::thread([this]() {
- _svc->add(14, 123).thenAccept([](int val) {
- std::cout << "[UsingHardcodedServiceService] add(14, 123)
returned " << val << std::endl;
- }).timeout(std::chrono::seconds(10)).wait();
- });
- }
-
- void stop() {
- if(_t.joinable()) {
- _t.join();
- }
- }
-
-private:
- IHardcodedService *_svc{};
- std::thread _t{};
-};
-
-class ExampleActivator {
-public:
- explicit ExampleActivator(std::shared_ptr<celix::dm::DependencyManager>
mng) {
- _addArgsSerializer.emplace(mng);
- _subtractArgsSerializer.emplace(mng);
- _toStringSerializer.emplace(mng);
-
- auto& factory =
mng->createComponent(std::make_unique<celix::async_rsa::DefaultImportedServiceFactory<IHardcodedService,
ImportedHardcodedService>>(mng))
- .addInterface<celix::async_rsa::IImportedServiceFactory>("1.0.0",
Properties{{celix::rsa::Endpoint::EXPORTS, "IHardcodedService"}}).build();
- _factory = &factory;
-
- auto &usingCmp = mng->createComponent<UsingHardcodedServiceService>()
- .setCallbacks(nullptr, &UsingHardcodedServiceService::start,
&UsingHardcodedServiceService::stop, nullptr);
-
-
usingCmp.createServiceDependency<IHardcodedService>().setCallbacks([cmp =
&usingCmp](IHardcodedService *svc, Properties&& props) {
- cmp->getInstance().setService(svc,
std::forward<Properties>(props));
- })
- .setRequired(true)
- .build();
-
- usingCmp.build();
- }
-
- ExampleActivator(const ExampleActivator &) = delete;
- ExampleActivator &operator=(const ExampleActivator &) = delete;
-
-private:
- std::optional<AddArgsSerializer> _addArgsSerializer{};
- std::optional<SubtractArgsSerializer> _subtractArgsSerializer{};
- std::optional<ToStringArgsSerializer> _toStringSerializer{};
-
Component<celix::async_rsa::DefaultImportedServiceFactory<IHardcodedService,
ImportedHardcodedService>> *_factory{};
-};
-
-CELIX_GEN_CXX_BUNDLE_ACTIVATOR(ExampleActivator)
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/examples/IHardcodedService.h
b/bundles/cxx_remote_services/examples/IHardcodedService.h
deleted file mode 100644
index ba87878..0000000
--- a/bundles/cxx_remote_services/examples/IHardcodedService.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <celix/Promise.h>
-
-struct IHardcodedService {
- virtual ~IHardcodedService() = default;
-
- virtual celix::Promise<int> add(int a, int b) noexcept = 0;
- virtual celix::Promise<int> subtract(int a, int b) noexcept = 0;
- virtual celix::Promise<std::string> toString(int a) = 0;
-
- static constexpr std::string_view VERSION = "1.0.0";
- static constexpr std::string_view NAME = "IHardcodedService";
-};
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/examples/discovery/endpoint.json
b/bundles/cxx_remote_services/examples/discovery/endpoint.json
deleted file mode 100644
index c8d65fc..0000000
--- a/bundles/cxx_remote_services/examples/discovery/endpoint.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "endpoints": [
- {
- "endpoint.id": "id-01",
- "service.imported": true,
- "service.imported.configs": [
- "pubsub"
- ],
- "service.exported.interfaces": "IHardcodedService",
- "endpoint.objectClass": "TestComponentName",
- "endpoint.scope": "default",
- "endpoint.topic": "default"
- },
- {
- "endpoint.id": "id-02",
- "service.imported": true,
- "service.imported.configs": [
- "pubsub"
- ],
- "service.exported.interfaces": "*",
- "endpoint.objectClass": "TestComponentName",
- "endpoint.scope": "default",
- "endpoint.topic": "default"
- }
- ]
-}
\ No newline at end of file
diff --git
a/bundles/cxx_remote_services/examples/pubsub_properties/IHardcodedService.properties
b/bundles/cxx_remote_services/examples/pubsub_properties/IHardcodedService.properties
deleted file mode 100644
index 044c2e0..0000000
---
a/bundles/cxx_remote_services/examples/pubsub_properties/IHardcodedService.properties
+++ /dev/null
@@ -1,27 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-tcp.static.bind.url=tcp://localhost:9500
-tcp.passive.key=tcp://localhost:9500
-
-topic.name=IHardcodedService
-topic.id=IHardcodedService
-
-#Interface info
-interface.name=IHardcodedService
-interface.version=1.0.0
-interface.messages=IHardcodedService
-
diff --git a/bundles/cxx_remote_services/integration/CMakeLists.txt
b/bundles/cxx_remote_services/integration/CMakeLists.txt
index d12a42f..7f72d05 100644
--- a/bundles/cxx_remote_services/integration/CMakeLists.txt
+++ b/bundles/cxx_remote_services/integration/CMakeLists.txt
@@ -39,10 +39,12 @@ target_compile_options(CalculatorProvider PRIVATE
-std=c++17) #TODO how can this
add_celix_bundle(CalculatorConsumer
SOURCES src/CalculatorConsumer.cc
)
-target_link_libraries(CalculatorConsumer PRIVATE Celix::Promises)
+celix_bundle_files(CalculatorConsumer
${CMAKE_CURRENT_SOURCE_DIR}/resources/endpoint_discovery.json DESTINATION
"META-INF/discovery") # add configured discovery as resource in the bundle.
+target_link_libraries(CalculatorConsumer PRIVATE Celix::Promises
Celix::shell_api Celix::RsaConfiguredDiscovery_api)
target_include_directories(CalculatorConsumer PRIVATE include)
target_compile_options(CalculatorConsumer PRIVATE -std=c++17) #TODO how can
this be improved (bring back -std=c++17 on INTERFACE for promises?
+add_subdirectory(gtest)
################# Integration examples ##################################
@@ -55,7 +57,7 @@ add_celix_container(RemoteCalculatorProvider
#PSA_ZMQ_STATIC_BIND_URL_FOR_test_return=ipc:///tmp/pubsub-test-return
#PSA_ZMQ_STATIC_CONNECT_URL_FOR_test_invoke=ipc:///tmp/pubsub-test-invoke
BUNDLES
- Celix::shell
+ Celix::ShellCxx
Celix::shell_tui
#Needed for remote services (full pubsub stack + remote services
stack)
@@ -79,9 +81,8 @@ add_celix_container(RemoteCalculatorConsumer
#Configuration to let the pubsub zmq operate without dicscovery
#PSA_ZMQ_STATIC_BIND_URL_FOR_test_invoke=ipc:///tmp/pubsub-test-invoke
#PSA_ZMQ_STATIC_CONNECT_URL_FOR_test_return=ipc:///tmp/pubsub-test-return
-
CELIX_RSA_CONFIGURED_DISCOVERY_DISCOVERY_FILES=${CMAKE_CURRENT_SOURCE_DIR}/resources/endpoint_discovery.json
BUNDLES
- Celix::shell
+ Celix::ShellCxx
Celix::shell_tui
#Needed for remote services (full pubsub stack + remote services
stack)
diff --git a/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt
b/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt
new file mode 100644
index 0000000..9b03a0f
--- /dev/null
+++ b/bundles/cxx_remote_services/integration/gtest/CMakeLists.txt
@@ -0,0 +1,67 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+add_executable(test_cxx_remote_services_integration
+ src/RemoteServicesIntegrationTestSuite.cc
+)
+target_link_libraries(test_cxx_remote_services_integration PRIVATE
Celix::framework GTest::gtest GTest::gtest_main)
+target_compile_options(test_cxx_remote_services_integration PRIVATE -std=c++17)
+target_include_directories(test_cxx_remote_services_integration PRIVATE
../include) #Add ICalculator
+
+add_celix_bundle_dependencies(test_cxx_remote_services_integration
+ Celix::pubsub_serializer_json
+ Celix::pubsub_topology_manager
+ Celix::pubsub_admin_zmq
+ Celix::pubsub_protocol_wire_v2
+ Celix::RsaConfiguredDiscovery
+ Celix::RemoteServiceAdmin
+ TestExportImportRemoteServiceFactory
+ CalculatorProvider
+ CalculatorConsumer
+)
+
+celix_get_bundle_file(Celix::pubsub_serializer_json PS_SER_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
PS_SER_BUNDLE_LOC="${PS_SER_BUNDLE_LOC}")
+
+celix_get_bundle_file(Celix::pubsub_topology_manager PS_PSTM_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
PS_PSTM_BUNDLE_LOC="${PS_PSTM_BUNDLE_LOC}")
+
+celix_get_bundle_file(Celix::pubsub_admin_zmq PS_PSA_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
PS_PSA_BUNDLE_LOC="${PS_PSA_BUNDLE_LOC}")
+
+celix_get_bundle_file(Celix::pubsub_protocol_wire_v2 PS_WIRE_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
PS_WIRE_BUNDLE_LOC="${PS_WIRE_BUNDLE_LOC}")
+
+celix_get_bundle_file(Celix::RsaConfiguredDiscovery RS_DISCOVERY_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
RS_DISCOVERY_BUNDLE_LOC="${RS_DISCOVERY_BUNDLE_LOC}")
+
+celix_get_bundle_file(Celix::RemoteServiceAdmin RS_RSA_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
RS_RSA_BUNDLE_LOC="${RS_RSA_BUNDLE_LOC}")
+
+celix_get_bundle_file(TestExportImportRemoteServiceFactory
RS_FACTORY_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
RS_FACTORY_BUNDLE_LOC="${RS_FACTORY_BUNDLE_LOC}")
+
+celix_get_bundle_file(CalculatorProvider RS_PROVIDER_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
RS_PROVIDER_BUNDLE_LOC="${RS_PROVIDER_BUNDLE_LOC}")
+
+celix_get_bundle_file(CalculatorConsumer RS_CONSUMER_BUNDLE_LOC)
+target_compile_definitions(test_cxx_remote_services_integration PRIVATE
RS_CONSUMER_BUNDLE_LOC="${RS_CONSUMER_BUNDLE_LOC}")
+
+
+
+add_test(NAME test_cxx_remote_services_integration COMMAND
test_cxx_remote_services_integration)
+setup_target_for_coverage(test_cxx_remote_services_integration SCAN_DIR ../..)
\ No newline at end of file
diff --git
a/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc
b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc
new file mode 100644
index 0000000..9e460ba
--- /dev/null
+++
b/bundles/cxx_remote_services/integration/gtest/src/RemoteServicesIntegrationTestSuite.cc
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "celix/FrameworkFactory.h"
+
+class RemoteServicesIntegrationTestSuite : public ::testing::Test {
+public:
+ RemoteServicesIntegrationTestSuite() {
+ celix::Properties clientConfig{
+ {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "trace"},
+ {celix::FRAMEWORK_CACHE_DIR, ".clientCache"}
+ };
+ clientFw = celix::createFramework(clientConfig);
+ clientCtx = clientFw->getFrameworkBundleContext();
+
+ celix::Properties serverConfig{
+ {"CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL", "trace"},
+ {celix::FRAMEWORK_CACHE_DIR, ".serverCache"}
+ };
+ serverFw = celix::createFramework(serverConfig);
+ serverCtx = serverFw->getFrameworkBundleContext();
+ }
+
+ void installSharedBundles(std::shared_ptr<celix::BundleContext>& ctx) {
+ auto sharedBundles = {
+ PS_SER_BUNDLE_LOC,
+ PS_PSTM_BUNDLE_LOC,
+ PS_PSA_BUNDLE_LOC,
+ PS_WIRE_BUNDLE_LOC,
+ RS_DISCOVERY_BUNDLE_LOC,
+ RS_RSA_BUNDLE_LOC,
+ RS_FACTORY_BUNDLE_LOC };
+ for (const auto& bndLoc : sharedBundles) {
+ auto bndId = ctx->installBundle(bndLoc);
+ EXPECT_GE(bndId, 0);
+ }
+ }
+
+ void installProviderBundles() {
+ installSharedBundles(serverCtx);
+ auto bndId = serverCtx->installBundle(RS_PROVIDER_BUNDLE_LOC);
+ EXPECT_GE(bndId, 0);
+ }
+
+ void installConsumerBundles() {
+ installSharedBundles(clientCtx);
+ auto bndId = clientCtx->installBundle(RS_CONSUMER_BUNDLE_LOC);
+ EXPECT_GE(bndId, 0);
+ }
+
+ std::shared_ptr<celix::Framework> clientFw{};
+ std::shared_ptr<celix::BundleContext> clientCtx{};
+ std::shared_ptr<celix::Framework> serverFw{};
+ std::shared_ptr<celix::BundleContext> serverCtx{};
+};
+
+TEST_F(RemoteServicesIntegrationTestSuite, StartStopFrameworks) {
+ installConsumerBundles();
+ installProviderBundles();
+}
\ No newline at end of file
diff --git a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc
b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc
index de4caae..7ef3330 100644
--- a/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc
+++ b/bundles/cxx_remote_services/integration/src/CalculatorConsumer.cc
@@ -19,45 +19,36 @@
#include <memory>
+#include "celix/IShellCommand.h"
#include "celix/BundleActivator.h"
#include "celix/PromiseFactory.h"
+#include "celix/rsa/IConfiguredDiscoveryManager.h"
#include "ICalculator.h"
-class CalculatorConsumer final {
+class CalculatorConsumer final : public celix::IShellCommand {
public:
- void start() {
- std::cout << "starting calc thread" << std::endl;
- active = true;
- calcThread = std::thread{[this]() {
- double secondArg = 1;
- while(active) {
- std::cout << "Calling calc" << std::endl;
- calculator->add(42, secondArg++)
- .onSuccess([](double val) {
- std::cout << "calc result is " << val << std::endl;
- })
- .onFailure([](const auto& exp) {
- std::cerr << "error calling calc: " << exp.what() <<
std::endl;
- });
- std::this_thread::sleep_for(std::chrono::seconds{5});
- }
- }};
- }
-
- void stop() {
- active = false;
- if (calcThread.joinable()) {
- calcThread.join();
- }
- }
+ ~CalculatorConsumer() override = default;
void setCalculator(const std::shared_ptr<ICalculator>& cal) {
calculator = cal;
}
+
+ void executeCommand(const std::string &/*commandLine*/, const
std::vector<std::string> &/*commandArgs*/, FILE *outStream,
+ FILE *errorStream) override {
+ thread_local double secondArg = 1;
+ fprintf(outStream, "Calling calc\n");
+ calculator->add(42, secondArg++)
+ .onSuccess([outStream](double val) {
+ fprintf(outStream, "calc result is %f\n", val);
+ })
+ .onFailure([errorStream](const auto& exp) {
+ fprintf(errorStream, "error calling calc: %s", exp.what());
+ })
+ .wait(); //note waiting on promise to ensure outStream and
errorStream are still valid.
+ }
+
private:
- std::atomic<bool> active{false};
std::shared_ptr<ICalculator> calculator{};
- std::thread calcThread{};
};
class CalculatorProviderActivator {
@@ -67,8 +58,17 @@ public:
cmp.createServiceDependency<ICalculator>()
.setRequired(true)
.setCallbacks(&CalculatorConsumer::setCalculator);
- cmp.setCallbacks(nullptr, &CalculatorConsumer::start,
&CalculatorConsumer::stop, nullptr);
+ cmp.createProvidedService<celix::IShellCommand>()
+ .addProperty(celix::IShellCommand::COMMAND_NAME, "calc");
cmp.build();
+
+ //bootstrap own configured import discovery to the configured
discovery manager
+ auto path =
ctx->getBundle().getEntry("META-INF/discovery/endpoint_discovery.json");
+ ctx->useService<celix::rsa::IConfiguredDiscoveryManager>()
+ .addUseCallback([&path](auto& disc) {
+ disc.addConfiguredDiscoveryFile(path);
+ })
+ .build();
}
};
diff --git a/bundles/logging/log_helper/include/celix/LogHelper.h
b/bundles/logging/log_helper/include/celix/LogHelper.h
index f4fd4b3..3f447f2 100644
--- a/bundles/logging/log_helper/include/celix/LogHelper.h
+++ b/bundles/logging/log_helper/include/celix/LogHelper.h
@@ -19,7 +19,9 @@
#pragma once
+#include <memory>
#include "celix_log_helper.h"
+#include "celix/BundleContext.h"
namespace celix {
diff --git a/cmake/cmake_celix/Generic.cmake b/cmake/cmake_celix/Generic.cmake
index a0e00be..ae82881 100644
--- a/cmake/cmake_celix/Generic.cmake
+++ b/cmake/cmake_celix/Generic.cmake
@@ -18,3 +18,28 @@
function(install_celix_targets)
install_celix_bundle_targets(${ARGN})
endfunction ()
+
+#[[
+Add bundles as dependencies to a cmake target, so that the bundle zip files
are created before the cmake target is
+ created.
+
+add_celix_bundle_dependencies(<cmake_target>
+ bundles...
+)
+]]
+function(add_celix_bundle_dependencies)
+ list(GET ARGN 0 TARGET)
+ list(REMOVE_AT ARGN 0)
+ message("TEST")
+ foreach(BUNDLE_TARGET IN LISTS ARGN)
+ if (TARGET ${BUNDLE_TARGET})
+ get_target_property(IMPORT ${BUNDLE_TARGET} BUNDLE_IMPORTED)
+ get_target_property(CREATE_BUNDLE_TARGET ${BUNDLE_TARGET}
BUNDLE_CREATE_BUNDLE_TARGET)
+ if (IMPORT)
+ #NOP, an imported bundle target -> handle target without
DEPENDS
+ else ()
+ add_dependencies(${TARGET} ${CREATE_BUNDLE_TARGET})
+ endif ()
+ endif()
+ endforeach()
+endfunction()
\ No newline at end of file
diff --git a/libs/framework/include/celix/Bundle.h
b/libs/framework/include/celix/Bundle.h
index a1e97b8..a098b3c 100644
--- a/libs/framework/include/celix/Bundle.h
+++ b/libs/framework/include/celix/Bundle.h
@@ -50,9 +50,10 @@ namespace celix {
*/
std::string getEntry(const std::string& path) const {
std::string result{};
- const char* entry = celix_bundle_getEntry(cBnd.get(),
path.c_str());
+ char* entry = celix_bundle_getEntry(cBnd.get(), path.c_str());
if (entry != nullptr) {
result = std::string{entry};
+ free(entry);
}
return result;
}
diff --git a/libs/framework/include/celix/Constants.h
b/libs/framework/include/celix/Constants.h
index 7c44233..084602d 100644
--- a/libs/framework/include/celix/Constants.h
+++ b/libs/framework/include/celix/Constants.h
@@ -174,4 +174,12 @@ namespace celix {
*
*/
constexpr const char * const LOAD_BUNDLES_WITH_NODELETE =
CELIX_LOAD_BUNDLES_WITH_NODELETE;
+
+ /**
+ * @brief Celix framework environment property (named
"org.osgi.framework.storage") specifying the cache
+ * directory used for the bundle caches.
+ *
+ * If not specified ".cache" is used.
+ */
+ constexpr const char * const FRAMEWORK_CACHE_DIR =
OSGI_FRAMEWORK_FRAMEWORK_STORAGE;
}
\ No newline at end of file