Repository: celix Updated Branches: refs/heads/feature/CELIX-237_rsa-ffi fa527209f -> 7dc2039f1
CELIX-237: Implemented client server test and needed changes to get that working. There is still an issue in the export_registration Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/7dc2039f Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/7dc2039f Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/7dc2039f Branch: refs/heads/feature/CELIX-237_rsa-ffi Commit: 7dc2039f11b6fc3505ce2677ad2a59bfdb423d1f Parents: fa52720 Author: Pepijn Noltes <pepijnnol...@gmail.com> Authored: Tue Aug 11 20:18:15 2015 +0200 Committer: Pepijn Noltes <pepijnnol...@gmail.com> Committed: Tue Aug 11 20:18:15 2015 +0200 ---------------------------------------------------------------------- launcher/private/src/main.c | 8 +- remote_services/CMakeLists.txt | 1 + .../remote_service_admin_dfi/CMakeLists.txt | 2 +- .../dynamic_function_interface/dyn_function.c | 2 + .../dynamic_function_interface/dyn_type.c | 16 +-- .../json_serializer.c | 6 +- .../json_serializer.h | 1 + .../tst/dyn_function_tests.cpp | 7 +- .../private/include/import_registration_dfi.h | 5 + .../private/src/export_registration_dfi.c | 81 ++++++++--- .../private/src/import_registration_dfi.c | 135 ++++++++++++++++--- .../private/src/remote_service_admin_dfi.c | 38 ++---- .../remote_service_admin_dfi/tst/CMakeLists.txt | 4 +- .../tst/bundle/CMakeLists.txt | 5 + .../tst/bundle/tst_activator.c | 86 +++++++++--- .../tst/bundle/tst_service.h | 2 +- .../tst/client.properties.in | 1 + .../tst/rsa_client_server_tests.cpp | 19 +-- .../tst/server.properties.in | 1 + 19 files changed, 296 insertions(+), 124 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/launcher/private/src/main.c ---------------------------------------------------------------------- diff --git a/launcher/private/src/main.c b/launcher/private/src/main.c index 82530e1..90e5612 100644 --- a/launcher/private/src/main.c +++ b/launcher/private/src/main.c @@ -63,9 +63,11 @@ int main(int argc, char *argv[]) { // Set signal handler (void) signal(SIGINT, shutdown_framework); - celixLauncher_launch(config_file, &framework); - celixLauncher_waitForShutdown(framework); - celixLauncher_destroy(framework); + int rc = celixLauncher_launch(config_file, &framework); + if (rc == 0) { + celixLauncher_waitForShutdown(framework); + celixLauncher_destroy(framework); + } } static void show_usage(char* prog_name) { http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/CMakeLists.txt b/remote_services/CMakeLists.txt index abc9177..f39b604 100644 --- a/remote_services/CMakeLists.txt +++ b/remote_services/CMakeLists.txt @@ -39,6 +39,7 @@ if (REMOTE_SERVICE_ADMIN) add_subdirectory(remote_service_admin) add_subdirectory(remote_service_admin_http) + add_subdirectory(remote_service_admin_dfi/tst/bundle) add_subdirectory(remote_service_admin_dfi) add_subdirectory(remote_service_admin_shm) http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/CMakeLists.txt b/remote_services/remote_service_admin_dfi/CMakeLists.txt index b7a66f3..83dfc41 100644 --- a/remote_services/remote_service_admin_dfi/CMakeLists.txt +++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt @@ -44,7 +44,7 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI) SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi") SET(BUNDLE_VERSION "0.0.1") - SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for dynamic function interface") + SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin Dynamic Function Interface (DFI)") bundle(remote_service_admin_dfi SOURCES private/src/remote_service_admin_dfi.c http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c index f80d26f..af3902c 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_function.c @@ -10,6 +10,7 @@ #include <stdlib.h> #include <ffi.h> +#include <ffi-x86_64.h> #include "dyn_common.h" #include "dyn_type.h" @@ -222,6 +223,7 @@ int dynFunction_createClosure(dyn_function_type *dynFunc, void (*bind)(void *, v } if (status == 0) { + dynFunc->userData = userData; dynFunc->bind = bind; dynFunc->fn = fn; *out =fn; http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c index c8a9adb..e47fe6d 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/dyn_type.c @@ -5,11 +5,6 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> -#include <ctype.h> #include <assert.h> #include <errno.h> @@ -763,6 +758,7 @@ static ffi_type * dynType_ffiTypeFor(int c) { break; case 'P' : type = &ffi_type_pointer; + break; case 'V' : type = &ffi_type_void; break; @@ -864,16 +860,6 @@ int dynType_text_allocAndInit(dyn_type *type, void *textLoc, const char *value) - - - - - - - - - - void dynType_print(dyn_type *type, FILE *stream) { if (type != NULL) { dynType_printTypes(type, stream); http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c index c6bda91..cf9a0ee 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.c @@ -237,7 +237,7 @@ int jsonSerializer_serialize(dyn_type *type, void *input, char **output) { int status = OK; json_t *root = NULL; - status = jsonSerializer_writeAny(type, input, &root); + status = jsonSerializer_serializeJson(type, input, &root); if (status == OK) { *output = json_dumps(root, JSON_COMPACT); @@ -247,6 +247,10 @@ int jsonSerializer_serialize(dyn_type *type, void *input, char **output) { return status; } +int jsonSerializer_serializeJson(dyn_type *type, void *input, json_t **out) { + return jsonSerializer_writeAny(type, input, out); +} + static int jsonSerializer_writeAny(dyn_type *type, void *input, json_t **out) { int status = OK; http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h index abfdd03..9999aea 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/json_serializer.h @@ -15,5 +15,6 @@ int jsonSerializer_deserialize(dyn_type *type, const char *input, void **result) int jsonSerializer_deserializeJson(dyn_type *type, json_t *input, void **result); int jsonSerializer_serialize(dyn_type *type, void *input, char **output); +int jsonSerializer_serializeJson(dyn_type *type, void *input, json_t **out); #endif http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp index 868073b..006897c 100644 --- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp +++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/tst/dyn_function_tests.cpp @@ -128,7 +128,6 @@ extern "C" { CHECK_EQUAL(2.0, *b) CHECK_EQUAL(a, 2.0); *out = *b * a; - printf("out is %p and *out is %f\n", out, *out); return 0; } @@ -140,8 +139,6 @@ extern "C" { CHECK_EQUAL(0, rc); double result = -1.0; double *input = &result; - printf("\n"); - printf("input is %p, &input is %p and *input is %d\n", input, &input, *input); double a = 2.0; void *ptr = &a; void *args[3]; @@ -150,8 +147,8 @@ extern "C" { args[2] = &input; void (*fp)(void) = (void(*)(void)) testExample3; - rc = dynFunction_call(dynFunc, fp, &result, args); - printf("input is %p, &input is %p and *input is %d\n", input, &input, *input); + int rVal; + rc = dynFunction_call(dynFunc, fp, &rVal, args); CHECK_EQUAL(0, rc); CHECK_EQUAL(4.0, result); http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h b/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h index d05375d..ec885fd 100644 --- a/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h +++ b/remote_services/remote_service_admin_dfi/private/include/import_registration_dfi.h @@ -8,9 +8,14 @@ #include <celix_errno.h> +typedef void (*send_func_type)(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus); + celix_status_t importRegistration_create(bundle_context_pt context, endpoint_description_pt description, const char *classObject, import_registration_pt *import); void importRegistration_destroy(import_registration_pt import); +celix_status_t importRegistration_setSendFn(import_registration_pt reg, + send_func_type, + void *handle); celix_status_t importRegistration_start(import_registration_pt import); celix_status_t importRegistration_stop(import_registration_pt import); http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c index 95d58b9..0713efb 100644 --- a/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/private/src/export_registration_dfi.c @@ -7,7 +7,6 @@ #include <remote_constants.h> #include "export_registration.h" #include "export_registration_dfi.h" -#include "endpoint_description.h" struct export_reference { endpoint_description_pt endpoint; //owner @@ -24,15 +23,17 @@ struct export_registration { bool closed; }; +typedef void (*gen_func_type)(void); + struct generic_service_layout { void *handle; - void **methods; + gen_func_type methods[]; }; celix_status_t exportRegistration_create(log_helper_pt helper, service_reference_pt reference, endpoint_description_pt endpoint, bundle_context_pt context, export_registration_pt *out) { celix_status_t status = CELIX_SUCCESS; - export_registration_pt reg = calloc(1, sizeof(*reg)); + export_registration_pt reg = calloc(1, sizeof(*reg)); if (reg == NULL) { status = CELIX_ENOMEM; @@ -90,7 +91,7 @@ celix_status_t exportRegistration_create(log_helper_pt helper, service_reference return status; } -celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **response, int *responseLength) { +celix_status_t exportRegistration_call(export_registration_pt export, char *data, int datalength, char **responseOut, int *responseLength) { int status = CELIX_SUCCESS; //TODO lock/sema export @@ -122,21 +123,26 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data if (method == NULL) { status = CELIX_ILLEGAL_STATE; + } else { + printf("RSA: found method '%s'\n", entry->id); } if (method != NULL) { int nrOfArgs = dynFunction_nrOfArguments(method->dynFunc); - void *args[nrOfArgs + 1]; //arg 0 is handle - dyn_type *returnType = dynFunction_returnType(method->dynFunc); + void *args[nrOfArgs]; //arg 0 is handle json_t *arguments = json_object_get(js_request, "a"); - json_t *value; - size_t index; + json_t *value = NULL; + int index = -1; json_array_foreach(arguments, index, value) { - dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, index + 1); - status = jsonSerializer_deserializeJson(argType, value, &(args[index + 1])); - index += 1; + int argNr = index + 1; + if (argNr < nrOfArgs -1 ) { //note skip last argument. this is the output + dyn_type *argType = dynFunction_argumentTypeForIndex(method->dynFunc, argNr); + status = jsonSerializer_deserializeJson(argType, value, &(args[argNr])); + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } if (status != 0) { break; } @@ -144,21 +150,56 @@ celix_status_t exportRegistration_call(export_registration_pt export, char *data json_decref(js_request); + struct generic_service_layout *serv = export->service; - args[0] = serv->handle; - void *returnVal = NULL; - dynType_alloc(returnType, &returnVal); - dynFunction_call(method->dynFunc, serv->methods[method->index], returnVal, args); - - status = jsonSerializer_serialize(returnType, returnVal, response); - if (returnVal != NULL) { - dynType_free(returnType, returnVal); - } + args[0] = &serv->handle; + + //TODO assert last is output pointer (e.g. double pointer) + dyn_type *lastTypePtr = dynFunction_argumentTypeForIndex(method->dynFunc, nrOfArgs-1); + dyn_type *lastType = NULL; + dynType_typedPointer_getTypedType(lastTypePtr, &lastType); + + + void *out = NULL; + dynType_alloc(lastType, &out); //TODO, NOTE only for simple types or single pointer types.. TODO check + printf("out ptr is %p value is %f\n", out, *(double *)out); + args[nrOfArgs-1] = &out; //NOTE for simple type no double + + printf("args is %p %p %p\n", args[0] , args[1], args[2]); + printf("args derefs is %p %p %p\n", *(void **)args[0], *(void **)args[1], *(void **)args[2]); + + //TODO assert return type is native int + int returnVal = 0; + //printf("calling function '%s', with index %i, nrOfArgs %i and at loc %p\n", method->id, method->index, nrOfArgs, serv->methods[method->index]); + dynFunction_call(method->dynFunc, serv->methods[method->index], (void *)&returnVal, args); + //printf("done calling\n"); + //printf("args is %p %p %p\n", args[0] , args[1], args[2]); + //printf("args derefs is %p %p %p\n", *(void **)args[0], *(void **)args[1], *(void **)args[2]); + //printf("out is %p and val is %f\n", out, *(double *)out); + + json_t *responseJson = NULL; + //double r = 2.0; + //status = jsonSerializer_serializeJson(lastOutputType, &r /*out*/, &responseJson); + printf("out ptr is %p, value is %f\n", out, *(double *)out); + status = jsonSerializer_serializeJson(lastType, out, &responseJson); + + json_t *payload = json_object(); + json_object_set_new(payload, "r", responseJson); + + char *response = json_dumps(payload, JSON_DECODE_ANY); + json_decref(payload); + + + *responseOut = response; + *responseLength = -1; + + //TODO free args (created by jsonSerializer and dynType_alloc) (dynType_free) ///TODO add more status checks } //TODO unlock/sema export + printf("done export reg call\n"); return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c index 4e424a8..985d94d 100644 --- a/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c +++ b/remote_services/remote_service_admin_dfi/private/src/import_registration_dfi.c @@ -1,4 +1,6 @@ #include <stdlib.h> +#include <jansson.h> +#include "json_serializer.h" #include "dyn_interface.h" #include "import_registration.h" #include "import_registration_dfi.h" @@ -7,6 +9,8 @@ struct import_registration { bundle_context_pt context; endpoint_description_pt endpoint; //TODO owner? -> free when destroyed const char *classObject; //NOTE owned by endpoint + send_func_type send; + void *sendHandle; service_factory_pt factory; service_registration_pt factoryReg; @@ -47,14 +51,30 @@ celix_status_t importRegistration_create(bundle_context_pt context, endpoint_des } if (status == CELIX_SUCCESS) { + printf("IMPORT REGISTRATION IS %p\n", reg); *out = reg; } return status; } + +celix_status_t importRegistration_setSendFn(import_registration_pt reg, + send_func_type send, + void *handle) { + reg->send = send; + reg->sendHandle = handle; + + return CELIX_SUCCESS; +} + void importRegistration_destroy(import_registration_pt import) { if (import != NULL) { + if (import->proxies != NULL) { + //TODO destroy proxies + hashMap_destroy(import->proxies, false, false); + import->proxies = NULL; + } if (import->factory != NULL) { free(import->factory); } @@ -93,7 +113,6 @@ celix_status_t importRegistration_getService(import_registration_pt import, bund printf("getting service for bundle '%s'\n", name); */ - struct service_proxy *proxy = hashMap_get(import->proxies, bundle); //TODO lock if (proxy == NULL) { status = importRegistration_createProxy(import, bundle, &proxy); @@ -117,16 +136,17 @@ static celix_status_t importRegistration_createProxy(import_registration_pt impo char name[128]; snprintf(name, 128, "%s.descriptor", import->classObject); status = bundle_getEntry(bundle, name, &descriptorFile); - if (status != CELIX_SUCCESS) { + if (descriptorFile == NULL) { printf("Cannot find entry '%s'\n", name); + status = CELIX_ILLEGAL_ARGUMENT; + } else { + printf("Found descriptor at '%s'\n", descriptorFile); } struct service_proxy *proxy = NULL; if (status == CELIX_SUCCESS) { proxy = calloc(1, sizeof(*proxy)); - if (proxy != NULL) { - - } else { + if (proxy == NULL) { status = CELIX_ENOMEM; } } @@ -142,16 +162,23 @@ static celix_status_t importRegistration_createProxy(import_registration_pt impo } } - void **serv = NULL; + if (status == CELIX_SUCCESS) { size_t count = dynInterface_nrOfMethods(proxy->intf); - serv = calloc(1 + count, sizeof(void *)); - serv[0] = proxy; + proxy->service = calloc(1 + count, sizeof(void *)); + if (proxy->service == NULL) { + status = CELIX_ENOMEM; + } + } + + if (status == CELIX_SUCCESS) { + void **serv = proxy->service; + serv[0] = import; struct methods_head *list = NULL; dynInterface_methods(proxy->intf, &list); struct method_entry *entry = NULL; - void (*fn)(void); + void (*fn)(void) = NULL; int index = 0; TAILQ_FOREACH(entry, list, entries) { int rc = dynFunction_createClosure(entry->dynFunc, importRegistration_proxyFunc, entry, &fn); @@ -166,31 +193,102 @@ static celix_status_t importRegistration_createProxy(import_registration_pt impo } if (status == CELIX_SUCCESS) { - proxy->service = serv; + *out = proxy; } else { - if (serv != NULL) { - free(serv); + if (proxy->intf != NULL) { + dynInterface_destroy(proxy->intf); + proxy->intf = NULL; + } + if (proxy->service != NULL) { + free(proxy->service); + proxy->service = NULL; + } + if (proxy != NULL) { + free(proxy); } - } - - if (status == CELIX_SUCCESS) { - *out = proxy; } return status; } static void importRegistration_proxyFunc(void *userData, void *args[], void *returnVal) { + int status = CELIX_SUCCESS; struct method_entry *entry = userData; - //struct proxy_service *proxy = args[0]; printf("Calling function '%s'\n", entry->id); + json_t *invoke = json_object(); + json_object_set(invoke, "m", json_string(entry->id)); + + json_t *jsonArgs = json_array(); + json_object_set(invoke, "a", jsonArgs); + json_decref(jsonArgs); + + int i; + int nrOfArgs = dynFunction_nrOfArguments(entry->dynFunc); + import_registration_pt import = *((void **)args[0]); + + for (i = 1; i < nrOfArgs -1; i +=1) { //note 0 = handle, last = output + json_t *val = NULL; + dyn_type *type = dynFunction_argumentTypeForIndex(entry->dynFunc, i); + int rc = jsonSerializer_serializeJson(type, args[i], &val); + if (rc == 0) { + json_array_append_new(jsonArgs, val); + } else { + status = CELIX_ILLEGAL_ARGUMENT; + break; + } + } - //TODO + + char *output = json_dumps(invoke, JSON_DECODE_ANY); + printf("Need to send following json '%s'\n", output); + + printf("import is %p\n", import); + if (import != NULL && import->send != NULL) { + char *reply = NULL; + int rc = 0; + printf("sending request\n"); + import->send(import->sendHandle, import->endpoint, output, &reply, &rc); + printf("request sended. got reply '%s'\n", reply); + + json_t *replyJson = json_loads(reply, JSON_DECODE_ANY, NULL); //TODO check + json_t *result = json_object_get(replyJson, "r"); //TODO check + + printf("replyJson p is %p and result is %p\n", replyJson, result); + + if (rc == 0) { + dyn_type *lastPtr = dynFunction_argumentTypeForIndex(entry->dynFunc, nrOfArgs - 1); + dyn_type *lastType = NULL; + dynType_typedPointer_getTypedType(lastPtr, &lastType); + if (rc == CELIX_SUCCESS) { + void *tmp = NULL; + rc = jsonSerializer_deserializeJson(lastType, result, &tmp); + void **out = (void **)args[nrOfArgs-1]; + memcpy(*out, tmp, dynType_size(lastType)); + dynType_free(lastType, tmp); //TODO only for simple types -> eg complex type will be alloc by callee + } + json_decref(replyJson); + + int *returnInt = returnVal; + *returnInt = status; + + printf("done with proxy func\n"); + } + } else { + printf("Error import of import->send is NULL\n"); + } + + json_decref(invoke); } celix_status_t importRegistration_ungetService(import_registration_pt import, bundle_pt bundle, service_registration_pt registration, void **out) { celix_status_t status = CELIX_SUCCESS; + return status; + + /* TODO fix. gives segfault in framework shutdown (import->proxies == NULL) + assert(import != NULL); + assert(import->proxies != NULL); + struct service_proxy *proxy = hashMap_get(import->proxies, bundle); //TODO lock if (proxy != NULL) { if (*out == proxy->service) { @@ -203,6 +301,7 @@ celix_status_t importRegistration_ungetService(import_registration_pt import, bu importRegistration_destroyProxy(proxy); } } + */ return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c index 5e11c3b..c78cc19 100644 --- a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c +++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_dfi.c @@ -27,16 +27,11 @@ #include <stdlib.h> #include <arpa/inet.h> -#include <sys/socket.h> #include <netdb.h> #include <ifaddrs.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> #include <string.h> #include <uuid/uuid.h> #include <curl/curl.h> -#include <sys/queue.h> #include <jansson.h> @@ -47,19 +42,7 @@ #include "remote_service_admin.h" #include "remote_constants.h" #include "constants.h" -#include "utils.h" -#include "bundle_context.h" -#include "bundle.h" -#include "service_reference.h" -#include "service_registration.h" -#include "log_helper.h" -#include "log_service.h" -#include "celix_threads.h" #include "civetweb.h" -#include "log_helper.h" -#include "endpoint_description.h" -#include "dyn_interface.h" -#include "json_serializer.h" // defines how often the webserver is restarted (with an increased port number) #define MAX_NUMBER_OF_RESTARTS 5 @@ -112,11 +95,9 @@ static const char *DEFAULT_IP = "127.0.0.1"; static const unsigned int DEFAULT_TIMEOUT = 0; static int remoteServiceAdmin_callback(struct mg_connection *conn); - static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *description); - +static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus); static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip); - static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp); static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp); static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...); @@ -296,7 +277,7 @@ celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) { celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory); static int remoteServiceAdmin_callback(struct mg_connection *conn) { - int result = 0; // zero means: let civetweb handle it further, any non-zero value means it is handled by us... + int result = 1; // zero means: let civetweb handle it further, any non-zero value means it is handled by us... const struct mg_request_info *request_info = mg_get_request_info(conn); if (request_info->uri != NULL) { @@ -355,6 +336,7 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) { if (response != NULL) { mg_write(conn, data_response_headers, strlen(data_response_headers)); // mg_write(conn, no_content_response_headers, strlen(no_content_response_headers)); + printf("writing response '%s'\n", response); mg_write(conn, response, strlen(response)); // mg_send_data(conn, response, strlen(response)); // mg_write_data(conn, response, strlen(response)); @@ -363,10 +345,11 @@ static int remoteServiceAdmin_callback(struct mg_connection *conn) { } else { mg_write(conn, no_content_response_headers, strlen(no_content_response_headers)); } - result = 0; + result = 1; free(data); } else { + result = 0; //TODO log warning } @@ -597,6 +580,9 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, e if (objectClass != NULL) { status = importRegistration_create(admin->context, endpointDescription, objectClass, &import); } + if (status == CELIX_SUCCESS) { + importRegistration_setSendFn(import, remoteServiceAdmin_send, admin); + } if (status == CELIX_SUCCESS) { status = importRegistration_start(import); @@ -657,8 +643,8 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt } -celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) { - +static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) { + remote_service_admin_pt rsa = handle; struct post post; post.readptr = request; post.size = strlen(request); @@ -703,11 +689,13 @@ celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_des 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"); res = curl_easy_perform(curl); - curl_easy_cleanup(curl); *reply = get.writeptr; *replyStatus = res; + + curl_easy_cleanup(curl); } return status; http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt index a184d21..d21fb89 100644 --- a/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt +++ b/remote_services/remote_service_admin_dfi/tst/CMakeLists.txt @@ -5,8 +5,6 @@ #TODO add FRAMEWORK_TEST / TEST check #if (RSA_EXAMPLES) - add_subdirectory(bundle) - include_directories( ${PROJECT_SOURCE_DIR}/launcher/public/include ${CPPUTEST_INCLUDE_DIR} @@ -27,7 +25,7 @@ ${PROJECT_SOURCE_DIR}/launcher/private/src/launcher.c #TODO move to libframework ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c ) - target_link_libraries(test_rsa_dfi celix_framework celix_utils ${CURL_LIBRARIES}) + target_link_libraries(test_rsa_dfi celix_framework celix_utils ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY}) get_property(rsa_bundle_file TARGET remote_service_admin_dfi PROPERTY BUNDLE) get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE) http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/bundle/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/bundle/CMakeLists.txt b/remote_services/remote_service_admin_dfi/tst/bundle/CMakeLists.txt index e1d4fb3..b91ebf1 100644 --- a/remote_services/remote_service_admin_dfi/tst/bundle/CMakeLists.txt +++ b/remote_services/remote_service_admin_dfi/tst/bundle/CMakeLists.txt @@ -7,8 +7,13 @@ include_directories( ${CPPUTEST_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/framework/public/include ${PROJECT_SOURCE_DIR}/utils/public/include + ${PROJECT_SOURCE_DIR}/remote_services/examples/calculator_service/public/include ) +SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_dfi_tst_bundle") +SET(BUNDLE_VERSION "0.0.1") +SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin DFI test bundle") + bundle(rsa_dfi_tst_bundle SOURCES http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/bundle/tst_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/bundle/tst_activator.c b/remote_services/remote_service_admin_dfi/tst/bundle/tst_activator.c index 9b16e65..728030e 100644 --- a/remote_services/remote_service_admin_dfi/tst/bundle/tst_activator.c +++ b/remote_services/remote_service_admin_dfi/tst/bundle/tst_activator.c @@ -4,6 +4,8 @@ #include <stdlib.h> #include <string.h> #include <assert.h> +#include <service_tracker_customizer.h> +#include <service_tracker.h> #include "bundle_activator.h" #include "bundle_context.h" @@ -19,9 +21,15 @@ struct activator { bundle_context_pt context; struct tst_service serv; service_registration_pt reg; + + service_tracker_customizer_pt cust; + service_tracker_pt tracker; + calculator_service_pt calc; }; -static void test(void *handle); +static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service); +static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service); +static int test(void *handle); celix_status_t bundleActivator_create(bundle_context_pt context, void **out) { celix_status_t status = CELIX_SUCCESS; @@ -30,17 +38,48 @@ celix_status_t bundleActivator_create(bundle_context_pt context, void **out) { act->context = context; act->serv.handle = act; act->serv.test = test; + + status = serviceTrackerCustomizer_create(act, NULL, addCalc, NULL, removeCalc, &act->cust); + status = CELIX_DO_IF(status, serviceTracker_create(context, CALCULATOR2_SERVICE, act->cust, &act->tracker)); + } else { status = CELIX_ENOMEM; } if (status == CELIX_SUCCESS) { *out = act; + } else if (act != NULL) { + if (act->cust != NULL) { + free(act->cust); + act->cust = NULL; + } + if (act->tracker != NULL) { + serviceTracker_destroy(act->tracker); + act->tracker = NULL; + } + free(act); } return CELIX_SUCCESS; } +static celix_status_t addCalc(void * handle, service_reference_pt reference, void * service) { + celix_status_t status = CELIX_SUCCESS; + struct activator * act = handle; + act->calc = service; + return status; +} + +static celix_status_t removeCalc(void * handle, service_reference_pt reference, void * service) { + celix_status_t status = CELIX_SUCCESS; + struct activator * act = handle; + if (act->calc == service) { + act->calc = NULL; + } + return status; + +} + celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { celix_status_t status = CELIX_SUCCESS; struct activator * act = userData; @@ -48,6 +87,9 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) act->reg = NULL; status = bundleContext_registerService(context, (char *)TST_SERVICE_NAME, &act->serv, NULL, &act->reg); + status = CELIX_DO_IF(status, serviceTracker_open(act->tracker)); + + return status; } @@ -57,35 +99,39 @@ celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) struct activator * act = userData; status = serviceRegistration_unregister(act->reg); + status = CELIX_DO_IF(status, serviceTracker_close(act->tracker)); return status; } celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { - free(userData); + struct activator *act = userData; + if (act != NULL) { + if (act->tracker != NULL) { + serviceTracker_destroy(act->tracker); + act->tracker = NULL; + } + free(act); + } return CELIX_SUCCESS; } -static void test(void *handle) { +static int test(void *handle) { + int status = 0; struct activator *act = handle; - bundle_context_pt context = act->context; - //TODO improve. don't use asserts. - - int rc = 0; - service_reference_pt ref = NULL; - calculator_service_pt calc = NULL; - - rc = bundleContext_getServiceReference(context, (char *)CALCULATOR2_SERVICE, &ref); - assert(rc == 0); - - rc = bundleContext_getService(context, ref, (void **)&calc); - assert(rc == 0); double result = 0.0; - rc = calc->sqrt(calc->calculator, 4, &result); - assert(rc == 0); - assert(result == 2); - bundleContext_ungetService(context, ref, NULL); - bundleContext_ungetServiceReference(context, ref); + int rc; + if (act->calc != NULL) { + rc = act->calc->sqrt(act->calc->calculator, 4, &result); + printf("calc result is %d\n", result); + } else { + printf("calc not ready\n"); + } + + if (rc != 0 || result != 2.0) { + status = 1; + } + return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/bundle/tst_service.h ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/bundle/tst_service.h b/remote_services/remote_service_admin_dfi/tst/bundle/tst_service.h index 2fc2b21..2678b0c 100644 --- a/remote_services/remote_service_admin_dfi/tst/bundle/tst_service.h +++ b/remote_services/remote_service_admin_dfi/tst/bundle/tst_service.h @@ -9,7 +9,7 @@ struct tst_service { void *handle; - void (*test)(void *handle); + int (*test)(void *handle); }; typedef struct tst_service *tst_service_pt; http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/client.properties.in ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/client.properties.in b/remote_services/remote_service_admin_dfi/tst/client.properties.in index 9cde4bd..a9a06fb 100644 --- a/remote_services/remote_service_admin_dfi/tst/client.properties.in +++ b/remote_services/remote_service_admin_dfi/tst/client.properties.in @@ -4,4 +4,5 @@ RSA_PORT=50881 DISCOVERY_CFG_SERVER_PORT=50991 DISCOVERY_CFG_POLL_ENDPOINTS=http://127.0.0.1:50992/org.apache.celix.discovery.configured org.osgi.framework.storage.clean=onFirstInit +org.osgi.framework.storage=.cacheClient DISCOVERY_CFG_POLL_INTERVAL=1 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/rsa_client_server_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/rsa_client_server_tests.cpp b/remote_services/remote_service_admin_dfi/tst/rsa_client_server_tests.cpp index 5ffb47a..35beffe 100644 --- a/remote_services/remote_service_admin_dfi/tst/rsa_client_server_tests.cpp +++ b/remote_services/remote_service_admin_dfi/tst/rsa_client_server_tests.cpp @@ -4,6 +4,7 @@ #include <CppUTest/TestHarness.h> #include <remote_constants.h> #include <constants.h> +#include <tst_service.h> #include "CppUTest/CommandLineTestRunner.h" #include "../../examples/calculator_service/public/include/calculator_service.h" @@ -74,30 +75,24 @@ extern "C" { static void test1(void) { int rc = 0; - /* TODO use tst_service for (which has a descriptor file of the calculator service) service_reference_pt ref = NULL; - calculator_service_pt calc = NULL; + tst_service_pt tst = NULL; - usleep(5000000); //needed to accept connection (firewall) + usleep(2000000); //TODO use tracker - bundleContext_getServiceReference(clientContext, (char *)CALCULATOR2_SERVICE, &ref); + bundleContext_getServiceReference(clientContext, (char *)TST_SERVICE_NAME, &ref); CHECK_EQUAL(0, rc); CHECK(ref != NULL); - //NOTE will not work. using framework context. need to use calc client context (lookup bundle / create own?) - - bundleContext_getService(clientContext, ref, (void **)&calc); + bundleContext_getService(clientContext, ref, (void **)&tst); CHECK_EQUAL(0, rc); - CHECK(calc != NULL); + CHECK(tst != NULL); - double result = 0.0; - rc = calc->sqrt(calc->calculator, 4, &result); + rc = tst->test(tst->handle); CHECK_EQUAL(0, rc); - CHECK(result == 2.0); bundleContext_ungetService(clientContext, ref, NULL); bundleContext_ungetServiceReference(clientContext, ref); - */ } } http://git-wip-us.apache.org/repos/asf/celix/blob/7dc2039f/remote_services/remote_service_admin_dfi/tst/server.properties.in ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_dfi/tst/server.properties.in b/remote_services/remote_service_admin_dfi/tst/server.properties.in index f75bf24..ea02519 100644 --- a/remote_services/remote_service_admin_dfi/tst/server.properties.in +++ b/remote_services/remote_service_admin_dfi/tst/server.properties.in @@ -4,4 +4,5 @@ RSA_PORT=50882 DISCOVERY_CFG_SERVER_PORT=50992 DISCOVERY_CFG_POLL_ENDPOINTS=http://127.0.0.1:50991/org.apache.celix.discovery.configured org.osgi.framework.storage.clean=onFirstInit +org.osgi.framework.storage=.cacheServer DISCOVERY_CFG_POLL_INTERVAL=1 \ No newline at end of file