CELIX-418: Added functionality to run executables without config.properties
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/5c9e52e2 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/5c9e52e2 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/5c9e52e2 Branch: refs/heads/master Commit: 5c9e52e238fb7dc5b33bd4a979315c701113c0bc Parents: 7bf5886 Author: Roy Lenferink <[email protected]> Authored: Wed Dec 27 18:56:10 2017 +0100 Committer: Roy Lenferink <[email protected]> Committed: Wed Dec 27 19:57:36 2017 +0100 ---------------------------------------------------------------------- cmake/cmake_celix/DeployPackaging.cmake | 28 +++++++++- framework/private/src/celix_launcher.c | 71 +++++++++++++++++++++++++- framework/public/include/celix_launcher.h | 2 + utils/private/src/properties.c | 28 ++++++++++ utils/public/include/properties.h | 2 + 5 files changed, 128 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/5c9e52e2/cmake/cmake_celix/DeployPackaging.cmake ---------------------------------------------------------------------- diff --git a/cmake/cmake_celix/DeployPackaging.cmake b/cmake/cmake_celix/DeployPackaging.cmake index 91200d8..0ec2322 100644 --- a/cmake/cmake_celix/DeployPackaging.cmake +++ b/cmake/cmake_celix/DeployPackaging.cmake @@ -92,7 +92,33 @@ function(add_celix_container) else () add_custom_command(OUTPUT ${LAUNCHER_SRC} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/celix/gen - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LAUNCHER_ORG} ${LAUNCHER_SRC} + ) + + if (CONTAINER_CXX) + set(STAGE1_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/${CONTAINER_TARGET}-main-stage1.cc") + else() + set(STAGE1_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/${CONTAINER_TARGET}-main-stage1.c") + endif() + + file(GENERATE + OUTPUT "${STAGE1_LAUNCHER}" + CONTENT "#include <celix_launcher.h> + +int main(int argc, char *argv[]) { + const char * config = \"cosgi.auto.start.1=$<JOIN:$<TARGET_PROPERTY:${CONTAINER_TARGET},CONTAINER_BUNDLES>, >\\n\\ +$<JOIN:$<TARGET_PROPERTY:${CONTAINER_TARGET},CONTAINER_PROPERTIES>,\\n\\ +>\"; + + properties_pt packedConfig = properties_loadFromString(config); + + return celixLauncher_launchWithArgsAndProps(argc, argv, packedConfig); +} +" + ) + + file(GENERATE + OUTPUT "${LAUNCHER_SRC}" + INPUT "${STAGE1_LAUNCHER}" ) include_directories(${CELIX_INCLUDE_DIRS}) http://git-wip-us.apache.org/repos/asf/celix/blob/5c9e52e2/framework/private/src/celix_launcher.c ---------------------------------------------------------------------- diff --git a/framework/private/src/celix_launcher.c b/framework/private/src/celix_launcher.c index ba83f25..4732b15 100644 --- a/framework/private/src/celix_launcher.c +++ b/framework/private/src/celix_launcher.c @@ -48,11 +48,21 @@ static void show_usage(char* prog_name); static void shutdown_framework(int signal); static void ignore(int signal); +static int celixLauncher_launchWithConfigAndProps(const char *configFile, framework_pt *framework, properties_pt packedConfig); +static int celixLauncher_launchWithStreamAndProps(FILE *stream, framework_pt *framework, properties_pt packedConfig); + #define DEFAULT_CONFIG_FILE "config.properties" static framework_pt framework = NULL; +/** + * Method kept because of usage in examples & unit tests + */ int celixLauncher_launchWithArgs(int argc, char *argv[]) { + return celixLauncher_launchWithArgsAndProps(argc, argv, NULL); +} + +int celixLauncher_launchWithArgsAndProps(int argc, char *argv[], properties_pt packedConfig) { // Perform some minimal command-line option parsing... char *opt = NULL; if (argc > 1) { @@ -84,7 +94,7 @@ int celixLauncher_launchWithArgs(int argc, char *argv[]) { sigaction(SIGUSR1, &sigact, NULL); sigaction(SIGUSR2, &sigact, NULL); - int rc = celixLauncher_launch(config_file, &framework); + int rc = celixLauncher_launchWithConfigAndProps(config_file, &framework, packedConfig); if (rc == 0) { celixLauncher_waitForShutdown(framework); celixLauncher_destroy(framework); @@ -107,15 +117,25 @@ static void ignore(int signal) { } int celixLauncher_launch(const char *configFile, framework_pt *framework) { + return celixLauncher_launchWithConfigAndProps(configFile, framework, NULL); +} + +static int celixLauncher_launchWithConfigAndProps(const char *configFile, framework_pt *framework, properties_pt packedConfig){ int status = 0; FILE *config = fopen(configFile, "r"); - if (config != NULL) { + + if (config != NULL && packedConfig != NULL) { + status = celixLauncher_launchWithStreamAndProps(config, framework, packedConfig); + } else if (config != NULL) { status = celixLauncher_launchWithStream(config, framework); + } else if (packedConfig != NULL) { + status = celixLauncher_launchWithProperties(packedConfig, framework); } else { fprintf(stderr, "Error: invalid or non-existing configuration file: '%s'.", configFile); perror(""); status = 1; } + return status; } @@ -137,6 +157,53 @@ int celixLauncher_launchWithStream(FILE *stream, framework_pt *framework) { return status; } +static int celixLauncher_launchWithStreamAndProps(FILE *stream, framework_pt *framework, properties_pt packedConfig){ + int status = 0; + + properties_pt runtimeConfig = properties_loadWithStream(stream); + fclose(stream); + + // Make sure we've read it and that nothing went wrong with the file access... + // If there is no runtimeConfig, the packedConfig can be stored as global config + if (runtimeConfig == NULL){ + runtimeConfig = packedConfig; + } + + if (runtimeConfig == NULL) { + fprintf(stderr, "Error: invalid configuration file"); + perror(NULL); + status = 1; + } else { + // Check if there's a pre-compiled config available + if (packedConfig != NULL){ + // runtimeConfig and packedConfig must be merged + // when a duplicate of a key is available, the runtimeConfig must be prioritized + + hash_map_iterator_t iter = hashMapIterator_construct(packedConfig); + + hash_map_entry_pt entry = hashMapIterator_nextEntry(&iter); + const char * key = (const char *) hashMapEntry_getKey(entry); + const char * value = (const char *) hashMapEntry_getValue(entry); + + while (entry != NULL) { + // Check existence of key in runtimeConfig + if (!hashMap_containsKey(runtimeConfig, key)) { + properties_set(runtimeConfig, key, value); + } + + entry = hashMapIterator_nextEntry(&iter); + if (entry != NULL) { + key = (const char *) hashMapEntry_getKey(entry); + value = (const char *) hashMapEntry_getValue(entry); + } + } + } + + status = celixLauncher_launchWithProperties(runtimeConfig, framework); + } + + return status; +} int celixLauncher_launchWithProperties(properties_pt config, framework_pt *framework) { celix_status_t status; http://git-wip-us.apache.org/repos/asf/celix/blob/5c9e52e2/framework/public/include/celix_launcher.h ---------------------------------------------------------------------- diff --git a/framework/public/include/celix_launcher.h b/framework/public/include/celix_launcher.h index 0d819c9..5c7cf4d 100644 --- a/framework/public/include/celix_launcher.h +++ b/framework/public/include/celix_launcher.h @@ -36,6 +36,8 @@ extern "C" { int celixLauncher_launchWithArgs(int argc, char *argv[]); +int celixLauncher_launchWithArgsAndProps(int argc, char *argv[], properties_pt config); + int celixLauncher_launch(const char *configFile, framework_pt *framework); int celixLauncher_launchWithStream(FILE *config, framework_pt *framework); http://git-wip-us.apache.org/repos/asf/celix/blob/5c9e52e2/utils/private/src/properties.c ---------------------------------------------------------------------- diff --git a/utils/private/src/properties.c b/utils/private/src/properties.c index 0bd6dc3..1e097a0 100644 --- a/utils/private/src/properties.c +++ b/utils/private/src/properties.c @@ -96,6 +96,34 @@ properties_pt properties_loadWithStream(FILE *file) { return props; } +properties_pt properties_loadFromString(const char *input){ + properties_pt props = properties_create(); + + char *in = strdup(input); + char *line = NULL; + char *saveLinePointer = NULL; + + bool firstTime = true; + do { + if (firstTime){ + line = strtok_r(in, "\n", &saveLinePointer); + firstTime = false; + }else { + line = strtok_r(NULL, "\n", &saveLinePointer); + } + + if (line == NULL){ + break; + } + + parseLine(line, props); + } while(line != NULL); + + free(in); + + return props; +} + /** * Header is ignored for now, cannot handle comments yet http://git-wip-us.apache.org/repos/asf/celix/blob/5c9e52e2/utils/public/include/properties.h ---------------------------------------------------------------------- diff --git a/utils/public/include/properties.h b/utils/public/include/properties.h index cf93ca0..5c6dc4d 100644 --- a/utils/public/include/properties.h +++ b/utils/public/include/properties.h @@ -46,6 +46,8 @@ UTILS_EXPORT properties_pt properties_load(const char *filename); UTILS_EXPORT properties_pt properties_loadWithStream(FILE *stream); +UTILS_EXPORT properties_pt properties_loadFromString(const char *input); + UTILS_EXPORT void properties_store(properties_pt properties, const char *file, const char *header); UTILS_EXPORT const char *properties_get(properties_pt properties, const char *key);
