You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2020/02/11 21:47:07 UTC
[celix] branch develop updated: Feature/gh 142 rsa issues (#153)
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/celix.git
The following commit(s) were added to refs/heads/develop by this push:
new 16235c3 Feature/gh 142 rsa issues (#153)
16235c3 is described below
commit 16235c321f081ffc67bf86ceb8667891d6d36f69
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Tue Feb 11 22:46:58 2020 +0100
Feature/gh 142 rsa issues (#153)
Fixes several issues for remote services
* gh-142: Refactors RSA tests and adds an additional remote service example for testing
* gh-142: Adds test for ffi and string as input argument handling.
* gh-142: Fixes some issue with remote calls and string input/output.
* gh-142: Extends remote services test for string, const string, enums and complex types and fixes several issues in remote services
* gh-142: Replace mutex with rw lock in rsa to support handling multiple calls and adds missing test for libdfi
* #142: Fixes a memory leak in handling pre allocated output arguments for remote services
* #142: Fixes an issue in remote service etcd for configuring the ttl.
* #142: Refactors remote calculator client to use celix_ api.
---
.travis.yml | 2 +-
CMakeLists.txt | 8 +-
.../pubsub_discovery/src/pubsub_discovery_impl.c | 2 +-
.../src/endpoint_discovery_server.c | 2 +-
.../discovery_etcd/src/discovery_impl.c | 12 +-
.../discovery_etcd/src/discovery_impl.h | 7 -
.../discovery_etcd/src/etcd_watcher.c | 74 ++------
.../discovery_etcd/src/etcd_watcher.h | 7 -
bundles/remote_services/examples/CMakeLists.txt | 8 +-
.../examples/calculator_api/CMakeLists.txt | 4 +-
.../calculator_api/include/calculator_service.h | 17 +-
.../org.apache.celix.calc.api.Calculator.avpr | 0
...org.apache.celix.calc.api.Calculator.descriptor | 0
.../examples/calculator_service/CMakeLists.txt | 2 +-
.../calculator_service/src/calculator_activator.c | 88 +++------
.../calculator_service/src/calculator_impl.c | 37 ++--
.../calculator_service/src/calculator_impl.h | 14 +-
.../examples/calculator_shell/CMakeLists.txt | 2 +-
.../examples/calculator_shell/src/add_command.c | 92 ++++-----
.../examples/calculator_shell/src/add_command.h | 10 +-
.../src/calculator_shell_activator.c | 110 +++--------
...org.apache.celix.calc.api.Calculator.descriptor | 11 --
.../examples/calculator_shell/src/sqrt_command.c | 87 +++++----
.../examples/calculator_shell/src/sqrt_command.h | 10 +-
.../examples/calculator_shell/src/sub_command.c | 94 ++++-----
.../examples/calculator_shell/src/sub_command.h | 10 +-
.../CMakeLists.txt | 16 +-
.../remote_example_api/include/remote_example.h | 66 +++++++
.../org.apache.celix.RemoteExample.descriptor | 18 ++
.../CMakeLists.txt | 16 +-
.../src/remote_example_activator.c | 62 ++++++
.../src/remote_example_impl.c | 129 +++++++++++++
.../src/remote_example_impl.h | 40 ++++
.../src/import_registration_dfi.c | 2 +-
.../src/remote_service_admin_dfi.c | 24 +--
.../remote_service_admin_dfi/test/CMakeLists.txt | 16 +-
.../test/server.properties.in | 2 +-
.../test/src/rsa_client_server_tests.cpp | 127 ++++++-------
.../test/src/rsa_tests.cpp | 153 +++++++--------
.../test/src/run_tests.cpp | 1 +
.../test/src/tst_activator.c | 211 +++++++++++++++++++--
.../test/src/tst_service.h | 10 +-
bundles/shell/shell/CMakeLists.txt | 6 +-
bundles/shell/shell/deprecated_api/command.h | 9 +-
bundles/shell/shell/src/activator.c | 2 +-
bundles/shell/shell/src/help_command.c | 5 +
bundles/shell/shell/src/shell.c | 4 +-
bundles/shell/shell/src/shell_private.h | 6 +-
bundles/shell/shell/test/CMakeLists.txt | 4 +-
bundles/shell/shell/test/src/shell_tests.cpp | 2 +-
libs/dfi/include/dyn_function.h | 13 ++
libs/dfi/include/dyn_type.h | 2 +-
libs/dfi/src/avrobin_serializer.c | 6 +
libs/dfi/src/dyn_function.c | 5 +
libs/dfi/src/dyn_type.c | 39 ++--
libs/dfi/src/json_rpc.c | 93 +++++++--
libs/dfi/src/json_serializer.c | 16 +-
libs/dfi/test/dyn_avpr_function_tests.cpp | 44 ++++-
libs/dfi/test/dyn_function_tests.cpp | 32 ++++
libs/etcdlib/api/etcd.h | 30 ++-
libs/framework/src/celix_framework_factory.c | 2 +-
61 files changed, 1201 insertions(+), 722 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 2980ab1..33994bd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -88,7 +88,7 @@ before_script:
script:
- if [ "$SANITIZE" == 1 ]; then export BUILD_OPTIONS="${BUILD_OPTIONS} DENABLE_ADDRESS_SANITIZER=ON"; fi
- if [ "$USE_ZIP_INSTEAD_OF_JAR" == 1 ]; then export BUILD_OPTIONS="${BUILD_OPTIONS} -DDCELIX_USE_ZIP_INSTEAD_OF_JAR=ON"; fi
- - if [ "$ONLY_V3_API" == 1 ]; then export BUILD_OPTIONS="${BUILD_OPTIONS} -DCELIX_ADD_DEPRECATED_API=OFF"; fi
+ - if [ "$ONLY_V3_API" == 1 ]; then export BUILD_OPTIONS="${BUILD_OPTIONS} -DCELIX_INSTALL_DEPRECATED_API=OFF"; fi
- cd build
- if [ "$CC" = "gcc" ] && [ "$TRAVIS_OS_NAME" = "linux" ]; then export BUILD_OPTS="${BUILD_OPTS} -DENABLE_CODE_COVERAGE=ON"; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ] && [ -z "$ANDROID" ]; then cmake -DCMAKE_BUILD_TYPE=Debug ${BUILD_OPTIONS} ${BUILD_OPTIONS_LINUX} -DBUILD_FRAMEWORK_TESTS=ON -DBUILD_UTILS-TESTS=ON -DENABLE_TESTING=ON ${BUILD_OPTS} -DCMAKE_INSTALL_PREFIX=../install ..; fi
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ac6681b..a887f39 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,7 +99,13 @@ if (ENABLE_TESTING)
enable_testing()
endif()
-option(CELIX_ADD_DEPRECATED_API "whether to use and install deprecated apis (i.e. header without a celix_ prefix." ON)
+option(CELIX_INSTALL_DEPRECATED_API "whether to install (and use) deprecated apis (i.e. header without a celix_ prefix." ON)
+
+option(CELIX_ADD_DEPRECATED_ATTRIBUTES "If enabled add deprecated attributes to deprecated services/functions." ON)
+if (CELIX_ADD_DEPRECATED_ATTRIBUTES)
+ set(CMAKE_C_FLAGS "-DCELIX_ADD_DEPRECATED_ATTRIBUTES ${CMAKE_C_FLAGS}")
+ set(CMAKE_CXX_FLAGS "-DCELIX_ADD_DEPRECATED_ATTRIBUTES ${CMAKE_CXX_FLAGS}")
+endif ()
option(CELIX_ADD_OPENSSL_DEP "Enabled building Celix framework & etcdlib with OpenSSL library dependency. This can help in some libcurl resolving issues" OFF)
set(CELIX_OPTIONAL_EXTRA_LIBS "")
diff --git a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
index 3e9eab6..964afd9 100644
--- a/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
+++ b/bundles/pubsub/pubsub_discovery/src/pubsub_discovery_impl.c
@@ -164,7 +164,7 @@ static void psd_watchForChange(pubsub_discovery_t *disc, bool *connectedPtr, lon
char *action = NULL;
char *value = NULL;
char *readKey = NULL;
- //TODO add interruptable etcdlib_wait -> which returns a handle to interrupt and a can be used for a wait call
+ //TODO add interruptable etcdlib_watch -> which returns a handle to interrupt and a can be used for a wait call
int rc = etcdlib_watch(disc->etcdlib, disc->pubsubPath, watchIndex, &action, NULL, &value, &readKey, mIndex);
if (rc == ETCDLIB_RC_ERROR) {
L_ERROR("[PSD] Communicating with etcd. rc is %i, action value is %s\n", rc, action);
diff --git a/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c b/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c
index 5ad8e87..ba31c9d 100644
--- a/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c
+++ b/bundles/remote_services/discovery_common/src/endpoint_discovery_server.c
@@ -40,7 +40,7 @@
// defines how often the webserver is restarted (with an increased port number)
#define MAX_NUMBER_OF_RESTARTS 15
-#define DEFAULT_SERVER_THREADS "1"
+#define DEFAULT_SERVER_THREADS "5"
#define CIVETWEB_REQUEST_NOT_HANDLED 0
#define CIVETWEB_REQUEST_HANDLED 1
diff --git a/bundles/remote_services/discovery_etcd/src/discovery_impl.c b/bundles/remote_services/discovery_etcd/src/discovery_impl.c
index f4cd825..ecde542 100644
--- a/bundles/remote_services/discovery_etcd/src/discovery_impl.c
+++ b/bundles/remote_services/discovery_etcd/src/discovery_impl.c
@@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * discovery_impl.c
- *
- * \date Aug 8, 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <stdio.h>
#include <stdlib.h>
@@ -31,16 +24,13 @@
#include <netdb.h>
#include <netinet/in.h>
-#include "celix_constants.h"
+
#include "celix_threads.h"
#include "bundle_context.h"
-#include "array_list.h"
#include "utils.h"
#include "celix_errno.h"
#include "filter.h"
#include "service_reference.h"
-#include "service_registration.h"
-#include "remote_constants.h"
#include "discovery.h"
diff --git a/bundles/remote_services/discovery_etcd/src/discovery_impl.h b/bundles/remote_services/discovery_etcd/src/discovery_impl.h
index adf8e4b..096ef4c 100644
--- a/bundles/remote_services/discovery_etcd/src/discovery_impl.h
+++ b/bundles/remote_services/discovery_etcd/src/discovery_impl.h
@@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * discovery_impl.h
- *
- * \date Sep 29, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#ifndef DISCOVERY_IMPL_H_
#define DISCOVERY_IMPL_H_
diff --git a/bundles/remote_services/discovery_etcd/src/etcd_watcher.c b/bundles/remote_services/discovery_etcd/src/etcd_watcher.c
index d464cf1..1c22422 100644
--- a/bundles/remote_services/discovery_etcd/src/etcd_watcher.c
+++ b/bundles/remote_services/discovery_etcd/src/etcd_watcher.c
@@ -16,22 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * etcd_watcher.c
- *
- * \date 16 Sep 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include "celix_api.h"
#include "log_helper.h"
#include "log_service.h"
-#include "celix_constants.h"
#include "utils.h"
#include "discovery.h"
#include "discovery_impl.h"
@@ -44,6 +37,7 @@
struct etcd_watcher {
etcdlib_t *etcdlib;
+ int ttl;
discovery_t *discovery;
log_helper_t **loghelper;
@@ -140,19 +134,17 @@ static celix_status_t etcdWatcher_addAlreadyExistingWatchpoints(etcd_watcher_t *
static celix_status_t etcdWatcher_addOwnFramework(etcd_watcher_t *watcher)
{
- celix_status_t status = CELIX_BUNDLE_EXCEPTION;
char localNodePath[MAX_LOCALNODE_LENGTH];
char *value;
char url[MAX_VALUE_LENGTH];
int modIndex;
char* endpoints = NULL;
- const char* ttlStr = NULL;
- int ttl;
celix_bundle_context_t *context = watcher->discovery->context;
endpoint_discovery_server_t *server = watcher->discovery->server;
// register own framework
+ celix_status_t status;
if ((status = etcdWatcher_getLocalNodePath(context, localNodePath)) != CELIX_SUCCESS) {
return status;
}
@@ -163,32 +155,17 @@ static celix_status_t etcdWatcher_addOwnFramework(etcd_watcher_t *watcher)
endpoints = url;
- if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) {
- ttl = DEFAULT_ETCD_TTL;
- }
- else
- {
- char* endptr = (char *) ttlStr;
- errno = 0;
- ttl = strtol(ttlStr, &endptr, 10);
- if (*endptr || errno != 0) {
- ttl = DEFAULT_ETCD_TTL;
- }
- }
+ watcher->ttl = celix_bundleContext_getPropertyAsLong(context, CFG_ETCD_TTL, DEFAULT_ETCD_TTL);
if (etcdlib_get(watcher->etcdlib, localNodePath, &value, &modIndex) != ETCDLIB_RC_OK) {
- etcdlib_set(watcher->etcdlib, localNodePath, endpoints, ttl, false);
- }
- else if (etcdlib_set(watcher->etcdlib, localNodePath, endpoints, ttl, true) != ETCDLIB_RC_OK) {
+ etcdlib_set(watcher->etcdlib, localNodePath, endpoints, watcher->ttl, false);
+ } else if (etcdlib_set(watcher->etcdlib, localNodePath, endpoints, watcher->ttl , true) != ETCDLIB_RC_OK) {
logHelper_log(*watcher->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot register local discovery");
}
- else {
- status = CELIX_SUCCESS;
- }
FREE_MEM(value);
- return status;
+ return CELIX_SUCCESS;
}
@@ -281,8 +258,8 @@ static void* etcdWatcher_run(void* data) {
}
highestModified = modIndex;
- } else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
- sleep(DEFAULT_ETCD_TTL / 4);
+ } else if (time(NULL) - timeBeforeWatch <= (watcher->ttl / 4)) {
+ sleep(watcher->ttl / 4);
}
FREE_MEM(action);
@@ -291,7 +268,7 @@ static void* etcdWatcher_run(void* data) {
FREE_MEM(rkey);
// update own framework uuid
- if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
+ if (time(NULL) - timeBeforeWatch > (watcher->ttl / 4)) {
etcdWatcher_addOwnFramework(watcher);
timeBeforeWatch = time(NULL);
}
@@ -306,12 +283,6 @@ static void* etcdWatcher_run(void* data) {
*/
celix_status_t etcdWatcher_create(discovery_t *discovery, celix_bundle_context_t *context, etcd_watcher_t **watcher)
{
- celix_status_t status = CELIX_SUCCESS;
-
- const char* etcd_server = NULL;
- const char* etcd_port_string = NULL;
- int etcd_port = 0;
-
if (discovery == NULL) {
return CELIX_BUNDLE_EXCEPTION;
}
@@ -325,32 +296,17 @@ celix_status_t etcdWatcher_create(discovery_t *discovery, celix_bundle_context_t
(*watcher)->discovery = discovery;
(*watcher)->loghelper = &discovery->loghelper;
(*watcher)->entries = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
+ (*watcher)->ttl = DEFAULT_ETCD_TTL;
}
- if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, &etcd_server) != CELIX_SUCCESS) || !etcd_server) {
- etcd_server = DEFAULT_ETCD_SERVER_IP;
- }
+ const char* etcd_server = celix_bundleContext_getProperty(context, CFG_ETCD_SERVER_IP, DEFAULT_ETCD_SERVER_IP);
+ long etcd_port = celix_bundleContext_getPropertyAsLong(context, CFG_ETCD_SERVER_PORT, DEFAULT_ETCD_SERVER_PORT);
- if ((bundleContext_getProperty(context, CFG_ETCD_SERVER_PORT, &etcd_port_string) != CELIX_SUCCESS) || !etcd_port_string) {
- etcd_port = DEFAULT_ETCD_SERVER_PORT;
- }
- else
- {
- char* endptr = (char*)etcd_port_string;
- errno = 0;
- etcd_port = strtol(etcd_port_string, &endptr, 10);
- if (*endptr || errno != 0) {
- etcd_port = DEFAULT_ETCD_SERVER_PORT;
- }
- }
-
- (*watcher)->etcdlib = etcdlib_create(etcd_server, etcd_port, CURL_GLOBAL_DEFAULT);
+ (*watcher)->etcdlib = etcdlib_create(etcd_server, (int)etcd_port, CURL_GLOBAL_DEFAULT);
+ celix_status_t status = CELIX_SUCCESS;
if ((*watcher)->etcdlib == NULL) {
status = CELIX_BUNDLE_EXCEPTION;
- } else {
- status = CELIX_SUCCESS;
}
-
if (status == CELIX_SUCCESS) {
etcdWatcher_addOwnFramework(*watcher);
status = celixThreadMutex_create(&(*watcher)->watcherLock, NULL);
diff --git a/bundles/remote_services/discovery_etcd/src/etcd_watcher.h b/bundles/remote_services/discovery_etcd/src/etcd_watcher.h
index 67428ae..454a67e 100644
--- a/bundles/remote_services/discovery_etcd/src/etcd_watcher.h
+++ b/bundles/remote_services/discovery_etcd/src/etcd_watcher.h
@@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * etcd_watcher.h
- *
- * \date 17 Sep 2014
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#ifndef ETCD_WATCHER_H_
#define ETCD_WATCHER_H_
diff --git a/bundles/remote_services/examples/CMakeLists.txt b/bundles/remote_services/examples/CMakeLists.txt
index b0c9a5c..17dcabf 100644
--- a/bundles/remote_services/examples/CMakeLists.txt
+++ b/bundles/remote_services/examples/CMakeLists.txt
@@ -21,6 +21,9 @@ if (RSA_EXAMPLES)
add_subdirectory(calculator_service)
add_subdirectory(calculator_shell)
+ add_subdirectory(remote_example_api)
+ add_subdirectory(remote_example_service)
+
# TODO refactor shm remote service admin to use dfi
# if (BUILD_RSA_REMOTE_SERVICE_ADMIN_SHM AND BUILD_RSA_DISCOVERY_SHM)
@@ -51,11 +54,12 @@ if (RSA_EXAMPLES)
BUNDLES
Celix::rsa_discovery_etcd
Celix::rsa_topology_manager
- Celix::rsa_dfi calculator
+ Celix::rsa_dfi
Celix::shell
Celix::shell_tui
Celix::log_service
Celix::log_writer_stdout
+ calculator
PROPERTIES
RSA_PORT=18888
)
@@ -69,8 +73,8 @@ if (RSA_EXAMPLES)
Celix::shell_tui
Celix::log_service
Celix::log_writer_stdout
- calculator_shell
Celix::rsa_discovery_etcd
+ calculator_shell
PROPERTIES
RSA_PORT=28888
)
diff --git a/bundles/remote_services/examples/calculator_api/CMakeLists.txt b/bundles/remote_services/examples/calculator_api/CMakeLists.txt
index a87945f..3b0e334 100644
--- a/bundles/remote_services/examples/calculator_api/CMakeLists.txt
+++ b/bundles/remote_services/examples/calculator_api/CMakeLists.txt
@@ -18,5 +18,5 @@
add_library(calculator_api INTERFACE)
target_include_directories(calculator_api INTERFACE include)
set_target_properties(calculator_api PROPERTIES
- "INTERFACE_CALCULATOR_DESCRIPTOR"
- "${CMAKE_CURRENT_LIST_DIR}/include/org.apache.celix.calc.api.Calculator.avpr")
+ "INTERFACE_DESCRIPTOR"
+ "${CMAKE_CURRENT_LIST_DIR}/org.apache.celix.calc.api.Calculator.avpr")
diff --git a/bundles/remote_services/examples/calculator_api/include/calculator_service.h b/bundles/remote_services/examples/calculator_api/include/calculator_service.h
index 19e9741..6458554 100644
--- a/bundles/remote_services/examples/calculator_api/include/calculator_service.h
+++ b/bundles/remote_services/examples/calculator_api/include/calculator_service.h
@@ -16,13 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * calculator_service.h
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#ifndef CALCULATOR_SERVICE_H_
#define CALCULATOR_SERVICE_H_
@@ -30,8 +23,6 @@
#define CALCULATOR_SERVICE "org.apache.celix.calc.api.Calculator"
#define CALCULATOR_CONFIGURATION_TYPE "org.amdatu.remote.admin.http"
-typedef struct calculator calculator_t;
-
typedef struct calculator_service calculator_service_t;
/*
@@ -44,10 +35,10 @@ typedef struct calculator_service calculator_service_t;
* }
*/
struct calculator_service {
- calculator_t *calculator;
- int (*add)(calculator_t *calculator, double a, double b, double *result);
- int (*sub)(calculator_t *calculator, double a, double b, double *result);
- int (*sqrt)(calculator_t *calculator, double a, double *result);
+ void *handle;
+ int (*add)(void *handle, double a, double b, double *result);
+ int (*sub)(void *handle, double a, double b, double *result);
+ int (*sqrt)(void *handle, double a, double *result);
};
diff --git a/bundles/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator.avpr b/bundles/remote_services/examples/calculator_api/org.apache.celix.calc.api.Calculator.avpr
similarity index 100%
rename from bundles/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator.avpr
rename to bundles/remote_services/examples/calculator_api/org.apache.celix.calc.api.Calculator.avpr
diff --git a/bundles/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator.descriptor b/bundles/remote_services/examples/calculator_api/org.apache.celix.calc.api.Calculator.descriptor
similarity index 100%
rename from bundles/remote_services/examples/calculator_api/include/org.apache.celix.calc.api.Calculator.descriptor
rename to bundles/remote_services/examples/calculator_api/org.apache.celix.calc.api.Calculator.descriptor
diff --git a/bundles/remote_services/examples/calculator_service/CMakeLists.txt b/bundles/remote_services/examples/calculator_service/CMakeLists.txt
index b47a3ae..2d55e0b 100644
--- a/bundles/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/bundles/remote_services/examples/calculator_service/CMakeLists.txt
@@ -25,5 +25,5 @@ add_celix_bundle(calculator
target_include_directories(calculator PRIVATE src)
target_link_libraries(calculator PRIVATE Celix::rsa_spi calculator_api)
-get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+get_target_property(DESCR calculator_api INTERFACE_DESCRIPTOR)
celix_bundle_files(calculator ${DESCR} DESTINATION .)
diff --git a/bundles/remote_services/examples/calculator_service/src/calculator_activator.c b/bundles/remote_services/examples/calculator_service/src/calculator_activator.c
index 41737f1..e616fb4 100644
--- a/bundles/remote_services/examples/calculator_service/src/calculator_activator.c
+++ b/bundles/remote_services/examples/calculator_service/src/calculator_activator.c
@@ -16,88 +16,44 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * calculator_activator.c
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <stdlib.h>
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
+#include <celix_api.h>
#include "calculator_impl.h"
#include "remote_constants.h"
struct activator {
calculator_t *calculator;
- calculator_service_t *service;
-
- service_registration_t *calculatorReg;
+ calculator_service_t service;
+ long svcId;
};
-celix_status_t bundleActivator_create(celix_bundle_context_t *context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
+celix_status_t calculatorBndStart(struct activator *act, celix_bundle_context_t *ctx) {
+ act->svcId = -1L;
+ act->calculator = calculator_create();
+ if (act->calculator != NULL) {
+ act->service.handle = act->calculator;
+ act->service.add = (void*)calculator_add;
+ act->service.sub = (void*)calculator_sub;
+ act->service.sqrt = (void*)calculator_sqrt;
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->calculatorReg = NULL;
+ celix_properties_t *properties = celix_properties_create();
+ celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, CALCULATOR_SERVICE);
+ celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, CALCULATOR_CONFIGURATION_TYPE);
- *userData = activator;
+ act->svcId = celix_bundleContext_registerService(ctx, &act->service, CALCULATOR_SERVICE, properties);
}
-
- return status;
+ return CELIX_SUCCESS;
}
-celix_status_t bundleActivator_start(void * userData, celix_bundle_context_t *context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- status = calculator_create(&activator->calculator);
- if (status == CELIX_SUCCESS) {
- activator->service = calloc(1, sizeof(*activator->service));
- if (!activator->service) {
- status = CELIX_ENOMEM;
- } else {
- activator->service->calculator = activator->calculator;
- activator->service->add = calculator_add;
- activator->service->sub = calculator_sub;
- activator->service->sqrt = calculator_sqrt;
-
- celix_properties_t *properties = celix_properties_create();
- celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, CALCULATOR_SERVICE);
- celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, CALCULATOR_CONFIGURATION_TYPE);
- bundleContext_registerService(context, CALCULATOR_SERVICE, activator->service, properties, &activator->calculatorReg);
- }
+celix_status_t calculatorBndStop(struct activator *act, celix_bundle_context_t *ctx) {
+ celix_bundleContext_unregisterService(ctx, act->svcId);
+ if (act->calculator != NULL) {
+ calculator_destroy(act->calculator);
}
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, celix_bundle_context_t *context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- serviceRegistration_unregister(activator->calculatorReg);
-
- free(activator->service);
-
- calculator_destroy(&activator->calculator);
-
- return status;
+ return CELIX_SUCCESS;
}
-celix_status_t bundleActivator_destroy(void * userData, celix_bundle_context_t *context) {
- celix_status_t status = CELIX_SUCCESS;
-
- free(userData);
-
- return status;
-}
+CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, calculatorBndStart, calculatorBndStop);
diff --git a/bundles/remote_services/examples/calculator_service/src/calculator_impl.c b/bundles/remote_services/examples/calculator_service/src/calculator_impl.c
index ad59820..db6b7b8 100644
--- a/bundles/remote_services/examples/calculator_service/src/calculator_impl.c
+++ b/bundles/remote_services/examples/calculator_service/src/calculator_impl.c
@@ -16,13 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * calculator_impl.c
- *
- * \date Oct 5, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
+
#include <math.h>
@@ -31,24 +25,17 @@
#include "calculator_impl.h"
-celix_status_t calculator_create(calculator_t **calculator) {
- celix_status_t status = CELIX_SUCCESS;
-
- *calculator = calloc(1, sizeof(**calculator));
- if (!*calculator) {
- status = CELIX_ENOMEM;
- }
-
- return status;
+calculator_t* calculator_create(void) {
+ struct calculator *calc = calloc(1, sizeof(*calc));
+ return calc;
}
-celix_status_t calculator_destroy(calculator_t **calculator) {
- free(*calculator);
- return CELIX_SUCCESS;
+void calculator_destroy(calculator_t *calculator) {
+ free(calculator);
}
-celix_status_t calculator_add(calculator_t *calculator, double a, double b, double *result) {
- celix_status_t status = CELIX_SUCCESS;
+int calculator_add(calculator_t *calculator __attribute__((unused)), double a, double b, double *result) {
+ int status = CELIX_SUCCESS;
*result = a + b;
printf("CALCULATOR: Add: %f + %f = %f\n", a, b, *result);
@@ -56,8 +43,8 @@ celix_status_t calculator_add(calculator_t *calculator, double a, double b, doub
return status;
}
-celix_status_t calculator_sub(calculator_t *calculator, double a, double b, double *result) {
- celix_status_t status = CELIX_SUCCESS;
+int calculator_sub(calculator_t *calculator __attribute__((unused)), double a, double b, double *result) {
+ int status = CELIX_SUCCESS;
*result = a - b;
printf("CALCULATOR: Sub: %f + %f = %f\n", a, b, *result);
@@ -65,8 +52,8 @@ celix_status_t calculator_sub(calculator_t *calculator, double a, double b, doub
return status;
}
-celix_status_t calculator_sqrt(calculator_t *calculator, double a, double *result) {
- celix_status_t status = CELIX_SUCCESS;
+int calculator_sqrt(calculator_t *calculator __attribute__((unused)), double a, double *result) {
+ int status = CELIX_SUCCESS;
if (a > 0) {
*result = sqrt(a);
diff --git a/bundles/remote_services/examples/calculator_service/src/calculator_impl.h b/bundles/remote_services/examples/calculator_service/src/calculator_impl.h
index 94023f8..c70b2f9 100644
--- a/bundles/remote_services/examples/calculator_service/src/calculator_impl.h
+++ b/bundles/remote_services/examples/calculator_service/src/calculator_impl.h
@@ -31,13 +31,13 @@
#include "calculator_service.h"
-struct calculator {
-};
+typedef struct calculator {
+} calculator_t;
-celix_status_t calculator_create(calculator_t **calculator);
-celix_status_t calculator_destroy(calculator_t **calculator);
-celix_status_t calculator_add(calculator_t *calculator, double a, double b, double *result);
-celix_status_t calculator_sub(calculator_t *calculator, double a, double b, double *result);
-celix_status_t calculator_sqrt(calculator_t *calculator, double a, double *result);
+calculator_t* calculator_create(void);
+void calculator_destroy(calculator_t *calculator);
+int calculator_add(calculator_t *calculator, double a, double b, double *result);
+int calculator_sub(calculator_t *calculator, double a, double b, double *result);
+int calculator_sqrt(calculator_t *calculator, double a, double *result);
#endif /* CALCULATOR_IMPL_H_ */
diff --git a/bundles/remote_services/examples/calculator_shell/CMakeLists.txt b/bundles/remote_services/examples/calculator_shell/CMakeLists.txt
index 14087e3..2c0158a 100644
--- a/bundles/remote_services/examples/calculator_shell/CMakeLists.txt
+++ b/bundles/remote_services/examples/calculator_shell/CMakeLists.txt
@@ -28,7 +28,7 @@ target_include_directories(calculator_shell PRIVATE src)
target_link_libraries(calculator_shell PRIVATE Celix::shell_api calculator_api)
celix_bundle_files(calculator_shell
- ../calculator_api/include/org.apache.celix.calc.api.Calculator.avpr
+ ../calculator_api/org.apache.celix.calc.api.Calculator.avpr
#src/org.apache.celix.calc.api.Calculator2.descriptor ##Use this descriptor in case you want to try out versioning!
DESTINATION .
)
diff --git a/bundles/remote_services/examples/calculator_shell/src/add_command.c b/bundles/remote_services/examples/calculator_shell/src/add_command.c
index 7084f81..094a0e3 100644
--- a/bundles/remote_services/examples/calculator_shell/src/add_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/add_command.c
@@ -16,70 +16,74 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * add_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_api.h"
#include "add_command.h"
#include "calculator_service.h"
+#include "celix_utils.h"
static celix_status_t addCommand_isNumeric(char *number, bool *ret);
-void addCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+ double a;
+ double b;
+ double result;
+ int rc;
+};
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "ADD: Cannot get reference for %s.\n", CALCULATOR_SERVICE);
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- char *bStr = strtok_r(NULL, " ", &token);
- bool aNumeric, bNumeric;
- if (aStr != NULL && bStr != NULL) {
- addCommand_isNumeric(aStr, &aNumeric);
- addCommand_isNumeric(bStr, &bNumeric);
- if (aNumeric && bNumeric) {
- calculator_service_t *calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double b = atof(bStr);
- double result = 0;
- status = calculator->add(calculator->calculator, a, b, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", a, b, result);
- } else {
- fprintf(err, "ADD: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
+static void calcCallback(void *handle, void *svc) {
+ struct calc_callback_data *data = handle;
+ calculator_service_t *calc = svc;
+ data->rc = calc->add(calc->handle, data->a, data->b, &data->result);
+}
+
+bool addCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+ bool ok = true;
+ celix_bundle_context_t *context = handle;
+
+ char *line = celix_utils_strdup(const_line);
+
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ char *bStr = strtok_r(NULL, " ", &token);
+ bool aNumeric, bNumeric;
+ if (aStr != NULL && bStr != NULL) {
+ addCommand_isNumeric(aStr, &aNumeric);
+ addCommand_isNumeric(bStr, &bNumeric);
+ if (aNumeric && bNumeric) {
+ struct calc_callback_data data;
+
+ data.a = atof(aStr);
+ data.b = atof(bStr);
+ data.result = 0;
+ data.rc = 0;
+ bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+ if (called && data.rc == 0) {
+ fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", data.a, data.b, data.result);
+ } else if (!called) {
+ fprintf(err, "ADD: calculator service not available\n");
+ ok = false;
} else {
- fprintf(err, "ADD: Requires 2 numerical parameter\n");
+ fprintf(err, "ADD: Unexpected exception in Calc service\n");
+ ok = false;
}
} else {
fprintf(err, "ADD: Requires 2 numerical parameter\n");
+ ok = false;
}
} else {
- fprintf(err, "No calc service available\n");
+ fprintf(err, "ADD: Requires 2 numerical parameter\n");
+ ok = false;
}
- //return status;
+ free(line);
+ return ok;
}
static celix_status_t addCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/add_command.h b/bundles/remote_services/examples/calculator_shell/src/add_command.h
index 505fbab..40a4de3 100644
--- a/bundles/remote_services/examples/calculator_shell/src/add_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/add_command.h
@@ -16,17 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * add_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
+
#ifndef ADD_COMMAND_H_
#define ADD_COMMAND_H_
-void addCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool addCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
#endif /* ADD_COMMAND_H_ */
diff --git a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
index 05f5736..6cf1d5a 100644
--- a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
+++ b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
@@ -19,101 +19,51 @@
#include <stdlib.h>
#include <string.h>
-#include <celix_shell_command.h>
-#include "bundle_activator.h"
-#include "bundle_context.h"
-#include "service_registration.h"
+
+#include "celix_shell_command.h"
+#include "celix_api.h"
#include "add_command.h"
#include "sub_command.h"
#include "sqrt_command.h"
-struct activator {
- service_registration_t *addCommand;
- celix_shell_command_t *addCmd;
- celix_shell_command_t *addCmdSrv;
-
- service_registration_t *subCommand;
- celix_shell_command_t *subCmd;
- celix_shell_command_t *subCmdSrv;
-
- service_registration_t *sqrtCommand;
- celix_shell_command_t *sqrtCmd;
- celix_shell_command_t *sqrtCmdSrv;
-};
-
-celix_status_t bundleActivator_create(celix_bundle_context_t *context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- if (status == CELIX_SUCCESS) {
- *userData = calloc(1, sizeof(struct activator));
- if (!*userData) {
- status = CELIX_ENOMEM;
- } else {
- ((struct activator *) (*userData))->addCommand = NULL;
- ((struct activator *) (*userData))->subCommand = NULL;
- ((struct activator *) (*userData))->sqrtCommand = NULL;
-
- ((struct activator *) (*userData))->addCmd = NULL;
- ((struct activator *) (*userData))->subCmd = NULL;
- ((struct activator *) (*userData))->sqrtCmd = NULL;
-
- ((struct activator *) (*userData))->addCmdSrv = NULL;
- ((struct activator *) (*userData))->subCmdSrv = NULL;
- ((struct activator *) (*userData))->sqrtCmdSrv = NULL;
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, celix_bundle_context_t *context) {
- celix_status_t status = CELIX_SUCCESS;
-
- struct activator * activator = (struct activator *) userData;
-
- activator->addCmdSrv = calloc(1, sizeof(*activator->addCmdSrv));
- activator->addCmdSrv->handle = context;
- activator->addCmdSrv->executeCommand = (void *)addCommand_execute;
+typedef struct calc_shell_activator {
+ long addCmdSvcId;
+ celix_shell_command_t addCmd;
+ long subCmdSvcId;
+ celix_shell_command_t subCmd;
+ long sqrtCmdSvcId;
+ celix_shell_command_t sqrtCmd;
+} calc_shell_activator_t;
+
+static celix_status_t calcShell_start(calc_shell_activator_t *activator, celix_bundle_context_t *ctx) {
+ activator->addCmd.handle = ctx;
+ activator->addCmd.executeCommand = addCommand_execute;
celix_properties_t *props = celix_properties_create();
celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "add");
- bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->addCmdSrv, props, &activator->addCommand);
+ activator->addCmdSvcId = celix_bundleContext_registerService(ctx, &activator->addCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
-
- activator->sqrtCmdSrv = calloc(1, sizeof(*activator->sqrtCmdSrv));
- activator->sqrtCmdSrv->handle = context;
- activator->sqrtCmdSrv->executeCommand = (void *)sqrtCommand_execute;
- props = celix_properties_create();
- celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sqrt");
- bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->sqrtCmdSrv, props, &activator->sqrtCommand);
-
- activator->subCmdSrv = calloc(1, sizeof(*activator->subCmdSrv));
- activator->subCmdSrv->handle = context;
- activator->subCmdSrv->executeCommand = (void *)subCommand_execute;
+ activator->subCmd.handle = ctx;
+ activator->subCmd.executeCommand = subCommand_execute;
props = celix_properties_create();
celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sub");
- bundleContext_registerService(context, (char *)CELIX_SHELL_COMMAND_SERVICE_NAME, activator->subCmdSrv, props, &activator->subCommand);
-
- return status;
-}
+ activator->subCmdSvcId = celix_bundleContext_registerService(ctx, &activator->subCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
+ activator->sqrtCmd.handle = ctx;
+ activator->sqrtCmd.executeCommand = sqrtCommand_execute;
+ props = celix_properties_create();
+ celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "sqrt");
+ activator->sqrtCmdSvcId = celix_bundleContext_registerService(ctx, &activator->sqrtCmd, CELIX_SHELL_COMMAND_SERVICE_NAME, props);
-celix_status_t bundleActivator_stop(void * userData, celix_bundle_context_t *context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator * activator = (struct activator *) userData;
- serviceRegistration_unregister(activator->addCommand);
- serviceRegistration_unregister(activator->subCommand);
- serviceRegistration_unregister(activator->sqrtCommand);
-
- free(activator->addCmdSrv);
- free(activator->subCmdSrv);
- free(activator->sqrtCmdSrv);
-
- return status;
+ return CELIX_SUCCESS;
}
-celix_status_t bundleActivator_destroy(void * userData, celix_bundle_context_t *context) {
- free(userData);
+static celix_status_t calcShell_stop(calc_shell_activator_t *activator, celix_bundle_context_t *ctx) {
+ celix_bundleContext_unregisterService(ctx, activator->addCmdSvcId);
+ celix_bundleContext_unregisterService(ctx, activator->subCmdSvcId);
+ celix_bundleContext_unregisterService(ctx, activator->sqrtCmdSvcId);
return CELIX_SUCCESS;
}
+CELIX_GEN_BUNDLE_ACTIVATOR(calc_shell_activator_t, calcShell_start, calcShell_stop);
diff --git a/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor b/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor
deleted file mode 100644
index 35b4df7..0000000
--- a/bundles/remote_services/examples/calculator_shell/src/org.apache.celix.calc.api.Calculator.descriptor
+++ /dev/null
@@ -1,11 +0,0 @@
-:header
-type=interface
-name=calculator
-version=1.2.3
-:annotations
-classname=org.example.Calculator
-:types
-:methods
-add(DD)D=add(#am=handle;PDD#am=pre;*D)N
-sub(DD)D=sub(#am=handle;PDD#am=pre;*D)N
-sqrt(D)D=sqrt(#am=handle;PD#am=pre;*D)N
diff --git a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
index 07de852..175040a 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.c
@@ -16,66 +16,71 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * sqrt_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
+
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_api.h"
+#include "celix_utils.h"
#include "sqrt_command.h"
#include "calculator_service.h"
static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret);
-void sqrtCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+ double a;
+ double result;
+ int rc;
+};
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SQRT: Cannot get reference for %s.\n", CALCULATOR_SERVICE);
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- if(aStr != NULL){
- bool numeric;
- sqrtCommand_isNumeric(aStr, &numeric);
- if (numeric) {
- calculator_service_t *calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double result = 0;
- status = calculator->sqrt(calculator->calculator, a, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", a, result);
- } else {
- fprintf(err, "SQRT: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
+static void calcCallback(void *handle, void *svc) {
+ struct calc_callback_data *data = handle;
+ calculator_service_t *calc = svc;
+ data->rc = calc->sqrt(calc->handle, data->a, &data->result);
+}
+
+bool sqrtCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+ celix_bundle_context_t *context = handle;
+ bool ok = true;
+ char *line = celix_utils_strdup(const_line);
+
+
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ if(aStr != NULL) {
+ bool numeric;
+ sqrtCommand_isNumeric(aStr, &numeric);
+ if (numeric) {
+ struct calc_callback_data data;
+
+ data.a = atof(aStr);
+ data.result = 0;
+ data.rc = 0;
+ bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+ if (called && data.rc == 0) {
+ fprintf(out, "CALCULATOR_SHELL: Sqrt: %f = %f\n", data.a, data.result);
+ } else if (!called) {
+ fprintf(err, "ADD: calculator service not available\n");
+ ok = false;
} else {
- fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+ fprintf(err, "ADD: Unexpected exception in Calc service\n");
+ ok = false;
}
} else {
fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+ ok = false;
}
} else {
- fprintf(err, "No calc service available\n");
+ fprintf(err, "SQRT: Requires 1 numerical parameter\n");
+ ok = false;
}
- //return status;
+ free(line);
+
+ return ok;
}
static celix_status_t sqrtCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
index 65b5e7d..317363d 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/sqrt_command.h
@@ -16,17 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * sqrt_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
+
#ifndef SQRT_COMMAND_H_
#define SQRT_COMMAND_H_
-void sqrtCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool sqrtCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
#endif /* SQRT_COMMAND_H_ */
diff --git a/bundles/remote_services/examples/calculator_shell/src/sub_command.c b/bundles/remote_services/examples/calculator_shell/src/sub_command.c
index 9dbd5c1..9a1f89d 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sub_command.c
+++ b/bundles/remote_services/examples/calculator_shell/src/sub_command.c
@@ -16,69 +16,73 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * sub_command.c
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
-#include "array_list.h"
-#include "bundle_context.h"
+#include "celix_utils.h"
+#include "celix_api.h"
#include "sub_command.h"
#include "calculator_service.h"
static celix_status_t subCommand_isNumeric(char *number, bool *ret);
-void subCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err) {
- celix_status_t status = CELIX_SUCCESS;
- service_reference_pt calculatorService = NULL;
+struct calc_callback_data {
+ double a;
+ double b;
+ double result;
+ int rc;
+};
- status = bundleContext_getServiceReference(context, (char *) CALCULATOR_SERVICE, &calculatorService);
- if (calculatorService == NULL) {
- fprintf(err, "SUB: Cannot get reference for %s\n", CALCULATOR_SERVICE);
- }
- if (status == CELIX_SUCCESS) {
- char *token = line;
- strtok_r(line, " ", &token);
- char *aStr = strtok_r(NULL, " ", &token);
- char *bStr = strtok_r(NULL, " ", &token);
- if(aStr != NULL && bStr != NULL ){
- bool aNumeric, bNumeric;
- subCommand_isNumeric(aStr, &aNumeric);
- subCommand_isNumeric(bStr, &bNumeric);
- if (aNumeric && bNumeric) {
- calculator_service_t *calculator = NULL;
- status = bundleContext_getService(context, calculatorService, (void *) &calculator);
- if (status == CELIX_SUCCESS && calculator != NULL) {
- double a = atof(aStr);
- double b = atof(bStr);
- double result = 0;
- status = calculator->sub(calculator->calculator, a, b, &result);
- if (status == CELIX_SUCCESS) {
- fprintf(out, "CALCULATOR_SHELL: Sub: %f - %f = %f\n", a, b, result);
- } else {
- fprintf(err, "SUB: Unexpected exception in Calc service\n");
- }
- } else {
- fprintf(err, "No calc service available\n");
- }
+static void calcCallback(void *handle, void *svc) {
+ struct calc_callback_data *data = handle;
+ calculator_service_t *calc = svc;
+ data->rc = calc->sub(calc->handle, data->a, data->b, &data->result);
+}
+
+bool subCommand_execute(void *handle, const char *const_line, FILE *out, FILE *err) {
+ bool ok = true;
+ celix_bundle_context_t *context = handle;
+
+ char *line = celix_utils_strdup(const_line);
+
+ char *token = line;
+ strtok_r(line, " ", &token);
+ char *aStr = strtok_r(NULL, " ", &token);
+ char *bStr = strtok_r(NULL, " ", &token);
+ bool aNumeric, bNumeric;
+ if (aStr != NULL && bStr != NULL) {
+ subCommand_isNumeric(aStr, &aNumeric);
+ subCommand_isNumeric(bStr, &bNumeric);
+ if (aNumeric && bNumeric) {
+ struct calc_callback_data data;
+
+ data.a = atof(aStr);
+ data.b = atof(bStr);
+ data.result = 0;
+ data.rc = 0;
+ bool called = celix_bundleContext_useService(context, CALCULATOR_SERVICE, &data, calcCallback);
+ if (called && data.rc == 0) {
+ fprintf(out, "CALCULATOR_SHELL: Add: %f + %f = %f\n", data.a, data.b, data.result);
+ } else if (!called) {
+ fprintf(err, "Sub: calculator service not available\n");
+ ok = false;
} else {
- fprintf(err, "SUB: Requires 2 numerical parameter\n");
+ fprintf(err, "Sub: Unexpected exception in Calc service\n");
+ ok = false;
}
} else {
- fprintf(err, "SUB: Requires 2 numerical parameter\n");
+ fprintf(err, "Sub: Requires 2 numerical parameter\n");
+ ok = false;
}
} else {
- fprintf(err, "No calc service available\n");
+ fprintf(err, "Sub: Requires 2 numerical parameter\n");
+ ok = false;
}
- //return status;
+ free(line);
+ return ok;
}
static celix_status_t subCommand_isNumeric(char *number, bool *ret) {
diff --git a/bundles/remote_services/examples/calculator_shell/src/sub_command.h b/bundles/remote_services/examples/calculator_shell/src/sub_command.h
index 33a94c3..7673089 100644
--- a/bundles/remote_services/examples/calculator_shell/src/sub_command.h
+++ b/bundles/remote_services/examples/calculator_shell/src/sub_command.h
@@ -16,17 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- * sub_command.h
- *
- * \date Oct 13, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
+
#ifndef SUB_COMMAND_H_
#define SUB_COMMAND_H_
-void subCommand_execute(celix_bundle_context_t *context, char *line, FILE *out, FILE *err);
+bool subCommand_execute(void *handle, const char *line, FILE *out, FILE *err);
#endif /* SUB_COMMAND_H_ */
diff --git a/bundles/remote_services/examples/calculator_api/CMakeLists.txt b/bundles/remote_services/examples/remote_example_api/CMakeLists.txt
similarity index 67%
copy from bundles/remote_services/examples/calculator_api/CMakeLists.txt
copy to bundles/remote_services/examples/remote_example_api/CMakeLists.txt
index a87945f..6a0db33 100644
--- a/bundles/remote_services/examples/calculator_api/CMakeLists.txt
+++ b/bundles/remote_services/examples/remote_example_api/CMakeLists.txt
@@ -15,8 +15,14 @@
# specific language governing permissions and limitations
# under the License.
-add_library(calculator_api INTERFACE)
-target_include_directories(calculator_api INTERFACE include)
-set_target_properties(calculator_api PROPERTIES
- "INTERFACE_CALCULATOR_DESCRIPTOR"
- "${CMAKE_CURRENT_LIST_DIR}/include/org.apache.celix.calc.api.Calculator.avpr")
+#[[
+Note use avro-tools.jar (idl command) to generate avpr from avdl
+#]]
+
+add_library(remote_example_api INTERFACE)
+target_include_directories(remote_example_api INTERFACE include)
+set_target_properties(remote_example_api PROPERTIES
+ "INTERFACE_DESCRIPTOR"
+ "${CMAKE_CURRENT_LIST_DIR}/org.apache.celix.RemoteExample.descriptor")
+
+#TODO use avpr instead of descriptor
diff --git a/bundles/remote_services/examples/remote_example_api/include/remote_example.h b/bundles/remote_services/examples/remote_example_api/include/remote_example.h
new file mode 100644
index 0000000..85a6821
--- /dev/null
+++ b/bundles/remote_services/examples/remote_example_api/include/remote_example.h
@@ -0,0 +1,66 @@
+/**
+ *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.
+ */
+
+#ifndef CELIX_REMOTE_EXAMPLE_H
+#define CELIX_REMOTE_EXAMPLE_H
+
+#include <stdint.h>
+
+enum enum_example {
+ ENUM_EXAMPLE_VAL1 = 2,
+ ENUM_EXAMPLE_VAL2 = 4,
+ ENUM_EXAMPLE_VAL3 = 8
+};
+
+
+struct complex_input_example {
+ double a;
+ double b;
+ int32_t n;
+ char *name;
+ enum enum_example e;
+};
+
+struct complex_output_example {
+ double pow;
+ int32_t fib;
+ char *name;
+ enum enum_example e;
+};
+
+#define REMOTE_EXAMPLE_NAME "org.apache.celix.RemoteExample"
+
+typedef struct remote_example {
+ void *handle;
+
+ int (*pow)(void *handle, double a, double b, double *out);
+ int (*fib)(void *handle, int32_t n, int32_t *out);
+
+ int (*setName1)(void *handle, char *n, char **out);
+ int (*setName2)(void *handle, const char *n, char **out);
+
+ int (*setEnum)(void *handle, enum enum_example e, enum enum_example *out);
+
+ int (*action)(void *handle);
+
+ int (*setComplex)(void *handle, struct complex_input_example *exmpl, struct complex_output_example **out);
+
+} remote_example_t;
+
+#endif //CELIX_REMOTE_EXAMPLE_H
diff --git a/bundles/remote_services/examples/remote_example_api/org.apache.celix.RemoteExample.descriptor b/bundles/remote_services/examples/remote_example_api/org.apache.celix.RemoteExample.descriptor
new file mode 100644
index 0000000..7c43bff
--- /dev/null
+++ b/bundles/remote_services/examples/remote_example_api/org.apache.celix.RemoteExample.descriptor
@@ -0,0 +1,18 @@
+:header
+type=interface
+name=org.apache.celix.RemoteExample
+version=1.3.0
+:annotations
+classname=org.apache.celix.RemoteExample
+:types
+enum_example=#ENUM_EXAMPLE_VAL1=2;#ENUM_EXAMPLE_VAL2=4;#ENUM_EXAMPLE_VAL3=8;E
+complex_input={DDItlenum_example; a b n name e}
+complex_output={DItlenum_example; pow fib name e}
+:methods
+pow(DD)D=pow(#am=handle;PDD#am=pre;*D)N
+fib(I)I=fib(#am=handle;PI#am=pre;*I)N
+setName1=setName1(#am=handle;Pt#am=out;*t)N
+setName2=setName2(#am=handle;P#const=true;t#am=out;*t)N
+setEnum=setEnum(#am=handle;Plenum_example;#am=pre;Lenum_example;)N
+action=action(#am=handle;P)N
+setComplex=setComplex(#am=handle;PLcomplex_input;#am=out;*Lcomplex_output;)N
diff --git a/bundles/remote_services/examples/calculator_service/CMakeLists.txt b/bundles/remote_services/examples/remote_example_service/CMakeLists.txt
similarity index 64%
copy from bundles/remote_services/examples/calculator_service/CMakeLists.txt
copy to bundles/remote_services/examples/remote_example_service/CMakeLists.txt
index b47a3ae..03a2261 100644
--- a/bundles/remote_services/examples/calculator_service/CMakeLists.txt
+++ b/bundles/remote_services/examples/remote_example_service/CMakeLists.txt
@@ -15,15 +15,15 @@
# specific language governing permissions and limitations
# under the License.
-add_celix_bundle(calculator
+add_celix_bundle(remote_example_service
SOURCES
- src/calculator_impl
- src/calculator_activator
- SYMBOLIC_NAME "apache_celix_remoting_calculator_impl"
+ src/remote_example_activator.c
+ src/remote_example_impl.c
+ SYMBOLIC_NAME "apache_celix_remote_example_service"
VERSION 0.0.1
)
-target_include_directories(calculator PRIVATE src)
-target_link_libraries(calculator PRIVATE Celix::rsa_spi calculator_api)
+target_include_directories(remote_example_service PRIVATE src)
+target_link_libraries(remote_example_service PRIVATE Celix::rsa_spi remote_example_api)
-get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
-celix_bundle_files(calculator ${DESCR} DESTINATION .)
+get_target_property(DESCR remote_example_api INTERFACE_DESCRIPTOR)
+celix_bundle_files(remote_example_service ${DESCR} DESTINATION .)
diff --git a/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c b/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c
new file mode 100644
index 0000000..09da9b4
--- /dev/null
+++ b/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c
@@ -0,0 +1,62 @@
+/**
+ *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 <stdlib.h>
+
+#include <celix_api.h>
+
+#include "remote_example.h"
+#include "remote_constants.h"
+#include "remote_example_impl.h"
+
+struct activator {
+ remote_example_impl_t *impl;
+ remote_example_t service;
+ long svcId;
+};
+
+celix_status_t remoteExampleBndStart(struct activator *act, celix_bundle_context_t *ctx) {
+ act->svcId = -1L;
+ act->impl = remoteExample_create();
+ if (act->impl != NULL) {
+ act->service.handle = act->impl;
+ act->service.pow = (void*)remoteExample_pow;
+ act->service.fib = (void*)remoteExample_fib;
+ act->service.setName1 = (void*)remoteExample_setName1;
+ act->service.setName2 = (void*)remoteExample_setName2;
+ act->service.setEnum = (void*)remoteExample_setEnum;
+ act->service.action = (void*)remoteExample_action;
+ act->service.setComplex = (void*)remoteExample_setComplex;
+
+ celix_properties_t *properties = celix_properties_create();
+ celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, REMOTE_EXAMPLE_NAME);
+ act->svcId = celix_bundleContext_registerService(ctx, &act->service, REMOTE_EXAMPLE_NAME, properties);
+ }
+ return CELIX_SUCCESS;
+}
+
+celix_status_t remoteExampleBndStop(struct activator *act, celix_bundle_context_t *ctx) {
+ celix_bundleContext_unregisterService(ctx, act->svcId);
+ if (act->impl != NULL) {
+ remoteExample_destroy(act->impl);
+ }
+ return CELIX_SUCCESS;
+}
+
+CELIX_GEN_BUNDLE_ACTIVATOR(struct activator, remoteExampleBndStart, remoteExampleBndStop);
diff --git a/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c
new file mode 100644
index 0000000..2eb3eaa
--- /dev/null
+++ b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c
@@ -0,0 +1,129 @@
+/**
+ *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 <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "remote_example.h"
+#include "remote_example_impl.h"
+
+struct remote_example_impl {
+ pthread_mutex_t mutex; //protects below
+ char *name;
+ enum enum_example e;
+};
+
+remote_example_impl_t* remoteExample_create(void) {
+ remote_example_impl_t* impl = calloc(1, sizeof(remote_example_impl_t));
+ impl->e = ENUM_EXAMPLE_VAL1;
+ pthread_mutex_init(&impl->mutex, NULL);
+ return impl;
+}
+void remoteExample_destroy(remote_example_impl_t* impl) {
+ if (impl != NULL) {
+ pthread_mutex_destroy(&impl->mutex);
+ free(impl->name);
+ }
+ free(impl);
+}
+
+int remoteExample_pow(remote_example_impl_t* impl, double a, double b, double *out) {
+ *out = pow(a, b);
+ return 0;
+}
+
+static int fib_int(int n)
+{
+ if (n <= 0) {
+ return 0;
+ } else if (n <= 2) {
+ return 1;
+ } else {
+ return fib_int(n-1) + fib_int(n-2);
+ }
+}
+
+int remoteExample_fib(remote_example_impl_t* impl, int32_t a, int32_t *out) {
+ int r = fib_int(a);
+ *out = r;
+ return 0;
+}
+
+int remoteExample_setName1(remote_example_impl_t* impl, char *n, char **out) {
+ pthread_mutex_lock(&impl->mutex);
+ //note taking ownership of n;
+ if (impl->name != NULL) {
+ free(impl->name);
+ }
+ impl->name = n;
+ *out = strndup(impl->name, 1024 * 1024);
+ pthread_mutex_unlock(&impl->mutex);
+ return 0;
+}
+
+int remoteExample_setName2(remote_example_impl_t* impl, const char *n, char **out) {
+ pthread_mutex_lock(&impl->mutex);
+ //note _not_ taking ownership of n;
+ if (impl->name != NULL) {
+ free(impl->name);
+ }
+ impl->name = strndup(n, 1024 * 1024);
+ *out = strndup(impl->name, 1024 * 1024);
+ pthread_mutex_unlock(&impl->mutex);
+ return 0;
+}
+
+int remoteExample_setEnum(remote_example_impl_t* impl, enum enum_example e, enum enum_example *out) {
+ pthread_mutex_lock(&impl->mutex);
+ impl->e = e;
+ *out = e;
+ pthread_mutex_unlock(&impl->mutex);
+ return 0;
+}
+
+int remoteExample_action(remote_example_impl_t* impl) {
+ pthread_mutex_lock(&impl->mutex);
+ const char *n = impl->name;
+ printf("action called, name is %s\n", n);
+ pthread_mutex_unlock(&impl->mutex);
+ return 0;
+}
+
+int remoteExample_setComplex(remote_example_impl_t *impl, struct complex_input_example *exmpl, struct complex_output_example **out) {
+ struct complex_output_example *result = calloc(1, sizeof(*result));
+ int rc = remoteExample_pow(impl, exmpl->a, exmpl->b, &result->pow);
+ if (rc == 0) {
+ rc = remoteExample_fib(impl, exmpl->n, &result->fib);
+ }
+ if (rc == 0) {
+ rc = remoteExample_setName2(impl, exmpl->name, &result->name);
+ }
+ if (rc == 0) {
+ rc = remoteExample_setEnum(impl, exmpl->e, &result->e);
+ }
+ if (rc == 0 && out != NULL) {
+ *out = result;
+ } else {
+ free(result);
+ }
+
+ return rc;
+}
\ No newline at end of file
diff --git a/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.h b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.h
new file mode 100644
index 0000000..fe23f73
--- /dev/null
+++ b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.h
@@ -0,0 +1,40 @@
+/**
+ *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.
+ */
+
+#ifndef CELIX_REMOTE_EXAMPLE_IMPL_H
+#define CELIX_REMOTE_EXAMPLE_IMPL_H
+
+#include <stdlib.h>
+
+typedef struct remote_example_impl remote_example_impl_t;
+
+
+remote_example_impl_t* remoteExample_create(void);
+void remoteExample_destroy(remote_example_impl_t* impl);
+
+int remoteExample_pow(remote_example_impl_t* impl, double a, double b, double *out);
+int remoteExample_fib(remote_example_impl_t* impl, int32_t a, int32_t *out);
+int remoteExample_setEnum(remote_example_impl_t* impl, enum enum_example e, enum enum_example *out);
+int remoteExample_setName1(remote_example_impl_t* impl, char *n, char **out);
+int remoteExample_setName2(remote_example_impl_t* impl, const char *n, char **out);
+int remoteExample_action(remote_example_impl_t* impl);
+int remoteExample_setComplex(remote_example_impl_t *impl, struct complex_input_example *exmpl, struct complex_output_example **out);
+
+//TODO complex
+#endif //CELIX_REMOTE_EXAMPLE_IMPL_H
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
index fc01587..55a3810 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
@@ -340,7 +340,7 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret
celixThreadMutex_unlock(&import->mutex);
//printf("request sended. got reply '%s' with status %i\n", reply, rc);
- if (rc == 0) {
+ if (rc == 0 && dynFunction_hasReturn(entry->dynFunc)) {
//fjprintf("Handling reply '%s'\n", reply);
status = jsonRpc_handleReply(entry->dynFunc, reply, args);
}
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
index 0ba4574..eb45cf8 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
@@ -60,7 +60,7 @@ struct remote_service_admin {
celix_bundle_context_t *context;
log_helper_t *loghelper;
- celix_thread_mutex_t exportedServicesLock;
+ celix_thread_rwlock_t exportedServicesLock;
hash_map_pt exportedServices;
celix_thread_mutex_t importedServicesLock;
@@ -118,8 +118,8 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote
(*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
arrayList_create(&(*admin)->importedServices);
- celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
- celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+ celixThreadRwlock_create(&(*admin)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
logHelper_start((*admin)->loghelper);
@@ -217,7 +217,7 @@ celix_status_t remoteServiceAdmin_destroy(remote_service_admin_t **admin)
celix_status_t remoteServiceAdmin_stop(remote_service_admin_t *admin) {
celix_status_t status = CELIX_SUCCESS;
- celixThreadMutex_lock(&admin->exportedServicesLock);
+ celixThreadRwlock_writeLock(&admin->exportedServicesLock);
hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
while (hashMapIterator_hasNext(iter)) {
@@ -233,7 +233,7 @@ celix_status_t remoteServiceAdmin_stop(remote_service_admin_t *admin) {
arrayList_destroy(exports);
}
hashMapIterator_destroy(iter);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
+ celixThreadRwlock_unlock(&admin->exportedServicesLock);
celixThreadMutex_lock(&admin->importedServicesLock);
int i;
@@ -291,7 +291,7 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) {
service[pos] = '\0';
unsigned long serviceId = strtoul(service,NULL,10);
- celixThreadMutex_lock(&rsa->exportedServicesLock);
+ celixThreadRwlock_readLock(&rsa->exportedServicesLock);
//find endpoint
export_registration_t *export = NULL;
@@ -345,7 +345,7 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) {
RSA_LOG_WARNING(rsa, "No export registration found for service id %lu", serviceId);
}
- celixThreadMutex_unlock(&rsa->exportedServicesLock);
+ celixThreadRwlock_unlock(&rsa->exportedServicesLock);
}
}
@@ -442,9 +442,9 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_t *admin, c
if (status == CELIX_SUCCESS) {
- celixThreadMutex_lock(&admin->exportedServicesLock);
+ celixThreadRwlock_writeLock(&admin->exportedServicesLock);
hashMap_put(admin->exportedServices, reference, *registrations);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
+ celixThreadRwlock_unlock(&admin->exportedServicesLock);
} else {
arrayList_destroy(*registrations);
*registrations = NULL;
@@ -464,7 +464,7 @@ celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_t *
if (status == CELIX_SUCCESS && ref != NULL) {
service_reference_pt servRef;
- celixThreadMutex_lock(&admin->exportedServicesLock);
+ celixThreadRwlock_writeLock(&admin->exportedServicesLock);
exportReference_getExportedService(ref, &servRef);
array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
@@ -475,7 +475,7 @@ celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_t *
exportRegistration_close(registration);
exportRegistration_destroy(registration);
- celixThreadMutex_unlock(&admin->exportedServicesLock);
+ celixThreadRwlock_unlock(&admin->exportedServicesLock);
free(ref);
@@ -748,7 +748,7 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
- logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
+ //logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
res = curl_easy_perform(curl);
*reply = get.writeptr;
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt b/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
index 20efa08..dddd0a5 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
+++ b/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
@@ -23,9 +23,16 @@ add_celix_bundle(rsa_dfi_tst_bundle
SOURCES
src/tst_activator.c
)
-get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+
+#add calculator avpr
+get_target_property(DESCR calculator_api INTERFACE_DESCRIPTOR)
+celix_bundle_files(rsa_dfi_tst_bundle ${DESCR} DESTINATION .)
+
+#add remote example avpr
+get_target_property(DESCR remote_example_api INTERFACE_DESCRIPTOR)
celix_bundle_files(rsa_dfi_tst_bundle ${DESCR} DESTINATION .)
-target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)
+
+target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api remote_example_api)
target_include_directories(rsa_dfi_tst_bundle PRIVATE src)
add_executable(test_rsa_dfi
@@ -37,7 +44,8 @@ target_include_directories(test_rsa_dfi PRIVATE src)
target_link_libraries(test_rsa_dfi PRIVATE CURL::libcurl ${CPPUTEST_LIBRARY}
Celix::framework
Celix::rsa_common
- calculator_api)
+ calculator_api
+)
get_property(rsa_bundle_file TARGET rsa_dfi PROPERTY BUNDLE_FILE)
get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
@@ -45,6 +53,7 @@ get_property(calculator_shell_bundle_file TARGET calculator_shell PROPERTY BUNDL
get_property(discovery_configured_bundle_file TARGET rsa_discovery_configured PROPERTY BUNDLE_FILE)
get_property(topology_manager_bundle_file TARGET Celix::rsa_topology_manager PROPERTY BUNDLE_FILE)
get_property(tst_bundle_file TARGET rsa_dfi_tst_bundle PROPERTY BUNDLE_FILE)
+get_property(remote_example_bundle_file TARGET remote_example_service PROPERTY BUNDLE_FILE)
configure_file(config.properties.in config.properties)
configure_file(client.properties.in client.properties)
@@ -53,6 +62,7 @@ configure_file(server.properties.in server.properties)
add_dependencies(test_rsa_dfi
rsa_dfi_bundle #note depend on the target creating the bundle zip not the lib target
calculator_bundle
+ remote_example_service_bundle
)
add_test(NAME run_test_rsa_dfi COMMAND test_rsa_dfi)
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in b/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
index 92e3407..5a1fa7d 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
+++ b/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @remote_example_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@
LOGHELPER_ENABLE_STDOUT_FALLBACK=true
org.osgi.framework.storage.clean=onFirstInit
org.osgi.framework.storage=.cacheServer
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
index 05935a6..3622235 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
@@ -17,12 +17,13 @@
* under the License.
*/
-#include <CppUTest/TestHarness.h>
+
#include <remote_constants.h>
-#include "celix_constants.h"
#include <tst_service.h>
-#include "CppUTest/CommandLineTestRunner.h"
-#include "calculator_service.h"
+#include "celix_api.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
extern "C" {
@@ -36,7 +37,6 @@ extern "C" {
#include "celix_launcher.h"
#include "framework.h"
#include "remote_service_admin.h"
-#include "calculator_service.h"
static celix_framework_t *serverFramework = NULL;
static celix_bundle_context_t *serverContext = NULL;
@@ -45,74 +45,69 @@ extern "C" {
static celix_bundle_context_t *clientContext = NULL;
static void setupFm(void) {
- int rc = 0;
- celix_bundle_t *bundle = NULL;
-
//server
- rc = celixLauncher_launch("server.properties", &serverFramework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bundle = NULL;
- rc = framework_getFrameworkBundle(serverFramework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &serverContext);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
+ celix_properties_t *serverProps = celix_properties_load("server.properties");
+ CHECK_TRUE(serverProps != NULL);
+ serverFramework = celix_frameworkFactory_createFramework(serverProps);
+ CHECK_TRUE(serverFramework != NULL);
+ serverContext = celix_framework_getFrameworkContext(serverFramework);
+ CHECK_TRUE(serverContext != NULL);
//client
- rc = celixLauncher_launch("client.properties", &clientFramework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bundle = NULL;
- rc = framework_getFrameworkBundle(clientFramework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &clientContext);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
+ celix_properties_t *clientProperties = celix_properties_load("client.properties");
+ CHECK_TRUE(clientProperties != NULL);
+ clientFramework = celix_frameworkFactory_createFramework(clientProperties);
+ CHECK_TRUE(clientFramework != NULL);
+ clientContext = celix_framework_getFrameworkContext(clientFramework);
+ CHECK_TRUE(clientContext != NULL);
}
static void teardownFm(void) {
- celixLauncher_stop(serverFramework);
- celixLauncher_waitForShutdown(serverFramework);
- celixLauncher_destroy(serverFramework);
-
- celixLauncher_stop(clientFramework);
- celixLauncher_waitForShutdown(clientFramework);
- celixLauncher_destroy(clientFramework);
-
- serverContext = NULL;
- serverFramework = NULL;
- clientContext = NULL;
- clientFramework = NULL;
+ celix_frameworkFactory_destroyFramework(serverFramework);
+ celix_frameworkFactory_destroyFramework(clientFramework);
}
- static void test1(void) {
- celix_status_t rc;
- service_reference_pt ref = NULL;
- tst_service_t *tst = NULL;
- int retries = 4;
-
- while (ref == NULL && retries > 0) {
- printf("Waiting for service .. %d\n", retries);
- rc = bundleContext_getServiceReference(clientContext, (char *) TST_SERVICE_NAME, &ref);
- usleep(1000000);
- --retries;
- }
-
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(ref != NULL);
-
- rc = bundleContext_getService(clientContext, ref, (void **)&tst);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(tst != NULL);
-
- rc = tst->test(tst->handle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- bool result;
- bundleContext_ungetService(clientContext, ref, &result);
- bundleContext_ungetServiceReference(clientContext, ref);
+ static void testCallback(void *handle __attribute__((unused)), void *svc) {
+ auto *tst = static_cast<tst_service_t *>(svc);
+
+ bool ok;
+
+ bool discovered = tst->isCalcDiscovered(tst->handle);
+ CHECK_TRUE(discovered);
+
+// ok = tst->testCalculator(tst->handle);
+// CHECK_TRUE(ok);
+
+ discovered = tst->isRemoteExampleDiscovered(tst->handle);
+ CHECK_TRUE(discovered);
+
+// ok = tst->testRemoteString(tst->handle);
+// CHECK_TRUE(ok);
+//
+// ok = tst->testRemoteConstString(tst->handle);
+// CHECK_TRUE(ok);
+
+ ok = tst->testRemoteNumbers(tst->handle);
+ CHECK_TRUE(ok);
+
+// ok = tst->testRemoteEnum(tst->handle);
+// CHECK_TRUE(ok);
+//
+// ok = tst->testRemoteAction(tst->handle);
+// CHECK_TRUE(ok);
+//
+// ok = tst->testRemoteComplex(tst->handle);
+// CHECK_TRUE(ok);
+ };
+
+ static void test(void) {
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = TST_SERVICE_NAME;
+ opts.use = testCallback;
+ opts.filter.ignoreServiceLanguage = true;
+ opts.waitTimeoutInSeconds = 2;
+ bool called = celix_bundleContext_useServiceWithOptions(clientContext, &opts);
+ CHECK_TRUE(called);
}
}
@@ -129,5 +124,5 @@ TEST_GROUP(RsaDfiClientServerTests) {
};
TEST(RsaDfiClientServerTests, Test1) {
- test1();
+ test();
}
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
index fe25fa0..cc7d09f 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
@@ -17,133 +17,100 @@
* under the License.
*/
-#include <CppUTest/TestHarness.h>
#include <remote_constants.h>
-#include "celix_constants.h"
-#include "CppUTest/CommandLineTestRunner.h"
+#include "celix_api.h"
#include "calculator_service.h"
-extern "C" {
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTest/CommandLineTestRunner.h>
+
+extern "C" {
-#include "celix_launcher.h"
-#include "framework.h"
#include "remote_service_admin.h"
#include "calculator_service.h"
#define TST_CONFIGURATION_TYPE "org.amdatu.remote.admin.http"
- static framework_pt framework = NULL;
+ static celix_framework_t *framework = NULL;
static celix_bundle_context_t *context = NULL;
- static service_reference_pt rsaRef = NULL;
- static remote_service_admin_service_t *rsa = NULL;
-
- static service_reference_pt calcRef = NULL;
- static calculator_service_t *calc = NULL;
+ long calcSvcId = -1L;
static void setupFm(void) {
- int rc = 0;
-
- rc = celixLauncher_launch("config.properties", &framework);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
+ celix_properties_t *fwProperties = celix_properties_load("config.properties");
+ CHECK_TRUE(fwProperties != NULL);
+ framework = celix_frameworkFactory_createFramework(fwProperties);
+ CHECK_TRUE(framework != NULL);
+ context = celix_framework_getFrameworkContext(framework);
+ CHECK_TRUE(context != NULL);
- celix_bundle_t *bundle = NULL;
- rc = framework_getFrameworkBundle(framework, &bundle);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundle_getContext(bundle, &context);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(rsaRef != NULL);
-
- rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_getServiceReference(context, (char *)CALCULATOR_SERVICE, &calcRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK(calcRef != NULL);
-
- rc = bundleContext_getService(context, calcRef, (void **)&calc);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
+ calcSvcId = celix_bundleContext_findService(context, CALCULATOR_SERVICE);
+ CHECK_TRUE(calcSvcId >= 0L);
}
static void teardownFm(void) {
- int rc = 0;
- rc = bundleContext_ungetService(context, rsaRef, NULL);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetServiceReference(context, rsaRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetService(context, calcRef, NULL);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- rc = bundleContext_ungetServiceReference(context, calcRef);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
-
- celixLauncher_stop(framework);
- celixLauncher_waitForShutdown(framework);
- celixLauncher_destroy(framework);
-
- rsaRef = NULL;
- rsa = NULL;
- calcRef = NULL;
- calc = NULL;
- context = NULL;
- framework = NULL;
+ celix_frameworkFactory_destroyFramework(framework);
}
- static void testServices(void) {
- int rc = 0;
- array_list_pt exported = NULL;
- array_list_pt imported = NULL;
- arrayList_create(&exported);
- arrayList_create(&imported);
+ static void testServicesCallback(void *handle __attribute__((unused)), void *svc) {
+ auto* rsa = static_cast<remote_service_admin_service_t*>(svc);
+ celix_array_list_t *exported = celix_arrayList_create();
+ celix_array_list_t *imported = celix_arrayList_create();
- rc = rsa->getExportedServices(rsa->admin, &exported);
+ int rc = rsa->getExportedServices(rsa->admin, &exported);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(0, arrayList_size(exported));
+ CHECK_EQUAL(0, celix_arrayList_size(exported));
rc = rsa->getImportedEndpoints(rsa->admin, &imported);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(0, arrayList_size(imported));
+ CHECK_EQUAL(0, celix_arrayList_size(imported));
- double result = 0;
- rc = calc->add(calc->calculator, 2.0, 5.0, &result);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(7.0, result);
+ celix_arrayList_destroy(imported);
+ celix_arrayList_destroy(exported);
+ }
- arrayList_destroy(imported);
- arrayList_destroy(exported);
+ static void testServices(void) {
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN;
+ opts.use = testServicesCallback;
+ opts.filter.ignoreServiceLanguage = true;
+ opts.waitTimeoutInSeconds = 0.25;
+ bool called = celix_bundleContext_useServiceWithOptions(context, &opts);
+ CHECK_TRUE(called);
}
- static void testExportService(void) {
- int rc = 0;
- const char *calcId = NULL;
- array_list_pt regs = NULL;
+ static void testExportServiceCallback(void *handle __attribute__((unused)), void *svc) {
+ auto* rsa = static_cast<remote_service_admin_service_t*>(svc);
- rc = serviceReference_getProperty(calcRef, (char *)"service.id", &calcId);
- CHECK_EQUAL(CELIX_SUCCESS, rc);
+ char strSvcId[64];
+ snprintf(strSvcId, 64, "%li", calcSvcId);
- rc = rsa->exportService(rsa->admin, (char*)calcId, NULL, ®s);
+ celix_array_list_t *svcRegistration = NULL;
+ int rc = rsa->exportService(rsa->admin, strSvcId, NULL, &svcRegistration);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- CHECK_EQUAL(1, arrayList_size(regs));
+ CHECK_EQUAL(1, celix_arrayList_size(svcRegistration));
- rc = rsa->exportRegistration_close(rsa->admin,(export_registration_t *)(arrayList_get(regs,0)));
+ rc = rsa->exportRegistration_close(rsa->admin,(export_registration_t *)(arrayList_get(svcRegistration,0)));
CHECK_EQUAL(CELIX_SUCCESS, rc);
+ }
+
+ static void testExportService(void) {
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN;
+ opts.use = testExportServiceCallback;
+ opts.filter.ignoreServiceLanguage = true;
+ opts.waitTimeoutInSeconds = 0.25;
+ bool called = celix_bundleContext_useServiceWithOptions(context, &opts);
+ CHECK_TRUE(called);
}
- static void testImportService(void) {
+ static void testImportServiceCallback(void *handle __attribute__((unused)), void *svc) {
+ auto *rsa = static_cast<remote_service_admin_service_t *>(svc);
+
int rc = 0;
import_registration_t *reg = NULL;
endpoint_description_t *endpoint = NULL;
@@ -181,6 +148,16 @@ extern "C" {
*/
}
+ static void testImportService(void) {
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN;
+ opts.use = testImportServiceCallback;
+ opts.filter.ignoreServiceLanguage = true;
+ opts.waitTimeoutInSeconds = 0.25;
+ bool called = celix_bundleContext_useServiceWithOptions(context, &opts);
+ CHECK_TRUE(called);
+ }
+
static void testBundles(void) {
array_list_pt bundles = NULL;
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
index c0d52be..efaee82 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
@@ -21,5 +21,6 @@
#include "CppUTest/CommandLineTestRunner.h"
int main(int argc, char** argv) {
+ MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
return RUN_ALL_TESTS(argc, argv);
}
\ No newline at end of file
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
index 98612e2..5894c73 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
@@ -24,16 +24,19 @@
#include "tst_service.h"
#include "calculator_service.h"
+#include "remote_example.h"
#include <unistd.h>
struct activator {
long svcId;
struct tst_service testSvc;
- long trackerId;
+ long trackerId1;
+ long trackerId2;
pthread_mutex_t mutex; //protects below
calculator_service_t *calc;
+ remote_example_t *remoteExample;
};
static void bndSetCalc(void* handle, void* svc) {
@@ -43,11 +46,15 @@ static void bndSetCalc(void* handle, void* svc) {
pthread_mutex_unlock(&act->mutex);
}
-static int bndTest(void *handle) {
- int status = 0;
- struct activator *act = handle;
+static void bndSetRemoteExample(void* handle, void* svc) {
+ struct activator * act = handle;
+ pthread_mutex_lock(&act->mutex);
+ act->remoteExample = svc;
+ pthread_mutex_unlock(&act->mutex);
+}
- double result = -1.0;
+static bool bndIsCalculatorDiscovered(void *handle) {
+ struct activator *act = handle;
int retries = 40;
@@ -64,28 +71,199 @@ static int bndTest(void *handle) {
pthread_mutex_unlock(&act->mutex);
}
+ bool discovered = local != NULL;
+ return discovered;
+}
+
+static bool bndIsRemoteExampleDiscovered(void *handle) {
+ struct activator *act = handle;
+
+ int retries = 40;
+
+ pthread_mutex_lock(&act->mutex);
+ remote_example_t *local = act->remoteExample;
+ pthread_mutex_unlock(&act->mutex);
+
+ while (local == NULL && retries > 0) {
+ printf("Waiting for remote example service .. %d\n", retries);
+ usleep(100000);
+ --retries;
+ pthread_mutex_lock(&act->mutex);
+ local = act->remoteExample;
+ pthread_mutex_unlock(&act->mutex);
+ }
+
+ bool discovered = local != NULL;
+ return discovered;
+}
+
+static bool bndTestCalculator(void *handle) {
+ struct activator *act = handle;
+
+ double result = -1.0;
pthread_mutex_lock(&act->mutex);
int rc = 1;
if (act->calc != NULL) {
- rc = act->calc->sqrt(act->calc->calculator, 4, &result);
+ rc = act->calc->sqrt(act->calc->handle, 4, &result);
printf("calc result is %f\n", result);
} else {
printf("calc not ready\n");
}
pthread_mutex_unlock(&act->mutex);
+ return rc == 0 && result == 2.0;
+}
+
+static bool bndTestRemoteString(void *handle) {
+ bool ok;
+ struct activator *act = handle;
+
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+ //test string call with taking ownership
+ char *tmp = strndup("test1", 1024);
+ char *result = NULL;
+ act->remoteExample->setName1(act->remoteExample->handle, tmp, &result);
+ //note setName1 should take ownership of tmp, so no free(tmp) needed.
+ ok = strncmp("test1", result, 1024) == 0;
+ free(result);
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
+ }
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
+}
+
+static bool bndTestRemoteConstString(void *handle) {
+ bool ok;
+ struct activator *act = handle;
+
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+ //test pow
+ const char *name = "name2";
+ char *result = NULL;
+ act->remoteExample->setName2(act->remoteExample->handle, name, &result);
+ ok = strncmp(result, "name2", 1024) == 0;
+ free(result);
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
+ }
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
+}
+
+static bool bndTestRemoteNumbers(void *handle) {
+ bool ok = true;
+ struct activator *act = handle;
+
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+
+ if (ok) {
+ //test pow
+ double p;
+ act->remoteExample->pow(act->remoteExample->handle, 2, 2, &p);
+ ok = (p == 4.0);
+ }
+
+ if (ok) {
+ //test fib
+ int32_t f;
+ act->remoteExample->fib(act->remoteExample->handle, 4, &f);
+ ok = (f == 3);
+ }
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
+ }
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
+}
+
+static bool bndTestRemoteEnum(void *handle) {
+ bool ok;
+ struct activator *act = handle;
+
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+ enum enum_example e = ENUM_EXAMPLE_VAL2;
+ enum enum_example result = ENUM_EXAMPLE_VAL3;
+ int rc = act->remoteExample->setEnum(act->remoteExample->handle, e, &result);
+ ok = rc == 0 && result == ENUM_EXAMPLE_VAL2;
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
+ }
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
+}
+
+static bool bndTestRemoteAction(void *handle) {
+ bool ok;
+ struct activator *act = handle;
+
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+ int rc = act->remoteExample->action(act->remoteExample->handle);
+ ok = rc == 0;
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
+ }
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
+}
+
+static bool bndTestRemoteComplex(void *handle) {
+ bool ok;
+ struct activator *act = handle;
- if (rc != 0 || result != 2.0) {
- status = 1;
+ pthread_mutex_lock(&act->mutex);
+ if (act->remoteExample != NULL) {
+ struct complex_input_example exmpl;
+ exmpl.a = 2;
+ exmpl.b = 3;
+ exmpl.n = 5;
+ exmpl.name = "name";
+ exmpl.e = ENUM_EXAMPLE_VAL3;
+ struct complex_output_example* result = NULL;
+ int rc = act->remoteExample->setComplex(act->remoteExample->handle, &exmpl, &result);
+ ok = rc == 0 && result->pow == 8 && result->fib == 5 && strncmp("name", result->name, 64) == 0;
+ if (rc == 0) {
+ free(result->name);
+ free(result);
+ }
+ } else {
+ fprintf(stderr, "remote example service not available");
+ ok = false;
}
- return status;
+ pthread_mutex_unlock(&act->mutex);
+
+ return ok;
}
static celix_status_t bndStart(struct activator *act, celix_bundle_context_t* ctx) {
//initialize service struct
act->testSvc.handle = act;
- act->testSvc.test = bndTest;
+ act->testSvc.isCalcDiscovered = bndIsCalculatorDiscovered;
+ act->testSvc.isRemoteExampleDiscovered = bndIsRemoteExampleDiscovered;
+ act->testSvc.testCalculator = bndTestCalculator;
+ act->testSvc.testRemoteString = bndTestRemoteString;
+ act->testSvc.testRemoteConstString = bndTestRemoteConstString;
+ act->testSvc.testRemoteNumbers = bndTestRemoteNumbers;
+ act->testSvc.testRemoteEnum = bndTestRemoteEnum;
+ act->testSvc.testRemoteAction = bndTestRemoteAction;
+ act->testSvc.testRemoteComplex = bndTestRemoteComplex;
+
//create mutex
pthread_mutex_init(&act->mutex, NULL);
@@ -97,7 +275,15 @@ static celix_status_t bndStart(struct activator *act, celix_bundle_context_t* ct
opts.callbackHandle = act;
opts.filter.serviceName = CALCULATOR_SERVICE;
opts.filter.ignoreServiceLanguage = true;
- act->trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+ act->trackerId1 = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+ }
+ {
+ celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.set = bndSetRemoteExample;
+ opts.callbackHandle = act;
+ opts.filter.serviceName = REMOTE_EXAMPLE_NAME;
+ opts.filter.ignoreServiceLanguage = true;
+ act->trackerId2 = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
}
//register test service
@@ -107,7 +293,8 @@ static celix_status_t bndStart(struct activator *act, celix_bundle_context_t* ct
static celix_status_t bndStop(struct activator *act, celix_bundle_context_t* ctx) {
celix_bundleContext_unregisterService(ctx, act->svcId);
- celix_bundleContext_stopTracker(ctx, act->trackerId);
+ celix_bundleContext_stopTracker(ctx, act->trackerId1);
+ celix_bundleContext_stopTracker(ctx, act->trackerId2);
pthread_mutex_destroy(&act->mutex);
return CELIX_SUCCESS;
}
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
index 0724794..596ab63 100644
--- a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
@@ -24,7 +24,15 @@
struct tst_service {
void *handle;
- int (*test)(void *handle);
+ bool (*isCalcDiscovered)(void *handle);
+ bool (*isRemoteExampleDiscovered)(void *handle);
+ bool (*testCalculator)(void *handle);
+ bool (*testRemoteString)(void *handle);
+ bool (*testRemoteConstString)(void *handle);
+ bool (*testRemoteNumbers)(void *handle);
+ bool (*testRemoteEnum)(void *handle);
+ bool (*testRemoteAction)(void *handle);
+ bool (*testRemoteComplex)(void *handle);
};
typedef struct tst_service tst_service_t;
diff --git a/bundles/shell/shell/CMakeLists.txt b/bundles/shell/shell/CMakeLists.txt
index 1331823..ad65293 100644
--- a/bundles/shell/shell/CMakeLists.txt
+++ b/bundles/shell/shell/CMakeLists.txt
@@ -26,7 +26,7 @@ if (SHELL)
install(TARGETS shell_api EXPORT celix COMPONENT shell)
install(DIRECTORY api/ DESTINATION include/celix/shell COMPONENT shell)
- if (CELIX_ADD_DEPRECATED_API)
+ if (CELIX_INSTALL_DEPRECATED_API)
target_include_directories(shell_api INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/deprecated_api>)
install(DIRECTORY deprecated_api/ DESTINATION include/celix/shell COMPONENT shell)
endif ()
@@ -54,8 +54,8 @@ if (SHELL)
target_include_directories(shell PRIVATE src)
target_link_libraries(shell PRIVATE Celix::shell_api CURL::libcurl Celix::log_service_api Celix::log_helper)
target_compile_options(shell PRIVATE -Wno-deprecated-declarations)
- if (CELIX_ADD_DEPRECATED_API)
- target_compile_definitions(shell PRIVATE CELIX_ADD_DEPRECATED_API)
+ if (CELIX_INSTALL_DEPRECATED_API)
+ target_compile_definitions(shell PRIVATE CELIX_INSTALL_DEPRECATED_API)
endif ()
install_celix_bundle(shell EXPORT celix COMPONENT shell)
diff --git a/bundles/shell/shell/deprecated_api/command.h b/bundles/shell/shell/deprecated_api/command.h
index a65b3e3..0e63e63 100644
--- a/bundles/shell/shell/deprecated_api/command.h
+++ b/bundles/shell/shell/deprecated_api/command.h
@@ -33,6 +33,12 @@
typedef struct commandService command_service_t;
typedef command_service_t * command_service_pt;
+#ifdef CELIX_ADD_DEPRECATED_ATTRIBUTES
+#define DEP_ATTRIBUTE __attribute__((deprecated("command_service_t is replaced by celix_shell_command_t in celix_shell_command.h")))
+#else
+#define DEP_ATTRIBUTE
+#endif
+
/**
* The command service can be used to register additional shell commands.
* The service should be register with the following properties:
@@ -45,8 +51,7 @@ typedef command_service_t * command_service_pt;
struct commandService {
void *handle;
- celix_status_t (*executeCommand)(void *handle, char * commandLine, FILE *outStream, FILE *errorStream)
- __attribute__((deprecated("command_service_t is replaced by celix_shell_command_t in celix_shell_command.h")));
+ celix_status_t (*executeCommand)(void *handle, char * commandLine, FILE *outStream, FILE *errorStream) DEP_ATTRIBUTE;
};
diff --git a/bundles/shell/shell/src/activator.c b/bundles/shell/shell/src/activator.c
index 6e0d80c..34a531f 100644
--- a/bundles/shell/shell/src/activator.c
+++ b/bundles/shell/shell/src/activator.c
@@ -234,7 +234,7 @@ celix_status_t bundleActivator_start(void *activatorData, celix_bundle_context_t
}
activator->legacyTrackerId = -1L;
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
if (status == CELIX_SUCCESS) {
celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
opts.callbackHandle = activator->shell;
diff --git a/bundles/shell/shell/src/help_command.c b/bundles/shell/shell/src/help_command.c
index accf620..fa124bb 100644
--- a/bundles/shell/shell/src/help_command.c
+++ b/bundles/shell/shell/src/help_command.c
@@ -92,6 +92,11 @@ static void printHelp(void *handle, void *svc) {
free(name);
}
celix_arrayList_destroy(commands);
+
+ if (!cmdFound) {
+ fprintf(out, "Command '%s' not found. Type 'help' to get an overview of the available commands\n", sub);
+ }
+
p->callSucceeded = cmdFound;
}
}
diff --git a/bundles/shell/shell/src/shell.c b/bundles/shell/shell/src/shell.c
index 1c2375b..d25cf3a 100644
--- a/bundles/shell/shell/src/shell.c
+++ b/bundles/shell/shell/src/shell.c
@@ -114,7 +114,7 @@ celix_status_t shell_removeCommand(shell_t *shell, celix_shell_command_t *svc, c
return status;
}
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
celix_status_t shell_addLegacyCommand(shell_t *shell, command_service_t *svc, const celix_properties_t *props) {
celix_status_t status = CELIX_SUCCESS;
const char *name = celix_properties_get(props, OSGI_SHELL_COMMAND_NAME, NULL);
@@ -141,7 +141,7 @@ celix_status_t shell_addLegacyCommand(shell_t *shell, command_service_t *svc, co
}
#endif
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
celix_status_t shell_removeLegacyCommand(shell_t *shell, command_service_t *svc, const celix_properties_t *props) {
celix_status_t status = CELIX_SUCCESS;
const char *name = celix_properties_get(props, OSGI_SHELL_COMMAND_NAME, NULL);
diff --git a/bundles/shell/shell/src/shell_private.h b/bundles/shell/shell/src/shell_private.h
index 3b35c52..a185b05 100644
--- a/bundles/shell/shell/src/shell_private.h
+++ b/bundles/shell/shell/src/shell_private.h
@@ -26,7 +26,7 @@
#include "celix_shell_command.h"
#include "log_helper.h"
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
#include "command.h"
#endif
@@ -39,7 +39,7 @@ typedef struct celix_shell_command_entry {
} celix_shell_command_entry_t;
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
typedef struct celix_legacy_command_entry {
long svcId;
command_service_t *svc;
@@ -80,7 +80,7 @@ celix_status_t shell_getCommands(shell_t *shell, celix_array_list_t **commands);
celix_status_t shell_getCommandUsage(shell_t *shell, const char *commandName, char **outUsage);
celix_status_t shell_getCommandDescription(shell_t *shell, const char *commandName, char **outDescription);
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
celix_status_t shell_addLegacyCommand(shell_t *shell, command_service_t *svc, const celix_properties_t *props);
celix_status_t shell_removeLegacyCommand(shell_t *shell, command_service_t *svc, const celix_properties_t *props);
#endif
diff --git a/bundles/shell/shell/test/CMakeLists.txt b/bundles/shell/shell/test/CMakeLists.txt
index 868b05e..6df4b32 100644
--- a/bundles/shell/shell/test/CMakeLists.txt
+++ b/bundles/shell/shell/test/CMakeLists.txt
@@ -27,8 +27,8 @@ target_include_directories(test_shell PRIVATE ${CPPUTEST_INCLUDE_DIRS})
add_dependencies(test_shell shell_bundle)
target_compile_definitions(test_shell PRIVATE -DSHELL_BUNDLE_LOCATION=\"$<TARGET_PROPERTY:shell,BUNDLE_FILE>\")
target_compile_options(test_shell PRIVATE -Wno-deprecated-declarations)
-if (CELIX_ADD_DEPRECATED_API)
- target_compile_definitions(test_shell PRIVATE CELIX_ADD_DEPRECATED_API)
+if (CELIX_INSTALL_DEPRECATED_API)
+ target_compile_definitions(test_shell PRIVATE CELIX_INSTALL_DEPRECATED_API)
endif ()
add_test(NAME test_shell COMMAND test_shell)
diff --git a/bundles/shell/shell/test/src/shell_tests.cpp b/bundles/shell/shell/test/src/shell_tests.cpp
index 8074555..c0e09f4 100644
--- a/bundles/shell/shell/test/src/shell_tests.cpp
+++ b/bundles/shell/shell/test/src/shell_tests.cpp
@@ -174,7 +174,7 @@ TEST(CelixShellTests, localNameClashTest) {
}
-#ifdef CELIX_ADD_DEPRECATED_API
+#ifdef CELIX_INSTALL_DEPRECATED_API
#include "command.h"
TEST(CelixShellTests, legacyCommandTest) {
command_service_t cmdService;
diff --git a/libs/dfi/include/dyn_function.h b/libs/dfi/include/dyn_function.h
index 6a54622..4b92456 100644
--- a/libs/dfi/include/dyn_function.h
+++ b/libs/dfi/include/dyn_function.h
@@ -31,6 +31,11 @@
* am=handle #void pointer for the handle
* am=pre #output pointer with memory pre-allocated
* am=out #output pointer
+ *
+ * text argument (t) can also be annotated to be considered const string.
+ * Normally a text argument will be handled as char*, meaning that the callee is expected to take of ownership.
+ * If a const=true annotation is used the text argument will be handled as a const char*, meaning that the caller
+ * keeps ownership of the string.
*/
typedef struct _dyn_function_type dyn_function_type;
@@ -59,8 +64,16 @@ int dynFunction_call(dyn_function_type *dynFunc, void(*fn)(void), void *returnVa
int dynFunction_createClosure(dyn_function_type *func, void (*bind)(void *, void **, void*), void *userData, void(**fn)(void));
int dynFunction_getFnPointer(dyn_function_type *func, void (**fn)(void));
+/**
+ * Returns whether the function has a return type.
+ * Will return false if return is void.
+ */
+bool dynFunction_hasReturn(dyn_function_type *dynFunction);
+
// Avpr parsing
dyn_function_type * dynFunction_parseAvprWithStr(const char * avpr, const char * fqn);
dyn_function_type * dynFunction_parseAvpr(FILE * avprStream, const char * fqn);
+
+
#endif
diff --git a/libs/dfi/include/dyn_type.h b/libs/dfi/include/dyn_type.h
index 500764b..1dff59e 100644
--- a/libs/dfi/include/dyn_type.h
+++ b/libs/dfi/include/dyn_type.h
@@ -89,7 +89,7 @@
* TypedPointer
* *(Type)
*
- * MetaInfo TODO
+ * MetaInfo
* #Name=Value;
*
*
diff --git a/libs/dfi/src/avrobin_serializer.c b/libs/dfi/src/avrobin_serializer.c
index 838a204..a7ed37c 100644
--- a/libs/dfi/src/avrobin_serializer.c
+++ b/libs/dfi/src/avrobin_serializer.c
@@ -380,6 +380,9 @@ static int avrobinSerializer_parseAny(dyn_type *type, void *loc, FILE *stream) {
status = avrobinSerializer_parseEnum(type, loc, stream);
}
break;
+ case 'l':
+ status = avrobinSerializer_parseAny(type->ref.ref, loc, stream);
+ break;
case 'P' :
status = ERROR;
LOG_WARNING("Untyped pointers are not supported for serialization.");
@@ -637,6 +640,9 @@ static int avrobinSerializer_writeAny(dyn_type *type, void *loc, FILE *stream) {
case 'E' :
status = avrobinSerializer_writeEnum(type, loc, stream);
break;
+ case 'l':
+ status = avrobinSerializer_writeAny(type->ref.ref, loc, stream);
+ break;
case 'P' :
status = ERROR;
LOG_WARNING("Untyped pointers are not supported for serialization.");
diff --git a/libs/dfi/src/dyn_function.c b/libs/dfi/src/dyn_function.c
index 802a8d4..56da893 100644
--- a/libs/dfi/src/dyn_function.c
+++ b/libs/dfi/src/dyn_function.c
@@ -23,6 +23,7 @@
#include <strings.h>
#include <stdlib.h>
#include <ffi.h>
+#include <dyn_type_common.h>
static const int OK = 0;
static const int MEM_ERROR = 1;
@@ -305,3 +306,7 @@ dyn_type * dynFunction_returnType(dyn_function_type *dynFunction) {
return dynFunction->funcReturn;
}
+bool dynFunction_hasReturn(dyn_function_type *dynFunction) {
+ dyn_type *t = dynFunction_returnType(dynFunction);
+ return t->descriptor != 'V';
+}
\ No newline at end of file
diff --git a/libs/dfi/src/dyn_type.c b/libs/dfi/src/dyn_type.c
index 89a1fa9..09cca39 100644
--- a/libs/dfi/src/dyn_type.c
+++ b/libs/dfi/src/dyn_type.c
@@ -571,27 +571,18 @@ static void dynType_clearTypedPointer(dyn_type *type) {
}
int dynType_alloc(dyn_type *type, void **bufLoc) {
- assert(type->type != DYN_TYPE_REF);
- assert(type->ffiType->size != 0);
int status = OK;
- void *inst = calloc(1, type->ffiType->size);
- if (inst != NULL) {
- if (type->type == DYN_TYPE_TYPED_POINTER) {
- void *ptr = NULL;
- dyn_type *sub = NULL;
- status = dynType_typedPointer_getTypedType(type, &sub);
- if (status == OK) {
- status = dynType_alloc(sub, &ptr);
- if (status == OK) {
- *(void **)inst = ptr;
- }
- }
- }
- *bufLoc = inst;
+ if (type->type == DYN_TYPE_REF) {
+ status = dynType_alloc(type->ref.ref, bufLoc);
} else {
- status = MEM_ERROR;
- LOG_ERROR("Error allocating memory for type '%c'", type->descriptor);
+ void *inst = calloc(1, type->ffiType->size);
+ if (inst != NULL) {
+ *bufLoc = inst;
+ } else {
+ status = MEM_ERROR;
+ LOG_ERROR("Error allocating memory for type '%c'", type->descriptor);
+ }
}
return status;
@@ -687,6 +678,9 @@ void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
dyn_type *subType = NULL;
char *text = NULL;
switch (type->type) {
+ case DYN_TYPE_REF:
+ dynType_deepFree(type->ref.ref, loc, alsoDeleteSelf);
+ break;
case DYN_TYPE_COMPLEX :
dynType_freeComplexType(type, loc);
break;
@@ -695,12 +689,19 @@ void dynType_deepFree(dyn_type *type, void *loc, bool alsoDeleteSelf) {
break;
case DYN_TYPE_TYPED_POINTER:
dynType_typedPointer_getTypedType(type, &subType);
- dynType_deepFree(subType, *(void **)loc, true);
+ void *ptrToType = *(void**)loc;
+ dynType_deepFree(subType, ptrToType, true);
break;
case DYN_TYPE_TEXT :
text = *(char **)loc;
free(text);
break;
+ case DYN_TYPE_SIMPLE:
+ //nop
+ break;
+ default:
+ LOG_ERROR("Unexpected switch case. cannot free dyn type %c\n", type->descriptor);
+ break;
}
if (alsoDeleteSelf) {
diff --git a/libs/dfi/src/json_rpc.c b/libs/dfi/src/json_rpc.c
index 6ff8367..7e62a7c 100644
--- a/libs/dfi/src/json_rpc.c
+++ b/libs/dfi/src/json_rpc.c
@@ -26,6 +26,7 @@
#include <stdint.h>
#include <string.h>
#include <ffi.h>
+#include <dyn_type_common.h>
static int OK = 0;
static int ERROR = 1;
@@ -106,14 +107,23 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
void *ptr = NULL;
void *ptrToPtr = &ptr;
- for (i = 0; i < nrOfArgs; i += 1) {
+ //setup and deserialize input
+ for (i = 0; i < nrOfArgs; ++i) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
value = json_array_get(arguments, index++);
- status = jsonSerializer_deserializeJson(argType, value, &(args[i]));
+ void *outPtr = NULL;
+ status = jsonSerializer_deserializeJson(argType, value, &outPtr);
+ args[i] = outPtr;
} else if (meta == DYN_FUNCTION_ARGUMENT_META__PRE_ALLOCATED_OUTPUT) {
- dynType_alloc(argType, &args[i]);
+ void **instPtr = calloc(1, sizeof(void*));
+ void *inst = NULL;
+ dyn_type *subType = NULL;
+ dynType_typedPointer_getTypedType(argType, &subType);
+ dynType_alloc(subType, &inst);
+ *instPtr = inst;
+ args[i] = instPtr;
} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
args[i] = &ptrToPtr;
} else if (meta == DYN_FUNCTION_ARGUMENT_META__HANDLE) {
@@ -145,15 +155,28 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
LOG_WARNING("Error calling remote endpoint function, got error code %i", funcCallStatus);
}
+ //free input args
json_t *jsonResult = NULL;
- for(i = 0; i < nrOfArgs; i += 1) {
+ for(i = 0; i < nrOfArgs; ++i) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
- enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
+ enum dyn_function_argument_meta meta = dynFunction_argumentMetaForIndex(func, i);
if (meta == DYN_FUNCTION_ARGUMENT_META__STD) {
- dynType_free(argType, args[i]);
+ if (dynType_descriptorType(argType) == 't') {
+ const char* isConst = dynType_getMetaInfo(argType, "const");
+ if (isConst != NULL && strncmp("true", isConst, 5) == 0) {
+ dynType_free(argType, args[i]);
+ } else {
+ //char* -> callee is now owner, no free for char seq needed
+ //will free the actual pointer
+ free(args[i]);
+ }
+ } else {
+ dynType_free(argType, args[i]);
+ }
}
}
+ //serialize and free output
if (funcCallStatus == 0 && status == OK) {
for (i = 0; i < nrOfArgs; i += 1) {
dyn_type *argType = dynFunction_argumentTypeForIndex(func, i);
@@ -162,7 +185,11 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
if (status == OK) {
status = jsonSerializer_serializeJson(argType, args[i], &jsonResult);
}
- dynType_free(argType, args[i]);
+ dyn_type *subType = NULL;
+ dynType_typedPointer_getTypedType(argType, &subType);
+ void **ptrToInst = (void**)args[i];
+ dynType_free(subType, *ptrToInst);
+ free(ptrToInst);
} else if (meta == DYN_FUNCTION_ARGUMENT_META__OUTPUT) {
if (ptr != NULL) {
dyn_type *typedType = NULL;
@@ -183,7 +210,7 @@ int jsonRpc_call(dyn_interface_type *intf, void *service, const char *request, c
}
if (status == OK) {
- dynType_free(typedTypedType, ptr);
+ dynType_free(typedTypedType, ptr);
}
}
@@ -247,6 +274,17 @@ int jsonRpc_prepareInvokeRequest(dyn_function_type *func, const char *id, void *
json_t *val = NULL;
int rc = jsonSerializer_serializeJson(type, args[i], &val);
+
+ if (dynType_descriptorType(type) == 't') {
+ const char *metaArgument = dynType_getMetaInfo(type, "const");
+ if (metaArgument != NULL && strncmp("true", metaArgument, 5) == 0) {
+ //const char * as input -> nop
+ } else {
+ char **str = args[i];
+ free(*str); //char * as input -> got ownership -> free it.
+ }
+ }
+
if (rc == 0) {
json_array_append_new(arguments, val);
} else {
@@ -279,14 +317,15 @@ int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]
}
json_t *result = NULL;
+ bool replyHasResult = false;
if (status == OK) {
- result = json_object_get(replyJson, "r"); //TODO check
- if (result == NULL) {
- status = ERROR;
- LOG_ERROR("Cannot find r entry in json reply '%s'", reply);
+ result = json_object_get(replyJson, "r");
+ if (result != NULL) {
+ replyHasResult = true;
}
}
+ bool replyHandled = false;
if (status == OK) {
int nrOfArgs = dynFunction_nrOfArguments(func);
int i;
@@ -299,19 +338,23 @@ int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]
size_t size = 0;
- if (dynType_descriptorType(argType) == 't') {
+ if (result == NULL) {
+ LOG_WARNING("Expected result in reply. got '%s'", reply);
+ } else if (dynType_descriptorType(argType) == 't') {
status = jsonSerializer_deserializeJson(argType, result, &tmp);
- if(tmp!=NULL){
+ if (tmp != NULL) {
size = strnlen(((char *) *(char**) tmp), 1024 * 1024);
memcpy(*out, *(void**) tmp, size);
}
+ replyHandled = true;
} else {
dynType_typedPointer_getTypedType(argType, &argType);
status = jsonSerializer_deserializeJson(argType, result, &tmp);
- if(tmp!=NULL){
+ if (tmp != NULL) {
size = dynType_size(argType);
memcpy(*out, tmp, size);
}
+ replyHandled = true;
}
dynType_free(argType, tmp);
@@ -320,14 +363,22 @@ int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]
dynType_typedPointer_getTypedType(argType, &subType);
- if (dynType_descriptorType(subType) == 't') {
- void ***out = (void ***) args[i];
- status = jsonSerializer_deserializeJson(subType, result, *out);
- } else {
+ if (result == NULL) {
+ LOG_WARNING("Expected result in reply. got '%s'", reply);
+ } else if (dynType_descriptorType(subType) == 't') {
+ char ***out = (char ***) args[i];
+ char **ptrToString = NULL;
+ status = jsonSerializer_deserializeJson(subType, result, (void**)&ptrToString);
+ char *s __attribute__((unused)) = *ptrToString; //note for debug
+ free(ptrToString);
+ **out = (void*)s;
+ replyHandled = true;
+ } else {
dyn_type *subSubType = NULL;
dynType_typedPointer_getTypedType(subType, &subSubType);
void ***out = (void ***) args[i];
status = jsonSerializer_deserializeJson(subSubType, result, *out);
+ replyHandled = true;
}
} else {
//skip
@@ -335,6 +386,10 @@ int jsonRpc_handleReply(dyn_function_type *func, const char *reply, void *args[]
}
}
+ if (replyHasResult && !replyHandled) {
+ LOG_WARNING("Reply has a result output, but this is not handled by the remote function!. Reply: '%s'", reply);
+ }
+
json_decref(replyJson);
return status;
diff --git a/libs/dfi/src/json_serializer.c b/libs/dfi/src/json_serializer.c
index b09635f..4af5523 100644
--- a/libs/dfi/src/json_serializer.c
+++ b/libs/dfi/src/json_serializer.c
@@ -77,7 +77,11 @@ static int jsonSerializer_createType(dyn_type *type, json_t *val, void **result)
if (dynType_descriptorType(type) == 't') {
if (json_typeof(val) == JSON_STRING) {
- inst = strdup(json_string_value(val));
+ //note a deserialized C string is a sequence of memory for the actual string and a
+ //pointer to that sequence. That pointer also needs to reside in the memory (heap).
+ const char *s = json_string_value(val);
+ inst = calloc(1, sizeof(char*));
+ *((char**)inst) = strdup(s);
} else {
status = ERROR;
LOG_ERROR("Expected json_string type got %i\n", json_typeof(val));
@@ -93,8 +97,8 @@ static int jsonSerializer_createType(dyn_type *type, json_t *val, void **result)
if (status == OK) {
*result = inst;
- }
- else{
+ } else {
+ *result = NULL;
dynType_free(type, inst);
}
@@ -262,6 +266,9 @@ static int jsonSerializer_parseAny(dyn_type *type, void *loc, json_t *val) {
status = ERROR;
LOG_WARNING("Untyped pointer are not supported for serialization");
break;
+ case 'l':
+ status = jsonSerializer_parseAny(type->ref.ref, loc, val);
+ break;
default :
status = ERROR;
LOG_ERROR("Error provided type '%c' not supported for JSON\n", dynType_descriptorType(type));
@@ -424,6 +431,9 @@ static int jsonSerializer_writeAny(dyn_type *type, void* input, json_t **out) {
case 'P' :
LOG_WARNING("Untyped pointer not supported for serialization. ignoring");
break;
+ case 'l':
+ status = jsonSerializer_writeAny(type->ref.ref, input, out);
+ break;
default :
LOG_ERROR("Unsupported descriptor '%c'", descriptor);
status = ERROR;
diff --git a/libs/dfi/test/dyn_avpr_function_tests.cpp b/libs/dfi/test/dyn_avpr_function_tests.cpp
index 6d8cb94..30fbf79 100644
--- a/libs/dfi/test/dyn_avpr_function_tests.cpp
+++ b/libs/dfi/test/dyn_avpr_function_tests.cpp
@@ -18,6 +18,7 @@
*/
#include <CppUTest/TestHarness.h>
+#include <celix_utils.h>
#include "CppUTest/CommandLineTestRunner.h"
extern "C" {
@@ -207,9 +208,16 @@ const char* theAvprFile = "{ \
\"structStringOutFunc\" : {\
\"request\" : [ ],\
\"response\" : \"StructString\" \
- } \
+ }, \
+ \"stringInFunc\" : {\
+ \"request\" : [{\
+ \"name\" : \"arg1\",\
+ \"type\" : \"string\" \
+ } ],\
+ \"response\" : \"Void\"\
+ }\
}\
- }";
+ }";
TEST_GROUP(DynAvprFunctionTests) {
void setup() override {
@@ -618,3 +626,35 @@ TEST(DynAvprFunctionTests, Example10) {
free(out.name);
dynFunction_destroy(dynFunc);
}
+
+#ifndef __APPLE__
+static int avpr_example11(void *handle __attribute__((unused)), char *arg1) {
+ STRCMP_EQUAL("input string test", arg1);
+ return 0;
+}
+
+//FIXME does not work in OSX. Also has issues in linux if input is not dynamically allocated.
+TEST(DynAvprFunctionTests, Example11) {
+ auto fp = (void(*)()) avpr_example11;
+ dyn_function_type * dynFunc = dynFunction_parseAvprWithStr(theAvprFile, "test.dt.stringInFunc");
+ CHECK(dynFunc != nullptr);
+
+ int handle = 0;
+ int* handle_ptr = &handle;
+
+ char *input = celix_utils_strdup("input string test");
+
+ void *args[2];
+ args[0] = &handle_ptr;
+ args[1]= &input;
+ int rVal = 1;
+
+ int rc = dynFunction_call(dynFunc, fp, &rVal, args);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(0, rVal);
+
+ free(input);
+
+ dynFunction_destroy(dynFunc);
+}
+#endif
diff --git a/libs/dfi/test/dyn_function_tests.cpp b/libs/dfi/test/dyn_function_tests.cpp
index b5efd15..3073a98 100644
--- a/libs/dfi/test/dyn_function_tests.cpp
+++ b/libs/dfi/test/dyn_function_tests.cpp
@@ -223,6 +223,34 @@ extern "C" {
dynFunction_destroy(dynFunc);
}
+ #define EXAMPLE5_DESCRIPTOR "example(#const=true;tt)V"
+
+ static void example5Func(const char *s1, char *s2) {
+ STRCMP_EQUAL("s1", s1);
+ STRCMP_EQUAL("s2", s2);
+ }
+
+ static void test_example5(void) {
+ dyn_function_type *dynFunc = NULL;
+ void (*fp)(void) = (void(*)(void)) example5Func;
+ int rc;
+
+ rc = dynFunction_parseWithStr(EXAMPLE5_DESCRIPTOR, NULL, &dynFunc);
+ CHECK_EQUAL(0, rc);
+
+ const char *a1 = "s1";
+ char *a2 = strdup("s2");
+ void *args[2];
+ args[0] = &a1;
+ args[1] = &a2;
+
+ rc = dynFunction_call(dynFunc, fp, NULL, args);
+ CHECK_EQUAL(0, rc);
+
+ dynFunction_destroy(dynFunc);
+ }
+
+
#define INVALID_FUNC_DESCRIPTOR "example$[D)V"//$ is an invalid symbol, missing (
static void test_invalidDynFunc(void) {
@@ -269,6 +297,10 @@ TEST(DynFunctionTests, DynFuncTest4) {
test_example4();
}
+TEST(DynFunctionTests, DynFuncTest5) {
+ test_example5();
+}
+
TEST(DynFunctionTests, InvalidDynFuncTest) {
test_invalidDynFunc();
test_invalidDynFuncType();
diff --git a/libs/etcdlib/api/etcd.h b/libs/etcdlib/api/etcd.h
index e75e103..69456af 100644
--- a/libs/etcdlib/api/etcd.h
+++ b/libs/etcdlib/api/etcd.h
@@ -27,6 +27,12 @@ extern "C"
#include "etcdlib.h"
+#ifdef CELIX_ADD_DEPRECATED_ATTRIBUTES
+#define DEP_ATTRIBUTE __attribute__((deprecated("etcd_ call are placed by etcdlib_ calls, use etcdlib.h instead of etcd.h")))
+#else
+#define DEP_ATTRIBUTE
+#endif
+
/**
* @desc Initialize the ETCD-LIB with the server/port where Etcd can be reached.
* @param const char* server. String containing the IP-number of the server.
@@ -34,8 +40,7 @@ extern "C"
* @param int flags. bitwise flags to control etcdlib initialization.
* @return 0 on success, non zero otherwise.
*/
-//__attribute__((deprecated("use etcdlib_create instead")))
-int etcd_init(const char* server, int port, int flags);
+int etcd_init(const char* server, int port, int flags) DEP_ATTRIBUTE;
/**
* @desc Retrieve a single value from Etcd.
@@ -44,8 +49,7 @@ int etcd_init(const char* server, int port, int flags);
* @param int* modifiedIndex. If not NULL the Etcd-index of the last modified value.
* @return 0 on success, non zero otherwise
*/
-//__attribute__((deprecated("use etcdlib_get instead")))
-int etcd_get(const char* key, char** value, int* modifiedIndex);
+int etcd_get(const char* key, char** value, int* modifiedIndex) DEP_ATTRIBUTE;
/**
* @desc Retrieve the contents of a directory. For every found key/value pair the given callback function is called.
@@ -55,8 +59,7 @@ int etcd_get(const char* key, char** value, int* modifiedIndex);
* @param int* modifiedIndex. If not NULL the Etcd-index of the last modified value.
* @return 0 on success, non zero otherwise
*/
-//__attribute__((deprecated("use etcdlib_get_directory instead")))
-int etcd_get_directory(const char* directory, etcdlib_key_value_callback callback, void *arg, long long* modifiedIndex);
+int etcd_get_directory(const char* directory, etcdlib_key_value_callback callback, void *arg, long long* modifiedIndex) DEP_ATTRIBUTE;
/**
* @desc Setting an Etcd-key/value
@@ -66,8 +69,7 @@ int etcd_get_directory(const char* directory, etcdlib_key_value_callback callbac
* @param bool prevExist. If true the value is only set when the key already exists, if false it is always set
* @return 0 on success, non zero otherwise
*/
-//__attribute__((deprecated("use etcdlib_set instead")))
-int etcd_set(const char* key, const char* value, int ttl, bool prevExist);
+int etcd_set(const char* key, const char* value, int ttl, bool prevExist) DEP_ATTRIBUTE;
/**
* @desc Refresh the ttl of an existing key.
@@ -75,8 +77,7 @@ int etcd_set(const char* key, const char* value, int ttl, bool prevExist);
* @param ttl the ttl value to use.
* @return 0 on success, non zero otherwise.
*/
-//__attribute__((deprecated("use etcdlib_refesh instead")))
-int etcd_refresh(const char *key, int ttl);
+int etcd_refresh(const char *key, int ttl) DEP_ATTRIBUTE;
/**
* @desc Setting an Etcd-key/value and checks if there is a different previous value
@@ -86,16 +87,14 @@ int etcd_refresh(const char *key, int ttl);
* @param bool always_write. If true the value is written, if false only when the given value is equal to the value in etcd.
* @return 0 on success, non zero otherwise
*/
-//__attribute__((deprecated("use etcdlib_set_with_check instead")))
-int etcd_set_with_check(const char* key, const char* value, int ttl, bool always_write);
+int etcd_set_with_check(const char* key, const char* value, int ttl, bool always_write) DEP_ATTRIBUTE;
/**
* @desc Deleting an Etcd-key
* @param const char* key. The Etcd-key (Note: a leading '/' should be avoided)
* @return 0 on success, non zero otherwise
*/
-//__attribute__((deprecated("use etcdlib_del instead")))
-int etcd_del(const char* key);
+int etcd_del(const char* key) DEP_ATTRIBUTE;
/**
* @desc Watching an etcd directory for changes
@@ -108,8 +107,7 @@ int etcd_del(const char* key);
* @param long long* modifiedIndex. If not NULL, the index of the modification is written.
* @return ETCDLIB_RC_OK (0) on success, non zero otherwise. Note that a timeout is signified by a ETCDLIB_RC_TIMEOUT return code.
*/
-//__attribute__((deprecated("use etcdlib_watch instead")))
-int etcd_watch(const char* key, long long index, char** action, char** prevValue, char** value, char** rkey, long long* modifiedIndex);
+int etcd_watch(const char* key, long long index, char** action, char** prevValue, char** value, char** rkey, long long* modifiedIndex) DEP_ATTRIBUTE;
#ifdef __cplusplus
}
diff --git a/libs/framework/src/celix_framework_factory.c b/libs/framework/src/celix_framework_factory.c
index ce004e5..098f80e 100644
--- a/libs/framework/src/celix_framework_factory.c
+++ b/libs/framework/src/celix_framework_factory.c
@@ -19,7 +19,7 @@
#include "celix_framework_factory.h"
-framework_t* celix_frameworkFactory_createFramework(properties_t *config) {
+framework_t* celix_frameworkFactory_createFramework(celix_properties_t *config) {
framework_t* fw = NULL;
if (config == NULL) {