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 ec3b1c0 Updates the HTTP Admin config properties and adds resource
urls info to the http_admin_info service.
ec3b1c0 is described below
commit ec3b1c0dce112711519d582743bd1ed2b7b109f2
Author: Pepijn Noltes <[email protected]>
AuthorDate: Thu Aug 15 22:20:10 2019 +0200
Updates the HTTP Admin config properties and adds resource urls info to the
http_admin_info service.
The HTTP Admin properties did not contain any prefixes.
This is the case for many bundle config properties, but for config property
we try to have an explicit prefix.
For HTTP Admin this is now CELIX_HTTP_ADMIN.
Also adds support for configured the num of threads used in civetweb (now
default 4).
---
bundles/http_admin/README.md | 11 +-
bundles/http_admin/http_admin/src/activator.c | 242 ++++-----------------
bundles/http_admin/http_admin/src/http_admin.c | 225 +++++++++++++++++--
bundles/http_admin/http_admin/src/http_admin.h | 7 +-
.../http_admin/src/http_admin_constants.h | 43 ++++
.../include/http_admin/http_admin_info_service.h | 12 +-
bundles/http_admin/test/CMakeLists.txt | 2 +-
bundles/http_admin/test/config.properties.in | 4 +-
.../http_admin/test/test/http_admin_info_tests.cc | 66 ++++++
.../http_admin/test/test/http_websocket_tests.cc | 14 +-
bundles/http_admin/test/test/test_runner.cc | 8 +-
libs/framework/include/celix_bundle_context.h | 8 +
libs/framework/include/service_tracker.h | 4 +
libs/framework/src/bundle_context.c | 2 +-
libs/framework/src/service_tracker.c | 37 +++-
.../framework/tst/bundle_context_bundles_tests.cpp | 12 +-
.../framework/tst/bundle_context_services_test.cpp | 136 +++++++-----
libs/framework/tst/multiple_frameworks_test.cpp | 22 +-
libs/framework/tst/single_framework_test.cpp | 22 +-
19 files changed, 561 insertions(+), 316 deletions(-)
diff --git a/bundles/http_admin/README.md b/bundles/http_admin/README.md
index 3e1b71e..c564372 100644
--- a/bundles/http_admin/README.md
+++ b/bundles/http_admin/README.md
@@ -40,11 +40,12 @@ celix_bundle_add_dir(<TARGET> <Document root of bundle>
DESTINATION ".")
```
### Celix supported config.properties
- LISTENING_PORTS default = 8080, can be multiple ports
divided by a comma
- PORT_RANGE_MIN default = 8000
- PORT_RANGE_MAX default = 9000
- USE_WEBSOCKETS default = false
- WEBSOCKET_TIMEOUT_MS default = 3600000
+ CELIX_TTP_ADMIN_LISTENING_PORTS default = 8080, can be
multiple ports divided by a comma
+ CELIX_HTTP_ADMIN_PORT_RANGE_MIN default = 8000
+ CELIX_HTTP_ADMIN_PORT_RANGE_MAX default = 9000
+ CELIX_HTTP_ADMIN_USE_WEBSOCKETS default = true
+ CELIX_HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS default = 3600000
+ CELIX_HTTP_ADMIN_NUM_THREADS default = 1
## CMake option
BUILD_HTTP_ADMIN=ON
diff --git a/bundles/http_admin/http_admin/src/activator.c
b/bundles/http_admin/http_admin/src/activator.c
index f3d1594..ecdbbe0 100644
--- a/bundles/http_admin/http_admin/src/activator.c
+++ b/bundles/http_admin/http_admin/src/activator.c
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <memory.h>
-#include <unistd.h>
#include "celix_api.h"
#include "celix_types.h"
@@ -35,6 +34,7 @@
#include "websocket_admin.h"
#include "http_admin/api.h"
+#include "http_admin_constants.h"
#include "civetweb.h"
@@ -45,223 +45,82 @@ typedef struct http_admin_activator {
long httpAdminSvcId;
long sockAdminSvcId;
- celix_array_list_t *aliasList; //Array list of http_alias_t
bool useWebsockets;
- char *root;
long bundleTrackerId;
} http_admin_activator_t;
-typedef struct http_alias {
- char *alias_path;
- long bundle_id;
-} http_alias_t;
-
-//Local function prototypes
-void createAliasesSymlink(const char *aliases, const char *admin_root, const
char *bundle_root, long bundle_id, celix_array_list_t *alias_list);
-bool aliasList_containsAlias(celix_array_list_t *alias_list, const char
*alias);
-
-static void http_admin_startBundle(void *data, const celix_bundle_t *bundle);
-static void http_admin_stopBundle(void *data, const celix_bundle_t *bundle);
-
-/**
- * Decode aliases from the given alias string and make a symbolic link for
proper resource behavior.
- * Save the created aliases as pair with the corresponding bundle id in the
given hash map.
- *
- * @param aliases String which contains the aliases to
append to the alias map
- * @param admin_root Root path of bundle where the admin runs
- * @param bundle_root Bundle path of bundle where the
resources remain
- * @param bundle_id Bundle ID to connect aliases to this
bundle
- * @param alias_map Pointer to the alias map to which the
created symlink is saved with the bundle id as key
- */
-void createAliasesSymlink(const char *aliases, const char *admin_root, const
char *bundle_root, long bundle_id, celix_array_list_t *alias_list) {
- char *token = NULL;
- char *sub_token = NULL;
- char *save_ptr = NULL;
- char *sub_save_ptr = NULL;
- char *alias_cpy;
-
- if(aliases != NULL && alias_list != NULL && admin_root != NULL &&
bundle_root != NULL) {
- token = alias_cpy = strdup(aliases);
- token = strtok_r(token, ",", &save_ptr);
-
- while(token != NULL) {
- int i;
- char *alias_path;
- char *bnd_resource_path;
- char cwdBuf[1024] = {0};
- char *cwd = getcwd(cwdBuf, sizeof(cwdBuf));
-
- while(isspace(*token)) token++; //skip spaces at beginning
- for (i = (int)(strlen(token) - 1); (isspace(token[i])); i--);
//skip spaces at end
- token[i+1] = '\0';
-
- sub_token = strtok_r(token, ";", &sub_save_ptr);
- if(sub_token == NULL) {
- token = strtok_r(NULL, ",", &save_ptr);
- continue; //Invalid alias to path, continue to next entry
- }
-
- asprintf(&alias_path, "%s/%s%s", cwd, admin_root, sub_token);
- if(aliasList_containsAlias(alias_list, alias_path)) {
- free(alias_path);
- continue; //Alias already existing, Continue to next entry
- }
-
- sub_token = strtok_r(NULL, ";", &sub_save_ptr);
- if(sub_token == NULL) {
- free(alias_path);
- token = strtok_r(NULL, ",", &save_ptr);
- continue; //Invalid alias to path, continue to next entry
- }
-
- asprintf(&bnd_resource_path, "%s/%s/%s", cwd, bundle_root,
sub_token);
-
- if(symlink(bnd_resource_path, alias_path) == 0) {
- http_alias_t *alias = calloc(1, sizeof(*alias));
- alias->alias_path = alias_path;
- alias->bundle_id = bundle_id;
- celix_arrayList_add(alias_list, alias);
- } else {
- free(alias_path);
- }
-
- free(bnd_resource_path);
- token = strtok_r(NULL, ",", &save_ptr);
- }
- free(alias_cpy);
- }
-}
-
-/**
- * Check if the given alias is already part of the given alias list
- *
- * @param alias_list The list to search for aliases
- * @param alias The alias to search for
- * @return true if alias is already in the list, false if not.
- */
-bool aliasList_containsAlias(celix_array_list_t *alias_list, const char
*alias) {
- unsigned int size = arrayList_size(alias_list);
- for(unsigned int i = 0; i < size; i++) {
- http_alias_t *http_alias = arrayList_get(alias_list, i);
- if(strcmp(http_alias->alias_path, alias) == 0) {
- return true;
- }
- }
-
- return false;
-}
-
-static void http_admin_startBundle(void *data, const celix_bundle_t *bundle) {
- bundle_archive_pt archive = NULL;
- bundle_revision_pt revision = NULL;
- manifest_pt manifest = NULL;
-
- http_admin_activator_t *act = data;
-
- // Retrieve manifest from current bundle revision (retrieve revision from
bundle archive) to check for
- // Amdatu pattern manifest property X-Web-Resource. This property is used
for aliases.
- celix_status_t status = bundle_getArchive((celix_bundle_t*)bundle,
&archive);
- if(status == CELIX_SUCCESS && archive != NULL) {
- status = bundleArchive_getCurrentRevision(archive, &revision);
- }
-
- if(status == CELIX_SUCCESS && revision != NULL) {
- status = bundleRevision_getManifest(revision, &manifest);
- }
-
- if(status == CELIX_SUCCESS && manifest != NULL) {
- const char *aliases = NULL;
- const char *revision_root = NULL;
- long bnd_id;
-
- aliases = manifest_getValue(manifest, "X-Web-Resource");
- bnd_id = celix_bundle_getId(bundle);
- bundleRevision_getRoot(revision, &revision_root);
- createAliasesSymlink(aliases, act->root, revision_root, bnd_id,
act->aliasList);
- }
-}
-
-static void http_admin_stopBundle(void *data, const celix_bundle_t *bundle) {
- http_admin_activator_t *act = data;
- long bundle_id = celix_bundle_getId(bundle);
-
- //Remove all aliases which are connected to this bundle
- unsigned int size = arrayList_size(act->aliasList);
- for (unsigned int i = (size - 1); i < size; i--) {
- http_alias_t *alias = arrayList_get(act->aliasList, i);
- if(alias->bundle_id == bundle_id) {
- remove(alias->alias_path); //Delete alias in cache directory
- free(alias->alias_path);
- free(alias);
- celix_arrayList_removeAt(act->aliasList, i);
- }
- }
-}
-
static int http_admin_start(http_admin_activator_t *act,
celix_bundle_context_t *ctx) {
celix_bundle_t *bundle = celix_bundleContext_getBundle(ctx);
- act->root = celix_bundle_getEntry(bundle, "root");
- act->aliasList = celix_arrayList_create();
+ char* root = celix_bundle_getEntry(bundle, "root");
- {
- celix_bundle_tracking_options_t opts =
CELIX_EMPTY_BUNDLE_TRACKING_OPTIONS;
- opts.callbackHandle = act;
- opts.onStarted = http_admin_startBundle;
- opts.onStopped = http_admin_stopBundle;
- act->bundleTrackerId =
celix_bundleContext_trackBundlesWithOptions(ctx, &opts);
- }
- const char *prop_doc_root = act->root;
- bool prop_use_websockets = celix_bundleContext_getPropertyAsBool(ctx,
"USE_WEBSOCKETS", true);
- const char *prop_port = celix_bundleContext_getProperty(ctx,
"LISTENING_PORTS", "8080");
- const char *prop_timeout = celix_bundleContext_getProperty(ctx,
"WEBSOCKET_TIMEOUT_MS", "3600000");
- long prop_port_min = celix_bundleContext_getPropertyAsLong(ctx,
"PORT_RANGE_MIN", 8000);
- long prop_port_max = celix_bundleContext_getPropertyAsLong(ctx,
"PORT_RANGE_MAX", 9000);
+ bool prop_use_websockets = celix_bundleContext_getPropertyAsBool(ctx,
HTTP_ADMIN_USE_WEBSOCKETS_KEY, HTTP_ADMIN_USE_WEBSOCKETS_DFT);
+ long listPort = celix_bundleContext_getPropertyAsLong(ctx,
HTTP_ADMIN_LISTENING_PORTS_KEY, HTTP_ADMIN_LISTENING_PORTS_DFT);
+ long websocketTimeoutMs = celix_bundleContext_getPropertyAsLong(ctx,
HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS_KEY, HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS_DFT);
+ long prop_port_min = celix_bundleContext_getPropertyAsLong(ctx,
HTTP_ADMIN_PORT_RANGE_MIN_KEY, HTTP_ADMIN_PORT_RANGE_MIN_DFT);
+ long prop_port_max = celix_bundleContext_getPropertyAsLong(ctx,
HTTP_ADMIN_PORT_RANGE_MAX_KEY, HTTP_ADMIN_PORT_RANGE_MAX_DFT);
+ long num_threads = celix_bundleContext_getPropertyAsLong(ctx,
HTTP_ADMIN_NUM_THREADS_KEY, HTTP_ADMIN_NUM_THREADS_DFT);
+
+ char prop_port[64];
+ snprintf(prop_port, 64, "%li", listPort);
+ char prop_timeout[64];
+ snprintf(prop_timeout, 64, "%li", websocketTimeoutMs);
+ char prop_num_threads[64];
+ snprintf(prop_num_threads, 64, "%li", num_threads);
+
act->useWebsockets = prop_use_websockets;
const char *svr_opts[] = {
- "document_root", prop_doc_root,
+ "document_root", root,
"listening_ports", prop_port,
"websocket_timeout_ms", prop_timeout,
- "websocket_root", prop_doc_root,
+ "websocket_root", root,
+ "num_threads", prop_num_threads,
NULL
};
//Try the 'LISTENING_PORT' property first, if failing continue with the
port range functionality
- act->httpManager = httpAdmin_create(ctx, svr_opts);
+ act->httpManager = httpAdmin_create(ctx, root, svr_opts);
for(long port = prop_port_min; act->httpManager == NULL && port <=
prop_port_max; port++) {
char *port_str;
asprintf(&port_str, "%li", port);
svr_opts[3] = port_str;
- act->httpManager = httpAdmin_create(ctx, svr_opts);
+ act->httpManager = httpAdmin_create(ctx, root, svr_opts);
free(port_str);
}
if (act->httpManager != NULL) {
- celix_service_tracking_options_t opts =
CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
- opts.callbackHandle = act->httpManager;
- opts.addWithProperties = http_admin_addHttpService;
- opts.removeWithProperties = http_admin_removeHttpService;
- opts.filter.serviceName = HTTP_ADMIN_SERVICE_NAME;
- act->httpAdminSvcId =
celix_bundleContext_trackServicesWithOptions(ctx, &opts);
-
- //Retrieve some data from the http admin and reuse it for the
websocket admin
- struct mg_context *svr_ctx =
httpAdmin_getServerContext(act->httpManager);
+ {
+ celix_service_tracking_options_t opts =
CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.callbackHandle = act->httpManager;
+ opts.addWithProperties = http_admin_addHttpService;
+ opts.removeWithProperties = http_admin_removeHttpService;
+ opts.filter.serviceName = HTTP_ADMIN_SERVICE_NAME;
+ act->httpAdminSvcId =
celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+ }
+ {
+ celix_bundle_tracking_options_t opts =
CELIX_EMPTY_BUNDLE_TRACKING_OPTIONS;
+ opts.callbackHandle = act->httpManager;
+ opts.onStarted = http_admin_startBundle;
+ opts.onStopped = http_admin_stopBundle;
+ act->bundleTrackerId =
celix_bundleContext_trackBundlesWithOptions(ctx, &opts);
+ }
//Websockets are dependent from the http admin, which starts the
server.
if(act->useWebsockets) {
+ //Retrieve some data from the http admin and reuse it for the
websocket admin
+ struct mg_context *svr_ctx =
httpAdmin_getServerContext(act->httpManager);
act->sockManager = websocketAdmin_create(ctx, svr_ctx);
-
if (act->sockManager != NULL) {
- celix_service_tracking_options_t opts2 =
CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
- opts2.callbackHandle = act->sockManager;
- opts2.addWithProperties = websocket_admin_addWebsocketService;
- opts2.removeWithProperties =
websocket_admin_removeWebsocketService;
- opts2.filter.serviceName = WEBSOCKET_ADMIN_SERVICE_NAME;
- act->sockAdminSvcId =
celix_bundleContext_trackServicesWithOptions(ctx, &opts2);
+ celix_service_tracking_options_t opts =
CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+ opts.callbackHandle = act->sockManager;
+ opts.addWithProperties = websocket_admin_addWebsocketService;
+ opts.removeWithProperties =
websocket_admin_removeWebsocketService;
+ opts.filter.serviceName = WEBSOCKET_ADMIN_SERVICE_NAME;
+ act->sockAdminSvcId =
celix_bundleContext_trackServicesWithOptions(ctx, &opts);
}
}
}
@@ -280,19 +139,6 @@ static int http_admin_stop(http_admin_activator_t *act,
celix_bundle_context_t *
act->useWebsockets = false;
}
- //Destroy alias map by removing symbolic links first.
- unsigned int size = arrayList_size(act->aliasList);
- for (unsigned int i = (size - 1); i < size; i--) {
- http_alias_t *alias = arrayList_get(act->aliasList, i);
- remove(alias->alias_path); //Delete alias in cache directory
- free(alias->alias_path);
- free(alias);
- celix_arrayList_removeAt(act->aliasList, i);
- }
- arrayList_destroy(act->aliasList);
-
- free(act->root);
-
return CELIX_SUCCESS;
}
diff --git a/bundles/http_admin/http_admin/src/http_admin.c
b/bundles/http_admin/http_admin/src/http_admin.c
index eead4da..79e20b9 100644
--- a/bundles/http_admin/http_admin/src/http_admin.c
+++ b/bundles/http_admin/http_admin/src/http_admin.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <memory.h>
#include <limits.h>
+#include <unistd.h>
#include "http_admin.h"
#include "http_admin/api.h"
@@ -39,33 +40,45 @@
struct http_admin_manager {
- bundle_context_pt context;
-
+ celix_bundle_context_t *context;
struct mg_context *mgCtx;
+ char *root;
+
+ celix_thread_mutex_t admin_lock; //protects below
celix_http_info_service_t infoSvc;
long infoSvcId;
-
+ celix_array_list_t *aliasList; //Array list of http_alias_t
service_tree_t http_svc_tree;
- celix_thread_mutex_t admin_lock;
};
+
+typedef struct http_alias {
+ char *url;
+ char *alias_path;
+ long bundle_id;
+} http_alias_t;
+
+
//Local function prototypes
-int http_request_handle(struct mg_connection *connection);
+static int http_request_handle(struct mg_connection *connection);
+static void httpAdmin_updateInfoSvc(http_admin_manager_t *admin);
+static void createAliasesSymlink(const char *aliases, const char *admin_root,
const char *bundle_root, long bundle_id, celix_array_list_t *alias_list);
+static bool aliasList_containsAlias(celix_array_list_t *alias_list, const char
*alias);
-http_admin_manager_t *httpAdmin_create(bundle_context_pt context, const char
**svr_opts) {
+http_admin_manager_t *httpAdmin_create(celix_bundle_context_t *context, char
*root, const char **svr_opts) {
celix_status_t status;
struct mg_callbacks callbacks;
http_admin_manager_t *admin = (http_admin_manager_t *) calloc(1,
sizeof(http_admin_manager_t));
- if (admin == NULL) {
- return NULL;
- }
-
admin->context = context;
+ admin->root = root;
+ admin->infoSvcId = -1L;
+
status = celixThreadMutex_create(&admin->admin_lock, NULL);
+ admin->aliasList = celix_arrayList_create();
if (status == CELIX_SUCCESS) {
//Use only begin_request callback
@@ -79,11 +92,8 @@ http_admin_manager_t *httpAdmin_create(bundle_context_pt
context, const char **s
if (status == CELIX_SUCCESS) {
//When webserver started successful, set port info in HTTP admin
service
const char *ports = mg_get_option(admin->mgCtx, "listening_ports");
- celix_properties_t *properties = celix_properties_create();
- celix_properties_set(properties, HTTP_ADMIN_INFO_PORT, ports);
- admin->infoSvcId = celix_bundleContext_registerService(context,
&admin->infoSvc,
-
HTTP_ADMIN_INFO_SERVICE_NAME, properties);
- fprintf(stdout, "Started HTTP webserver at port %s\n", ports);
+ httpAdmin_updateInfoSvc(admin);
+ fprintf(stdout, "HTTP Admin started at port %s\n", ports);
}
if (status != CELIX_SUCCESS) {
@@ -109,9 +119,22 @@ void httpAdmin_destroy(http_admin_manager_t *admin) {
destroyServiceTree(&admin->http_svc_tree);
+ //Destroy alias map by removing symbolic links first.
+ unsigned int size = arrayList_size(admin->aliasList);
+ for (unsigned int i = (size - 1); i < size; i--) {
+ http_alias_t *alias = arrayList_get(admin->aliasList, i);
+ remove(alias->alias_path); //Delete alias in cache directory
+ free(alias->url);
+ free(alias->alias_path);
+ free(alias);
+ celix_arrayList_removeAt(admin->aliasList, i);
+ }
+ arrayList_destroy(admin->aliasList);
+
celixThreadMutex_unlock(&(admin->admin_lock));
celixThreadMutex_destroy(&(admin->admin_lock));
+ free(admin->root);
free(admin);
}
@@ -325,3 +348,175 @@ int http_request_handle(struct mg_connection *connection)
{
return ret_status;
}
+
+static void httpAdmin_updateInfoSvc(http_admin_manager_t *admin) {
+ const char *ports = mg_get_option(admin->mgCtx, "listening_ports");
+
+ char *resources_urls = NULL;
+ size_t resources_urls_size;
+ FILE *stream = open_memstream(&resources_urls, &resources_urls_size);
+ fprintf(stream , "");
+
+ unsigned int size = arrayList_size(admin->aliasList);
+ for (unsigned int i = 0; i < size; ++i) {
+ http_alias_t *alias = arrayList_get(admin->aliasList, i);
+ bool isLast = (i == size-1);
+ const char *separator = isLast ? "" : ",";
+ fprintf(stream, "%s%s", alias->url, separator);
+ }
+ fclose(stream);
+
+ celixThreadMutex_lock(&admin->admin_lock);
+ celix_bundleContext_unregisterService(admin->context, admin->infoSvcId);
+
+ celix_properties_t *properties = celix_properties_create();
+ celix_properties_set(properties, HTTP_ADMIN_INFO_PORT, ports);
+ if (strncmp("", resources_urls, 1) != 0) {
+ celix_properties_set(properties, HTTP_ADMIN_INFO_RESOURCE_URLS,
resources_urls);
+ }
+ admin->infoSvcId = celix_bundleContext_registerService(admin->context,
&admin->infoSvc, HTTP_ADMIN_INFO_SERVICE_NAME, properties);
+
+ celixThreadMutex_unlock(&admin->admin_lock);
+
+ free(resources_urls);
+}
+
+
+/**
+ * Decode aliases from the given alias string and make a symbolic link for
proper resource behavior.
+ * Save the created aliases as pair with the corresponding bundle id in the
given hash map.
+ *
+ * @param aliases String which contains the aliases to
append to the alias map
+ * @param admin_root Root path of bundle where the admin runs
+ * @param bundle_root Bundle path of bundle where the
resources remain
+ * @param bundle_id Bundle ID to connect aliases to this
bundle
+ * @param alias_map Pointer to the alias map to which the
created symlink is saved with the bundle id as key
+ */
+static void createAliasesSymlink(const char *aliases, const char *admin_root,
const char *bundle_root, long bundle_id, celix_array_list_t *alias_list) {
+ char *token = NULL;
+ char *sub_token = NULL;
+ char *save_ptr = NULL;
+ char *sub_save_ptr = NULL;
+ char *alias_cpy;
+
+ if(aliases != NULL && alias_list != NULL && admin_root != NULL &&
bundle_root != NULL) {
+ token = alias_cpy = strdup(aliases);
+ token = strtok_r(token, ",", &save_ptr);
+
+ while(token != NULL) {
+ int i;
+ char *alias_path;
+ char *bnd_resource_path;
+ char cwdBuf[1024] = {0};
+ char *cwd = getcwd(cwdBuf, sizeof(cwdBuf));
+
+ while(isspace(*token)) token++; //skip spaces at beginning
+ for (i = (int)(strlen(token) - 1); (isspace(token[i])); i--);
//skip spaces at end
+ token[i+1] = '\0';
+
+ sub_token = strtok_r(token, ";", &sub_save_ptr);
+ if(sub_token == NULL) {
+ token = strtok_r(NULL, ",", &save_ptr);
+ continue; //Invalid alias to path, continue to next entry
+ }
+
+ asprintf(&alias_path, "%s/%s%s", cwd, admin_root, sub_token);
+ if(aliasList_containsAlias(alias_list, alias_path)) {
+ free(alias_path);
+ continue; //Alias already existing, Continue to next entry
+ }
+
+ sub_token = strtok_r(NULL, ";", &sub_save_ptr);
+ if(sub_token == NULL) {
+ free(alias_path);
+ token = strtok_r(NULL, ",", &save_ptr);
+ continue; //Invalid alias to path, continue to next entry
+ }
+
+ asprintf(&bnd_resource_path, "%s/%s/%s", cwd, bundle_root,
sub_token);
+
+ if(symlink(bnd_resource_path, alias_path) == 0) {
+ http_alias_t *alias = calloc(1, sizeof(*alias));
+ alias->url = strndup(token, 1024 * 1024 * 10);
+ alias->alias_path = alias_path;
+ alias->bundle_id = bundle_id;
+ celix_arrayList_add(alias_list, alias);
+ } else {
+ free(alias_path);
+ }
+
+ free(bnd_resource_path);
+ token = strtok_r(NULL, ",", &save_ptr);
+ }
+ free(alias_cpy);
+ }
+}
+
+/**
+ * Check if the given alias is already part of the given alias list
+ *
+ * @param alias_list The list to search for aliases
+ * @param alias The alias to search for
+ * @return true if alias is already in the list, false if not.
+ */
+static bool aliasList_containsAlias(celix_array_list_t *alias_list, const char
*alias) {
+ unsigned int size = arrayList_size(alias_list);
+ for(unsigned int i = 0; i < size; i++) {
+ http_alias_t *http_alias = arrayList_get(alias_list, i);
+ if(strcmp(http_alias->alias_path, alias) == 0) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void http_admin_startBundle(void *data, const celix_bundle_t *bundle) {
+ bundle_archive_pt archive = NULL;
+ bundle_revision_pt revision = NULL;
+ manifest_pt manifest = NULL;
+
+ http_admin_manager_t *admin = data;
+
+ // Retrieve manifest from current bundle revision (retrieve revision from
bundle archive) to check for
+ // Amdatu pattern manifest property X-Web-Resource. This property is used
for aliases.
+ celix_status_t status = bundle_getArchive((celix_bundle_t*)bundle,
&archive);
+ if(status == CELIX_SUCCESS && archive != NULL) {
+ status = bundleArchive_getCurrentRevision(archive, &revision);
+ }
+
+ if(status == CELIX_SUCCESS && revision != NULL) {
+ status = bundleRevision_getManifest(revision, &manifest);
+ }
+
+ if(status == CELIX_SUCCESS && manifest != NULL) {
+ const char *aliases = NULL;
+ const char *revision_root = NULL;
+ long bnd_id;
+
+ aliases = manifest_getValue(manifest, "X-Web-Resource");
+ bnd_id = celix_bundle_getId(bundle);
+ bundleRevision_getRoot(revision, &revision_root);
+ createAliasesSymlink(aliases, admin->root, revision_root, bnd_id,
admin->aliasList);
+ }
+ httpAdmin_updateInfoSvc(admin);
+}
+
+void http_admin_stopBundle(void *data, const celix_bundle_t *bundle) {
+ http_admin_manager_t *admin = data;
+ long bundle_id = celix_bundle_getId(bundle);
+
+ //Remove all aliases which are connected to this bundle
+ unsigned int size = arrayList_size(admin->aliasList);
+ for (unsigned int i = (size - 1); i < size; i--) {
+ http_alias_t *alias = arrayList_get(admin->aliasList, i);
+ if(alias->bundle_id == bundle_id) {
+ remove(alias->alias_path); //Delete alias in cache directory
+ free(alias->alias_path);
+ free(alias);
+ celix_arrayList_removeAt(admin->aliasList, i);
+ }
+ }
+ httpAdmin_updateInfoSvc(admin);
+}
+
diff --git a/bundles/http_admin/http_admin/src/http_admin.h
b/bundles/http_admin/http_admin/src/http_admin.h
index 66b70e9..3d282a0 100644
--- a/bundles/http_admin/http_admin/src/http_admin.h
+++ b/bundles/http_admin/http_admin/src/http_admin.h
@@ -27,13 +27,13 @@
#ifndef CELIX_HTTP_ADMIN_H
#define CELIX_HTTP_ADMIN_H
-#include "bundle_context.h"
+#include "celix_bundle_context.h"
#include "civetweb.h"
typedef struct http_admin_manager http_admin_manager_t;
-http_admin_manager_t *httpAdmin_create(bundle_context_pt context, const char
**svr_opts);
+http_admin_manager_t *httpAdmin_create(celix_bundle_context_t *context, char
*root /*note takes over ownership*/, const char **svr_opts);
void httpAdmin_destroy(http_admin_manager_t *admin);
struct mg_context *httpAdmin_getServerContext(const http_admin_manager_t
*admin);
@@ -41,5 +41,8 @@ struct mg_context *httpAdmin_getServerContext(const
http_admin_manager_t *admin)
void http_admin_addHttpService(void *handle, void *svc, const
celix_properties_t *props);
void http_admin_removeHttpService(void *handle, void *svc, const
celix_properties_t *props);
+void http_admin_startBundle(void *data, const celix_bundle_t *bundle);
+void http_admin_stopBundle(void *data, const celix_bundle_t *bundle);
+
#endif //CELIX_HTTP_ADMIN_H
diff --git a/bundles/http_admin/http_admin/src/http_admin_constants.h
b/bundles/http_admin/http_admin/src/http_admin_constants.h
new file mode 100644
index 0000000..2336569
--- /dev/null
+++ b/bundles/http_admin/http_admin/src/http_admin_constants.h
@@ -0,0 +1,43 @@
+/**
+ *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_HTTP_ADMIN_CONSTANTS_H
+#define CELIX_HTTP_ADMIN_CONSTANTS_H
+
+#define HTTP_ADMIN_USE_WEBSOCKETS_KEY
"CELIX_HTTP_ADMIN_USE_WEBSOCKETS"
+#define HTTP_ADMIN_USE_WEBSOCKETS_DFT true
+
+#define HTTP_ADMIN_LISTENING_PORTS_KEY
"CELIX_HTTP_ADMIN_LISTENING_PORTS"
+#define HTTP_ADMIN_LISTENING_PORTS_DFT 8080L
+
+#define HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS_KEY
"CELIX_HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS"
+#define HTTP_ADMIN_WEBSOCKET_TIMEOUT_MS_DFT 3600000L
+
+#define HTTP_ADMIN_PORT_RANGE_MIN_KEY
"CELIX_HTTP_ADMIN_PORT_RANGE_MIN"
+#define HTTP_ADMIN_PORT_RANGE_MIN_DFT 8000L
+
+#define HTTP_ADMIN_PORT_RANGE_MAX_KEY
"CELIX_HTTP_ADMIN_PORT_RANGE_MAX"
+#define HTTP_ADMIN_PORT_RANGE_MAX_DFT 9000L
+
+#define HTTP_ADMIN_NUM_THREADS_KEY "CELIX_HTTP_ADMIN_NUM_THREADS"
+#define HTTP_ADMIN_NUM_THREADS_DFT 1L
+
+
+#endif //CELIX_HTTP_ADMIN_CONSTANTS_H
diff --git
a/bundles/http_admin/http_admin_api/include/http_admin/http_admin_info_service.h
b/bundles/http_admin/http_admin_api/include/http_admin/http_admin_info_service.h
index 56d7cf0..d2fd22f 100644
---
a/bundles/http_admin/http_admin_api/include/http_admin/http_admin_info_service.h
+++
b/bundles/http_admin/http_admin_api/include/http_admin/http_admin_info_service.h
@@ -31,13 +31,23 @@
#define HTTP_ADMIN_INFO_SERVICE_NAME "http_admin_info_service"
-//Properties
+/**
+ * Listening port of the HTTP Admin
+ */
#define HTTP_ADMIN_INFO_PORT "http_admin_port"
+/**
+ * available resources found by the HTTP Admin. Entries are comma separated.
+ * Only present if there are available resources.
+ */
+#define HTTP_ADMIN_INFO_RESOURCE_URLS "http_admin_resource_urls"
+
/*
* Marker interface
* Mandatory properties:
* - http_admin_port
+ * Optional properties:
+ * - http_admin_resource_urls
*
*/
struct celix_http_info_service {
diff --git a/bundles/http_admin/test/CMakeLists.txt
b/bundles/http_admin/test/CMakeLists.txt
index 85c610a..f523f2a 100644
--- a/bundles/http_admin/test/CMakeLists.txt
+++ b/bundles/http_admin/test/CMakeLists.txt
@@ -52,7 +52,7 @@ add_celix_container(http_websocket_tests
http_admin_sut
# http_admin_tst
)
-target_sources(http_websocket_tests PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/test/http_websocket_tests.cc)
+target_sources(http_websocket_tests PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/test/http_websocket_tests.cc
${CMAKE_CURRENT_SOURCE_DIR}/test/http_admin_info_tests.cc)
target_link_libraries(http_websocket_tests PRIVATE Celix::http_admin_api
${CPPUTEST_LIBRARIES})
target_include_directories(http_websocket_tests PRIVATE
${CPPUTEST_INCLUDE_DIR})
diff --git a/bundles/http_admin/test/config.properties.in
b/bundles/http_admin/test/config.properties.in
index 6412a30..67f8ed4 100644
--- a/bundles/http_admin/test/config.properties.in
+++ b/bundles/http_admin/test/config.properties.in
@@ -20,6 +20,6 @@ CELIX_BUNDLES_PATH=bundles
CELIX_AUTO_START_3=@http_admin_service_cmp@ @http_admin_sut_cmp@
-USE_WEBSOCKETS=@use_websockets@
-LISTENING_PORTS=@listening_ports@
+CELIX_HTTP_ADMIN_USE_WEBSOCKETS=@use_websockets@
+CELIX_HTTP_ADMIN_LISTENING_PORTS=@listening_ports@
LOGHELPER_STD_OUT_FALLBACK_INCLUDE_DEBUG=@loghelper_std_out_fallback_incl_debug@
\ No newline at end of file
diff --git a/bundles/http_admin/test/test/http_admin_info_tests.cc
b/bundles/http_admin/test/test/http_admin_info_tests.cc
new file mode 100644
index 0000000..a7625d3
--- /dev/null
+++ b/bundles/http_admin/test/test/http_admin_info_tests.cc
@@ -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.
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "celix_api.h"
+#include "http_admin/api.h"
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+#include <constants.h>
+
+extern celix_framework_t *fw;
+
+TEST_GROUP(HTTP_ADMIN_INFO_INT_GROUP)
+{
+ celix_bundle_context_t *ctx = nullptr;
+ void setup() {
+ if (fw != nullptr) {
+ ctx = celix_framework_getFrameworkContext(fw);
+ }
+ //Setup
+ }
+
+ void teardown() {
+ //Teardown
+ }
+};
+
+
+TEST(HTTP_ADMIN_INFO_INT_GROUP, http_admin_info_test) {
+ CHECK(ctx != nullptr);
+
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = HTTP_ADMIN_INFO_SERVICE_NAME;
+ opts.filter.filter = "(http_admin_resource_urls=*)";
+ opts.waitTimeoutInSeconds = 2.0;
+ opts.useWithProperties = [](void */*handle*/, void */*svc*/, const
celix_properties_t *props) {
+ long port = celix_properties_getAsLong(props, HTTP_ADMIN_INFO_PORT,
-1L);
+ const char *resources = celix_properties_get(props,
HTTP_ADMIN_INFO_RESOURCE_URLS, "");
+ CHECK_EQUAL(8000L, port);
+ STRCMP_EQUAL("/alias,/socket_alias", resources);
+ };
+
+ bool called = celix_bundleContext_useServiceWithOptions(ctx, &opts);
+ CHECK(called);
+}
diff --git a/bundles/http_admin/test/test/http_websocket_tests.cc
b/bundles/http_admin/test/test/http_websocket_tests.cc
index 409d095..eb740e4 100644
--- a/bundles/http_admin/test/test/http_websocket_tests.cc
+++ b/bundles/http_admin/test/test/http_websocket_tests.cc
@@ -37,6 +37,8 @@
#include <CppUTestExt/MockSupport.h>
#include <constants.h>
+#define HTTP_PORT 8000
+
//Local function prototypes
static int
websocket_client_data_handler(struct mg_connection *conn, int flags, char
*data, size_t data_len, void *user_data);
@@ -67,7 +69,7 @@ TEST(HTTP_ADMIN_INT_GROUP, http_get_test) {
const struct mg_response_info *response_info;
struct mg_connection *connection;
- connection = mg_connect_client("localhost", 8000 /*port*/, 0 /*no ssl*/,
err_buf, sizeof(err_buf));
+ connection = mg_connect_client("localhost", HTTP_PORT /*port*/, 0 /*no
ssl*/, err_buf, sizeof(err_buf));
CHECK(connection != nullptr);
//Send request and check if complete request is send
@@ -93,7 +95,7 @@ TEST(HTTP_ADMIN_INT_GROUP, http_get_file_not_existing_test) {
const struct mg_response_info *response_info;
struct mg_connection *connection;
- connection = mg_connect_client("localhost", 8000 /*port*/, 0 /*no ssl*/,
err_buf, sizeof(err_buf));
+ connection = mg_connect_client("localhost", HTTP_PORT /*port*/, 0 /*no
ssl*/, err_buf, sizeof(err_buf));
CHECK(connection != nullptr);
send_bytes = mg_write(connection, get_req_str, strlen(get_req_str));
@@ -118,7 +120,7 @@ TEST(HTTP_ADMIN_INT_GROUP, http_get_uri_not_existing_test) {
const struct mg_response_info *response_info;
struct mg_connection *connection;
- connection = mg_connect_client("localhost", 8000 /*port*/, 0 /*no ssl*/,
err_buf, sizeof(err_buf));
+ connection = mg_connect_client("localhost", HTTP_PORT /*port*/, 0 /*no
ssl*/, err_buf, sizeof(err_buf));
CHECK(connection != nullptr);
send_bytes = mg_write(connection, get_req_str, strlen(get_req_str));
@@ -143,7 +145,7 @@ TEST(HTTP_ADMIN_INT_GROUP, http_request_not_existing_test) {
const struct mg_response_info *response_info;
struct mg_connection *connection;
- connection = mg_connect_client("localhost", 8000 /*port*/, 0 /*no ssl*/,
err_buf, sizeof(err_buf));
+ connection = mg_connect_client("localhost", HTTP_PORT /*port*/, 0 /*no
ssl*/, err_buf, sizeof(err_buf));
CHECK(connection != nullptr);
send_bytes = mg_write(connection, get_req_str, strlen(get_req_str));
@@ -169,7 +171,7 @@ TEST(HTTP_ADMIN_INT_GROUP, http_put_echo_alias_test) {
const struct mg_response_info *response_info;
struct mg_connection *connection;
- connection = mg_connect_client("localhost", 8000 /*port*/, 0 /*no ssl*/,
err_buf, sizeof(err_buf));
+ connection = mg_connect_client("localhost", HTTP_PORT /*port*/, 0 /*no
ssl*/, err_buf, sizeof(err_buf));
CHECK(connection != nullptr);
//Send request and check if complete request is send
@@ -209,7 +211,7 @@ TEST(HTTP_ADMIN_INT_GROUP, websocket_echo_test) {
echo_data.length = strlen(data_str);
echo_data.data = (char *) malloc(strlen(data_str));
- connection = mg_connect_websocket_client("127.0.0.1", 8000, 0, err_buf,
sizeof(err_buf),
+ connection = mg_connect_websocket_client("127.0.0.1", HTTP_PORT, 0,
err_buf, sizeof(err_buf),
"/", "websocket_test", websocket_client_data_handler, nullptr,
&echo_data);
CHECK(connection != nullptr);
diff --git a/bundles/http_admin/test/test/test_runner.cc
b/bundles/http_admin/test/test/test_runner.cc
index e53570a..916fa20 100644
--- a/bundles/http_admin/test/test/test_runner.cc
+++ b/bundles/http_admin/test/test/test_runner.cc
@@ -24,15 +24,19 @@
* \copyright Apache License, Version 2.0
*/
-#include "celix_api.h"
+#include <unistd.h>
+#include "celix_api.h"
#include <CppUTest/TestHarness.h>
#include <CppUTest/CommandLineTestRunner.h>
+celix_framework_t *fw = nullptr;
+
+
int main(int argc, char **argv) {
- celix_framework_t *fw = NULL;
celixLauncher_launch("config.properties", &fw);
+ //usleep(1000000);
MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
int rc = RUN_ALL_TESTS(argc, argv);
diff --git a/libs/framework/include/celix_bundle_context.h
b/libs/framework/include/celix_bundle_context.h
index 18fdb57..8eb6d90 100644
--- a/libs/framework/include/celix_bundle_context.h
+++ b/libs/framework/include/celix_bundle_context.h
@@ -489,6 +489,13 @@ typedef struct celix_service_use_options {
celix_service_filter_options_t filter OPTS_INIT;
/**
+ * An optional timeout (in seconds), if > 0 the use service call will
block untill the timeout is expired or
+ * when at least one service is found.
+ * Default (0)
+ */
+ double waitTimeoutInSeconds OPTS_INIT;
+
+ /**
* The optional callback pointer used in all the provided callback
function (set, add, remove, setWithProperties, etc).
*/
void *callbackHandle OPTS_INIT;
@@ -523,6 +530,7 @@ typedef struct celix_service_use_options {
.filter.versionRange = NULL, \
.filter.filter = NULL, \
.filter.serviceLanguage = NULL, \
+ .waitTimeoutInSeconds = 0.0F, \
.callbackHandle = NULL, \
.use = NULL, \
.useWithProperties = NULL, \
diff --git a/libs/framework/include/service_tracker.h
b/libs/framework/include/service_tracker.h
index 09278b1..545b1be 100644
--- a/libs/framework/include/service_tracker.h
+++ b/libs/framework/include/service_tracker.h
@@ -111,11 +111,15 @@ void celix_serviceTracker_destroy(celix_service_tracker_t
*tracker);
* If a serviceName is provided this will also be checked.
* No match -> no call to use.
*
+ * If waitForSvcTimeoutInSec is > 0. The call will block until a service is
found or the timeout is expired.
+ * (with a precision of roughly 1 microsecond)
+ *
* @return bool if the service if found and use has been called.
*/
bool celix_serviceTracker_useHighestRankingService(
celix_service_tracker_t *tracker,
const char *serviceName /*sanity*/,
+ double waitTimeoutInSeconds /*0 -> do not wait */,
void *callbackHandle,
void (*use)(void *handle, void *svc),
void (*useWithProperties)(void *handle, void *svc, const
celix_properties_t *props),
diff --git a/libs/framework/src/bundle_context.c
b/libs/framework/src/bundle_context.c
index 154b886..5f78f85 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -840,7 +840,7 @@ bool celix_bundleContext_useServiceWithOptions(
if (opts->useWithOwner != NULL) {
}
- called = celix_serviceTracker_useHighestRankingService(trk,
opts->filter.serviceName, opts->callbackHandle, opts->use,
opts->useWithProperties, opts->useWithOwner);
+ called = celix_serviceTracker_useHighestRankingService(trk,
opts->filter.serviceName, opts->waitTimeoutInSeconds, opts->callbackHandle,
opts->use, opts->useWithProperties, opts->useWithOwner);
celix_serviceTracker_destroy(trk);
}
}
diff --git a/libs/framework/src/service_tracker.c
b/libs/framework/src/service_tracker.c
index 9a5cc9e..66f1c45 100644
--- a/libs/framework/src/service_tracker.c
+++ b/libs/framework/src/service_tracker.c
@@ -22,6 +22,7 @@
#include "service_reference_private.h"
#include "framework_private.h"
#include <assert.h>
+#include <unistd.h>
#include "service_tracker_private.h"
#include "bundle_context.h"
@@ -41,6 +42,7 @@ static celix_status_t
serviceTracker_invokeRemovingService(celix_service_tracker
static void serviceTracker_checkAndInvokeSetService(void *handle, void
*highestSvc, const properties_t *props, const bundle_t *bnd);
static bool
serviceTracker_useHighestRankingServiceInternal(celix_service_tracker_instance_t
*instance,
const char
*serviceName /*sanity*/,
+ double
waitTimeoutInSeconds,
void
*callbackHandle,
void (*use)(void
*handle, void *svc),
void
(*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
@@ -491,7 +493,7 @@ static celix_status_t
serviceTracker_track(celix_service_tracker_instance_t *ins
celixThreadRwlock_unlock(&instance->lock);
serviceTracker_invokeAddService(instance, tracked);
- serviceTracker_useHighestRankingServiceInternal(instance,
tracked->serviceName, instance, NULL, NULL,
serviceTracker_checkAndInvokeSetService);
+ serviceTracker_useHighestRankingServiceInternal(instance,
tracked->serviceName, 0, instance, NULL, NULL,
serviceTracker_checkAndInvokeSetService);
}
}
@@ -633,7 +635,7 @@ static celix_status_t
serviceTracker_untrack(celix_service_tracker_instance_t* i
if (size == 0) {
serviceTracker_checkAndInvokeSetService(instance, NULL, NULL, NULL);
} else {
- serviceTracker_useHighestRankingServiceInternal(instance, serviceName,
instance, NULL, NULL, serviceTracker_checkAndInvokeSetService);
+ serviceTracker_useHighestRankingServiceInternal(instance, serviceName,
0, instance, NULL, NULL, serviceTracker_checkAndInvokeSetService);
}
serviceTracker_untrackTracked(instance, remove);
@@ -791,6 +793,7 @@ void celix_serviceTracker_destroy(celix_service_tracker_t
*tracker) {
static bool
serviceTracker_useHighestRankingServiceInternal(celix_service_tracker_instance_t
*instance,
const char
*serviceName /*sanity*/,
+ double
waitForSvcTimeoutInSec /*0 -> do not wait */,
void
*callbackHandle,
void (*use)(void
*handle, void *svc),
void
(*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
@@ -803,7 +806,32 @@ static bool
serviceTracker_useHighestRankingServiceInternal(celix_service_tracke
//first lock tracker and get highest tracked entry
celixThreadRwlock_readLock(&instance->lock);
- for (i = 0; i < arrayList_size(instance->trackedServices); i++) {
+ unsigned int size = arrayList_size(instance->trackedServices);
+
+ if (waitForSvcTimeoutInSec > 0) {
+ struct timespec start;
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &start);
+
+ double billion = 1E9;
+ long waitFor = (long)(waitForSvcTimeoutInSec * billion);
+ long diffInNs = 0L;
+
+ while (size == 0 && diffInNs < waitFor) {
+ size = arrayList_size(instance->trackedServices);
+ if (size > 0) {
+ break;
+ } else {
+ celixThreadRwlock_unlock(&instance->lock);
+ usleep(1);
+ celixThreadRwlock_readLock(&instance->lock);
+ };
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ diffInNs = ( now.tv_nsec - start.tv_nsec ) + ( now.tv_sec -
start.tv_sec ) * (long)billion;
+ }
+ }
+
+ for (i = 0; i < size; i++) {
tracked = (celix_tracked_entry_t *)
arrayList_get(instance->trackedServices, i);
if (serviceName != NULL && tracked->serviceName != NULL &&
strncmp(tracked->serviceName, serviceName, 10*1024) == 0) {
const char *val = properties_getWithDefault(tracked->properties,
OSGI_FRAMEWORK_SERVICE_RANKING, "0");
@@ -842,6 +870,7 @@ static bool
serviceTracker_useHighestRankingServiceInternal(celix_service_tracke
bool celix_serviceTracker_useHighestRankingService(
celix_service_tracker_t *tracker,
const char *serviceName /*sanity*/,
+ double waitTimeoutInSeconds,
void *callbackHandle,
void (*use)(void *handle, void *svc),
void (*useWithProperties)(void *handle, void *svc, const
celix_properties_t *props),
@@ -850,7 +879,7 @@ bool celix_serviceTracker_useHighestRankingService(
celix_service_tracker_instance_t *instance = tracker->instance;
bool called = false;
if (instance != NULL) {
- called = serviceTracker_useHighestRankingServiceInternal(instance,
serviceName, callbackHandle, use,
+ called = serviceTracker_useHighestRankingServiceInternal(instance,
serviceName, waitTimeoutInSeconds, callbackHandle, use,
useWithProperties, useWithOwner);
}
celixThreadRwlock_unlock(&tracker->instanceLock);
diff --git a/libs/framework/tst/bundle_context_bundles_tests.cpp
b/libs/framework/tst/bundle_context_bundles_tests.cpp
index 332e8e5..f0fdf39 100644
--- a/libs/framework/tst/bundle_context_bundles_tests.cpp
+++ b/libs/framework/tst/bundle_context_bundles_tests.cpp
@@ -31,9 +31,9 @@
TEST_GROUP(CelixBundleContextBundlesTests) {
- framework_t* fw = NULL;
- bundle_context_t *ctx = NULL;
- properties_t *properties = NULL;
+ framework_t* fw = nullptr;
+ bundle_context_t *ctx = nullptr;
+ properties_t *properties = nullptr;
const char * const TEST_BND1_LOC = "simple_test_bundle1.zip";
const char * const TEST_BND2_LOC = "simple_test_bundle2.zip";
@@ -158,7 +158,7 @@ TEST(CelixBundleContextBundlesTests, trackBundlesTest) {
auto started = [](void *handle, const bundle_t *bnd) {
struct data *d = static_cast<struct data*>(handle);
- CHECK(bnd != NULL);
+ CHECK(bnd != nullptr);
d->mutex.lock();
d->count += 1;
d->cond.notify_all();
@@ -166,7 +166,7 @@ TEST(CelixBundleContextBundlesTests, trackBundlesTest) {
};
auto stopped = [](void *handle, const bundle_t *bnd) {
struct data *d = static_cast<struct data*>(handle);
- CHECK(bnd != NULL);
+ CHECK(bnd != nullptr);
d->mutex.lock();
d->count -= 1;
d->cond.notify_all();
@@ -242,7 +242,7 @@ TEST(CelixBundleContextBundlesTests,
useBundlesConcurrentTest) {
struct data data{};
auto use = [](void *handle, const bundle_t *bnd) {
- CHECK(bnd != NULL);
+ CHECK(bnd != nullptr);
struct data *d = static_cast<struct data*>(handle);
diff --git a/libs/framework/tst/bundle_context_services_test.cpp
b/libs/framework/tst/bundle_context_services_test.cpp
index b276dfe..96e1332 100644
--- a/libs/framework/tst/bundle_context_services_test.cpp
+++ b/libs/framework/tst/bundle_context_services_test.cpp
@@ -24,6 +24,7 @@
#include <zconf.h>
#include <string.h>
#include <map>
+#include <future>
#include "celix_api.h"
#include "celix_framework_factory.h"
@@ -37,9 +38,9 @@
TEST_GROUP(CelixBundleContextServicesTests) {
- framework_t* fw = NULL;
- bundle_context_t *ctx = NULL;
- properties_t *properties = NULL;
+ framework_t* fw = nullptr;
+ bundle_context_t *ctx = nullptr;
+ properties_t *properties = nullptr;
void setup() {
properties = properties_create();
@@ -67,7 +68,7 @@ TEST(CelixBundleContextServicesTests, registerService) {
return n * 42;
};
- long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId >= 0);
celix_bundleContext_unregisterService(ctx, svcId);
};
@@ -90,17 +91,17 @@ TEST(CelixBundleContextServicesTests,
registerMultipleAndUseServices) {
return n * 42;
};
- long svcId1 = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId1 >= 0);
- long svcId2 = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId2 = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId2 >= 0);
- long svcId3 = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId3 = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId3 >= 0);
auto use = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *total = static_cast<int*>(handle);
struct calc *calc = static_cast<struct calc*>(svc);
int tmp = calc->calc(1);
@@ -137,12 +138,12 @@ TEST(CelixBundleContextServicesTests,
registerAndUseService) {
return n * 42;
};
- long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId >= 0);
int result = 0;
bool called = celix_bundleContext_useServiceWithId(ctx, svcId, calcName,
&result, [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *result = static_cast<int*>(handle);
struct calc *calc = static_cast<struct calc*>(svc);
int tmp = calc->calc(2);
@@ -165,6 +166,39 @@ TEST(CelixBundleContextServicesTests,
registerAndUseService) {
celix_bundleContext_unregisterService(ctx, svcId);
};
+TEST(CelixBundleContextServicesTests, registerAndUseServiceWithTimeout) {
+ struct calc {
+ int (*calc)(int);
+ };
+
+ const char *calcName = "calc";
+ struct calc svc;
+ svc.calc = [](int n) -> int {
+ return n * 42;
+ };
+
+ celix_service_use_options_t opts{};
+ opts.filter.serviceName = "calc";
+
+ bool called = celix_bundleContext_useServiceWithOptions(ctx, &opts);
+ CHECK(!called); //service not avail.
+
+ std::future<bool> result{std::async([&]{
+ opts.waitTimeoutInSeconds = 5.0;
+ bool calledAsync = celix_bundleContext_useServiceWithOptions(ctx,
&opts);
+ return calledAsync;
+ })};
+
+ long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
+ CHECK(svcId >= 0);
+
+
+ CHECK(result.get()); //should return true after waiting for the registered
service.
+
+
+ celix_bundleContext_unregisterService(ctx, svcId);
+}
+
TEST(CelixBundleContextServicesTests, registerAndUseWithForcedRaceCondition) {
struct calc {
int (*calc)(int);
@@ -176,7 +210,7 @@ TEST(CelixBundleContextServicesTests,
registerAndUseWithForcedRaceCondition) {
return n * 42;
};
- long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long svcId = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
CHECK(svcId >= 0);
struct sync {
@@ -190,7 +224,7 @@ TEST(CelixBundleContextServicesTests,
registerAndUseWithForcedRaceCondition) {
struct sync callInfo{};
auto use = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
struct sync *h = static_cast<struct sync*>(handle);
@@ -248,12 +282,12 @@ TEST(CelixBundleContextServicesTests,
registerAndUseWithForcedRaceCondition) {
TEST(CelixBundleContextServicesTests, servicesTrackerTest) {
int count = 0;
auto add = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *c = static_cast<int*>(handle);
*c += 1;
};
auto remove = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *c = static_cast<int*>(handle);
*c -= 1;
};
@@ -262,11 +296,11 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTest) {
CHECK(trackerId > 0);
CHECK_EQUAL(0, count);
- long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", nullptr);
CHECK(svcId1 > 0);
CHECK_EQUAL(1, count);
- long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", NULL);
+ long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", nullptr);
CHECK(svcId2 > 0);
CHECK_EQUAL(2, count);
@@ -278,19 +312,19 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTest) {
}
TEST(CelixBundleContextServicesTests, servicesTrackerInvalidArgsTest) {
- long trackerId = celix_bundleContext_trackServices(NULL, NULL, NULL, NULL,
NULL);
+ long trackerId = celix_bundleContext_trackServices(nullptr, nullptr,
nullptr, nullptr, nullptr);
CHECK(trackerId < 0); //required ctx and service name missing
- trackerId = celix_bundleContext_trackServices(ctx, NULL, NULL, NULL, NULL);
+ trackerId = celix_bundleContext_trackServices(ctx, nullptr, nullptr,
nullptr, nullptr);
CHECK(trackerId < 0); //required service name missing
- trackerId = celix_bundleContext_trackServices(ctx, "calc", NULL, NULL,
NULL);
+ trackerId = celix_bundleContext_trackServices(ctx, "calc", nullptr,
nullptr, nullptr);
CHECK(trackerId >= 0); //valid
celix_bundleContext_stopTracker(ctx, trackerId);
//opts
- trackerId = celix_bundleContext_trackServicesWithOptions(NULL, NULL);
+ trackerId = celix_bundleContext_trackServicesWithOptions(nullptr, nullptr);
CHECK(trackerId < 0); //required ctx and opts missing
- trackerId = celix_bundleContext_trackServicesWithOptions(ctx, NULL);
+ trackerId = celix_bundleContext_trackServicesWithOptions(ctx, nullptr);
CHECK(trackerId < 0); //required opts missing
celix_service_tracking_options_t opts{};
trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
@@ -304,18 +338,18 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerInvalidArgsTest) {
TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithAlreadyRegisteredServices) {
int count = 0;
auto add = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *c = static_cast<int*>(handle);
*c += 1;
};
auto remove = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
int *c = static_cast<int*>(handle);
*c -= 1;
};
- long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x010,
"calc", NULL);
- long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x020,
"calc", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x010,
"calc", nullptr);
+ long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x020,
"calc", nullptr);
@@ -323,11 +357,11 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithAlreadyRegisteredSe
CHECK(trackerId > 0);
CHECK_EQUAL(2, count);
- long svcId3 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", NULL);
+ long svcId3 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", nullptr);
CHECK(svcId1 > 0);
CHECK_EQUAL(3, count);
- long svcId4 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", NULL);
+ long svcId4 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", nullptr);
CHECK(svcId2 > 0);
CHECK_EQUAL(4, count);
@@ -343,19 +377,19 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithAlreadyRegisteredSe
TEST(CelixBundleContextServicesTests, servicesTrackerTestWithProperties) {
int count = 0;
auto add = [](void *handle, void *svc, const properties_t *props) {
- CHECK(svc != NULL);
- STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL));
+ CHECK(svc != nullptr);
+ STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, nullptr));
int *c = static_cast<int*>(handle);
*c += 1;
};
auto remove = [](void *handle, void *svc, const properties_t *props) {
- CHECK(svc != NULL);
- STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL));
+ CHECK(svc != nullptr);
+ STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, nullptr));
int *c = static_cast<int*>(handle);
*c -= 1;
};
- long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", nullptr);
celix_service_tracking_options_t opts{};
opts.filter.serviceName = "calc";
@@ -366,7 +400,7 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithProperties) {
CHECK(trackerId > 0);
CHECK_EQUAL(1, count);
- long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", NULL);
+ long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", nullptr);
CHECK(svcId1 > 0);
CHECK_EQUAL(2, count);
@@ -380,21 +414,21 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithProperties) {
TEST(CelixBundleContextServicesTests, servicesTrackerTestWithOwner) {
int count = 0;
auto add = [](void *handle, void *svc, const properties_t *props, const
bundle_t *svcOwner) {
- CHECK(svc != NULL);
- STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL));
+ CHECK(svc != nullptr);
+ STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, nullptr));
CHECK(celix_bundle_getId(svcOwner) >= 0);
int *c = static_cast<int*>(handle);
*c += 1;
};
auto remove = [](void *handle, void *svc, const properties_t *props, const
bundle_t *svcOwner) {
- CHECK(svc != NULL);
- STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL));
+ CHECK(svc != nullptr);
+ STRCMP_EQUAL("C", celix_properties_get(props,
CELIX_FRAMEWORK_SERVICE_LANGUAGE, nullptr));
CHECK(celix_bundle_getId(svcOwner) >= 0);
int *c = static_cast<int*>(handle);
*c -= 1;
};
- long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"calc", nullptr);
celix_service_tracking_options_t opts{};
opts.filter.serviceName = "calc";
@@ -405,7 +439,7 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerTestWithOwner) {
CHECK(trackerId > 0);
CHECK_EQUAL(1, count);
- long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", NULL);
+ long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200,
"calc", nullptr);
CHECK(svcId1 > 0);
CHECK_EQUAL(2, count);
@@ -439,7 +473,7 @@ TEST(CelixBundleContextServicesTests,
serviceTrackerWithRaceConditionTest) {
struct data data{};
auto add = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
struct data *d = static_cast<struct data*>(handle);
@@ -458,7 +492,7 @@ TEST(CelixBundleContextServicesTests,
serviceTrackerWithRaceConditionTest) {
};
auto remove = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
struct data *d = static_cast<struct data*>(handle);
@@ -473,7 +507,7 @@ TEST(CelixBundleContextServicesTests,
serviceTrackerWithRaceConditionTest) {
long trackerId = celix_bundleContext_trackServices(ctx, calcName, &data,
add, remove);
std::thread registerThread{[&]{
- long id = celix_bundleContext_registerService(ctx, &svc, calcName,
NULL);
+ long id = celix_bundleContext_registerService(ctx, &svc, calcName,
nullptr);
std::cout << "registered service with id " << id << std::endl;
std::lock_guard<std::mutex> lock{data.mutex};
data.svcId = id;
@@ -528,7 +562,7 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerSetTest) {
void *svc4 = (void*)0x400; //5 ranking
auto set = [](void *handle, void *svc) {
- CHECK(svc != NULL);
+ CHECK(svc != nullptr);
static int callCount = 0;
callCount += 1;
if (callCount == 1) {
@@ -546,8 +580,8 @@ TEST(CelixBundleContextServicesTests,
servicesTrackerSetTest) {
*c = callCount;
};
- long svcId1 = celix_bundleContext_registerService(ctx, svc1, "NA", NULL);
- long svcId2 = celix_bundleContext_registerService(ctx, svc2, "NA", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, svc1, "NA",
nullptr);
+ long svcId2 = celix_bundleContext_registerService(ctx, svc2, "NA",
nullptr);
//starting tracker should lead to first set call
celix_service_tracking_options_t opts{};
@@ -603,7 +637,7 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
*c += 1;
};
- long facId = celix_bundleContext_registerServiceFactory(ctx, &fac, name,
NULL);
+ long facId = celix_bundleContext_registerServiceFactory(ctx, &fac, name,
nullptr);
CHECK_TRUE(facId >= 0);
@@ -622,8 +656,8 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
}
TEST(CelixBundleContextServicesTests, findServicesTest) {
- long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"example", NULL);
- long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x100,
"example", NULL);
+ long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100,
"example", nullptr);
+ long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x100,
"example", nullptr);
long foundId = celix_bundleContext_findService(ctx, "non existing service
name");
CHECK_EQUAL(-1L, foundId);
@@ -670,15 +704,15 @@ TEST(CelixBundleContextServicesTests,
trackServiceTrackerTest) {
CHECK_TRUE(trackerId >= 0);
CHECK_EQUAL(0, count);
- long tracker2 = celix_bundleContext_trackService(ctx, "example", NULL,
NULL);
+ long tracker2 = celix_bundleContext_trackService(ctx, "example", nullptr,
nullptr);
CHECK_TRUE(tracker2 >= 0);
CHECK_EQUAL(1, count);
- long tracker3 = celix_bundleContext_trackServices(ctx, "example", NULL,
NULL, NULL);
+ long tracker3 = celix_bundleContext_trackServices(ctx, "example", nullptr,
nullptr, nullptr);
CHECK_TRUE(tracker3 >= 0);
CHECK_EQUAL(2, count);
- long tracker4 = celix_bundleContext_trackServices(ctx, "no-match", NULL,
NULL, NULL);
+ long tracker4 = celix_bundleContext_trackServices(ctx, "no-match",
nullptr, nullptr, nullptr);
CHECK_TRUE(tracker4 >= 0);
CHECK_EQUAL(2, count);
diff --git a/libs/framework/tst/multiple_frameworks_test.cpp
b/libs/framework/tst/multiple_frameworks_test.cpp
index 8c5eea3..392f851 100644
--- a/libs/framework/tst/multiple_frameworks_test.cpp
+++ b/libs/framework/tst/multiple_frameworks_test.cpp
@@ -31,21 +31,21 @@ extern "C" {
#include "celix_launcher.h"
#include "framework.h"
- static framework_pt serverFramework = NULL;
- static bundle_context_pt serverContext = NULL;
+ static framework_pt serverFramework = nullptr;
+ static bundle_context_pt serverContext = nullptr;
- static framework_pt clientFramework = NULL;
- static bundle_context_pt clientContext = NULL;
+ static framework_pt clientFramework = nullptr;
+ static bundle_context_pt clientContext = nullptr;
static void setupFm(void) {
int rc = 0;
- bundle_pt bundle = NULL;
+ bundle_pt bundle = nullptr;
//server
rc = celixLauncher_launch("framework1.properties", &serverFramework);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- bundle = NULL;
+ bundle = nullptr;
rc = framework_getFrameworkBundle(serverFramework, &bundle);
CHECK_EQUAL(CELIX_SUCCESS, rc);
@@ -57,7 +57,7 @@ extern "C" {
rc = celixLauncher_launch("framework2.properties", &clientFramework);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- bundle = NULL;
+ bundle = nullptr;
rc = framework_getFrameworkBundle(clientFramework, &bundle);
CHECK_EQUAL(CELIX_SUCCESS, rc);
@@ -75,10 +75,10 @@ extern "C" {
celixLauncher_waitForShutdown(clientFramework);
celixLauncher_destroy(clientFramework);
- serverContext = NULL;
- serverFramework = NULL;
- clientContext = NULL;
- clientFramework = NULL;
+ serverContext = nullptr;
+ serverFramework = nullptr;
+ clientContext = nullptr;
+ clientFramework = nullptr;
}
static void testFrameworks(void) {
diff --git a/libs/framework/tst/single_framework_test.cpp
b/libs/framework/tst/single_framework_test.cpp
index 861f186..6fa39f4 100644
--- a/libs/framework/tst/single_framework_test.cpp
+++ b/libs/framework/tst/single_framework_test.cpp
@@ -31,8 +31,8 @@ extern "C" {
#include "celix_framework_factory.h"
- static framework_pt framework = NULL;
- static bundle_context_pt context = NULL;
+ static framework_pt framework = nullptr;
+ static bundle_context_pt context = nullptr;
static void setupFm(void) {
int rc = 0;
@@ -40,7 +40,7 @@ extern "C" {
rc = celixLauncher_launch("config.properties", &framework);
CHECK_EQUAL(CELIX_SUCCESS, rc);
- bundle_pt bundle = NULL;
+ bundle_pt bundle = nullptr;
rc = framework_getFrameworkBundle(framework, &bundle);
CHECK_EQUAL(CELIX_SUCCESS, rc);
@@ -54,8 +54,8 @@ extern "C" {
celixLauncher_waitForShutdown(framework);
celixLauncher_destroy(framework);
- context = NULL;
- framework = NULL;
+ context = nullptr;
+ framework = nullptr;
}
static void testFramework(void) {
@@ -87,14 +87,14 @@ TEST_GROUP(FrameworkFactory) {
TEST(FrameworkFactory, testFactoryCreate) {
- framework_t* fw = celix_frameworkFactory_createFramework(NULL);
- CHECK(fw != NULL);
+ framework_t* fw = celix_frameworkFactory_createFramework(nullptr);
+ CHECK(fw != nullptr);
celix_frameworkFactory_destroyFramework(fw);
}
TEST(FrameworkFactory, testFactoryCreateAndToManyStartAndStops) {
- framework_t* fw = celix_frameworkFactory_createFramework(NULL);
- CHECK(fw != NULL);
+ framework_t* fw = celix_frameworkFactory_createFramework(nullptr);
+ CHECK(fw != nullptr);
framework_start(fw); //should already be done by
frameworkFactory_newFramework();
framework_start(fw);
@@ -112,8 +112,8 @@ TEST(FrameworkFactory,
testFactoryCreateAndToManyStartAndStops) {
}
TEST(FrameworkFactory, restartFramework) {
- framework_t* fw = celix_frameworkFactory_createFramework(NULL);
- CHECK(fw != NULL);
+ framework_t* fw = celix_frameworkFactory_createFramework(nullptr);
+ CHECK(fw != nullptr);
/* TODO fix mem leak in restarting framework