You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2015/07/31 22:57:36 UTC
[07/10] celix git commit: CELIX-237: moved rsa_http_ffi source to
rsa_dfi
CELIX-237: moved rsa_http_ffi source to rsa_dfi
Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/3d7f7641
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/3d7f7641
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/3d7f7641
Branch: refs/heads/feature/CELIX-237_rsa-ffi
Commit: 3d7f7641fbd58c79b54e00d9d7d1395f54db166c
Parents: bf76d21
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri Jul 31 16:11:31 2015 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri Jul 31 16:11:31 2015 +0200
----------------------------------------------------------------------
.../remote_service_admin_dfi/CMakeLists.txt | 26 +-
.../dynamic_function_interface/CMakeLists.txt | 5 +-
.../include/remote_service_admin_http_impl.h | 52 +
.../src/remote_service_admin_activator.c | 122 ++
.../private/src/remote_service_admin_impl.c | 1085 ++++++++++++++++++
.../CMakeLists.txt | 51 -
.../include/remote_service_admin_http_impl.h | 52 -
.../src/remote_service_admin_activator.c | 122 --
.../private/src/remote_service_admin_impl.c | 1085 ------------------
9 files changed, 1274 insertions(+), 1326 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/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 f74cac1..500e40e 100644
--- a/remote_services/remote_service_admin_dfi/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/CMakeLists.txt
@@ -34,19 +34,19 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI)
include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
- #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_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")
- #bundle(remote_service_admin_dfi SOURCES
- # private/src/remote_service_admin_impl
- # private/src/remote_service_admin_activator
- # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
- # ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
- # ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
- # ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
- #)
- #target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES})
+ bundle(remote_service_admin_dfi SOURCES
+ private/src/remote_service_admin_impl
+ private/src/remote_service_admin_activator
+ ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
+ ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
+ ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
+ ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
+ )
+ target_link_libraries(remote_service_admin_dfi celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES} dfi)
- #install_bundle(remote_service_admin_dfi)
+ install_bundle(remote_service_admin_dfi)
endif (RSA_REMOTE_SERVICE_ADMIN_DFI)
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
index 309176f..ae1d5c3 100644
--- a/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
+++ b/remote_services/remote_service_admin_dfi/dynamic_function_interface/CMakeLists.txt
@@ -18,7 +18,7 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(MEMSTREAM_SOURCES memstream/open_memstream.c memstream/fmemopen.c)
endif()
-add_library(dfi
+add_library(dfi STATIC
dyn_common.c
dyn_type.c
dyn_function.c
@@ -30,14 +30,13 @@ add_library(dfi
target_link_libraries(dfi ${FFI_LIBRARIES} ${JANSSON_LIBRARY})
-#if (FRAMEWORK_TESTS)
+#if (FRAMEWORK_TESTS) TODO
add_executable(dfi_tests
tst/dyn_type_tests.cpp
tst/dyn_function_tests.cpp
tst/dyn_closure_tests.cpp
tst/dyn_interface_tests.cpp
tst/json_serializer_tests.cpp
-# tst/avro_descriptor_translator_tests.cpp
tst/run_tests.cpp
)
target_link_libraries(dfi_tests dfi ${FFI_LIBRARIES} ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY})
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
new file mode 100644
index 0000000..dbf71c9
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/include/remote_service_admin_http_impl.h
@@ -0,0 +1,52 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin_http_impl.h
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
+
+#include "remote_service_admin_impl.h"
+#include "log_helper.h"
+#include "civetweb.h"
+
+struct remote_service_admin {
+ bundle_context_pt context;
+ log_helper_pt loghelper;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ hash_map_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..e4125fc
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_activator.c
@@ -0,0 +1,122 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin_activator.c
+ *
+ * \date Sep 30, 2011
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "service_registration.h"
+
+#include "remote_service_admin_http_impl.h"
+#include "export_registration_impl.h"
+#include "import_registration_impl.h"
+
+struct activator {
+ remote_service_admin_pt admin;
+ remote_service_admin_service_pt adminService;
+ service_registration_pt registration;
+};
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator;
+
+ activator = calloc(1, sizeof(*activator));
+ if (!activator) {
+ status = CELIX_ENOMEM;
+ } else {
+ activator->admin = NULL;
+ activator->registration = NULL;
+
+ *userData = activator;
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+ remote_service_admin_service_pt remoteServiceAdmin = NULL;
+
+ status = remoteServiceAdmin_create(context, &activator->admin);
+ if (status == CELIX_SUCCESS) {
+ remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
+ if (!remoteServiceAdmin) {
+ status = CELIX_ENOMEM;
+ } else {
+ remoteServiceAdmin->admin = activator->admin;
+ remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
+
+ remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
+ remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+ remoteServiceAdmin->importService = remoteServiceAdmin_importService;
+
+ remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+ remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
+
+ remoteServiceAdmin->exportRegistration_close = exportRegistration_close;
+ remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
+ remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+ remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+ remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
+
+ remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
+ remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
+ remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
+
+ status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
+ activator->adminService = remoteServiceAdmin;
+ }
+ }
+
+ return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ remoteServiceAdmin_stop(activator->admin);
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ remoteServiceAdmin_destroy(&activator->admin);
+
+ free(activator->adminService);
+
+ return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ struct activator *activator = userData;
+
+ free(activator);
+
+ return status;
+}
+
+
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
new file mode 100644
index 0000000..ac54e8d
--- /dev/null
+++ b/remote_services/remote_service_admin_dfi/private/src/remote_service_admin_impl.c
@@ -0,0 +1,1085 @@
+/**
+ *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.
+ */
+/*
+ * remote_service_admin_impl.c
+ *
+ * \date May 21, 2015
+ * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ * \copyright Apache License, Version 2.0
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#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 <ffi.h>
+#include <jansson.h>
+
+#include "export_registration_impl.h"
+#include "import_registration_impl.h"
+#include "remote_service_admin_impl.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"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 5
+
+typedef void (*GEN_FUNC_TYPE)(void);
+
+struct generic_service_layout {
+ void *handle;
+ GEN_FUNC_TYPE functions[];
+};
+
+struct proxy {
+ remote_service_admin_pt admin;
+ char *sig;
+ int index;
+ ffi_cif cif;
+ ffi_closure *closure;
+ endpoint_description_pt endpointDescription
+};
+
+
+
+
+
+struct remote_service_admin {
+ bundle_context_pt context;
+ log_helper_pt loghelper;
+
+ celix_thread_mutex_t exportedServicesLock;
+ hash_map_pt exportedServices;
+
+ celix_thread_mutex_t importedServicesLock;
+ hash_map_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+struct post {
+ const char *readptr;
+ int size;
+};
+
+struct get {
+ char *writeptr;
+ int size;
+};
+
+static const char *data_response_headers =
+ "HTTP/1.1 200 OK\r\n"
+ "Cache: no-cache\r\n"
+ "Content-Type: application/json\r\n"
+ "\r\n";
+
+static const char *no_content_response_headers =
+ "HTTP/1.1 204 OK\r\n";
+
+// TODO do we need to specify a non-Amdatu specific configuration type?!
+static const char * const CONFIGURATION_TYPE = "org.amdatu.remote.admin.http";
+static const char * const ENDPOINT_URL = "org.amdatu.remote.admin.http.url";
+
+static const char *DEFAULT_PORT = "8888";
+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_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);
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *admin = calloc(1, sizeof(**admin));
+
+ if (!*admin) {
+ status = CELIX_ENOMEM;
+ } else {
+ unsigned int port_counter = 0;
+ char *port = NULL;
+ char *ip = NULL;
+ char *detectedIp = NULL;
+ (*admin)->context = context;
+ (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+ (*admin)->importedServices = hashMap_create(NULL, NULL, NULL, NULL);
+
+ celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+ if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*admin)->loghelper);
+ }
+
+ bundleContext_getProperty(context, "RSA_PORT", &port);
+ if (port == NULL) {
+ port = (char *)DEFAULT_PORT;
+ }
+
+ bundleContext_getProperty(context, "RSA_IP", &ip);
+ if (ip == NULL) {
+ char *interface = NULL;
+
+ bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+ if ((interface != NULL) && (remoteServiceAdmin_getIpAdress(interface, &detectedIp) != CELIX_SUCCESS)) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: Could not retrieve IP adress for interface %s", interface);
+ }
+
+ if (ip == NULL) {
+ remoteServiceAdmin_getIpAdress(NULL, &detectedIp);
+ }
+
+ ip = detectedIp;
+ }
+
+ if (ip != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Using %s for service annunciation", ip);
+ (*admin)->ip = strdup(ip);
+ }
+ else {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No IP address for service annunciation set. Using %s", DEFAULT_IP);
+ (*admin)->ip = (char*) DEFAULT_IP;
+ }
+
+ if (detectedIp != NULL) {
+ free(detectedIp);
+ }
+
+ // Prepare callbacks structure. We have only one callback, the rest are NULL.
+ struct mg_callbacks callbacks;
+ memset(&callbacks, 0, sizeof(callbacks));
+ callbacks.begin_request = remoteServiceAdmin_callback;
+
+ do {
+ char newPort[10];
+ const char *options[] = { "listening_ports", port, NULL};
+
+ (*admin)->ctx = mg_start(&callbacks, (*admin), options);
+
+ if ((*admin)->ctx != NULL) {
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Start webserver: %s", port);
+ (*admin)->port = strdup(port);
+
+ }
+ else {
+ char* endptr = port;
+ int currentPort = strtol(port, &endptr, 10);
+
+ errno = 0;
+
+ if (*endptr || errno != 0) {
+ currentPort = strtol(DEFAULT_PORT, NULL, 10);
+ }
+
+ port_counter++;
+ snprintf(&newPort[0], 6, "%d", (currentPort+1));
+
+ logHelper_log((*admin)->loghelper, OSGI_LOGSERVICE_ERROR, "Error while starting rsa server on port %s - retrying on port %s...", port, newPort);
+ port = newPort;
+ }
+ } while(((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS));
+
+ }
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ free((*admin)->ip);
+ free((*admin)->port);
+ free(*admin);
+
+ *admin = NULL;
+
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(admin->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ array_list_pt exports = hashMapIterator_nextValue(iter);
+ int i;
+ for (i = 0; i < arrayList_size(exports); i++) {
+ export_registration_pt export = arrayList_get(exports, i);
+ exportRegistration_stopTracking(export);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ iter = hashMapIterator_create(admin->importedServices);
+ while (hashMapIterator_hasNext(iter))
+ {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+
+ import_registration_factory_pt importFactory = hashMapEntry_getValue(entry);
+
+ if (importFactory != NULL) {
+ int i;
+ for (i = 0; i < arrayList_size(importFactory->registrations); i++)
+ {
+ import_registration_pt importRegistration = arrayList_get(importFactory->registrations, i);
+
+ if (importFactory->trackedFactory != NULL)
+ {
+ importFactory->trackedFactory->unregisterProxyService(importFactory->trackedFactory->factory, importRegistration->endpointDescription);
+ }
+ }
+
+ serviceTracker_close(importFactory->proxyFactoryTracker);
+ importRegistrationFactory_close(importFactory);
+
+ hashMapIterator_remove(iter);
+ importRegistrationFactory_destroy(&importFactory);
+ }
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ if (admin->ctx != NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Stopping webserver...");
+ mg_stop(admin->ctx);
+ admin->ctx = NULL;
+ }
+
+ hashMap_destroy(admin->exportedServices, false, false);
+ hashMap_destroy(admin->importedServices, false, false);
+
+ logHelper_stop(admin->loghelper);
+ logHelper_destroy(&admin->loghelper);
+
+ return status;
+}
+
+/**
+ * Request: http://host:port/services/{service}/{request}
+ */
+//void *remoteServiceAdmin_callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info) {
+
+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...
+
+ const struct mg_request_info *request_info = mg_get_request_info(conn);
+ if (request_info->uri != NULL) {
+ remote_service_admin_pt rsa = request_info->user_data;
+
+
+ if (strncmp(request_info->uri, "/service/", 9) == 0 && strcmp("POST", request_info->request_method) == 0) {
+
+ // uri = /services/myservice/call
+ const char *uri = request_info->uri;
+ // rest = myservice/call
+
+ const char *rest = uri+9;
+ char *interfaceStart = strchr(rest, '/');
+ int pos = interfaceStart - rest;
+ char service[pos+1];
+ strncpy(service, rest, pos);
+ service[pos] = '\0';
+ long serviceId = atol(service);
+
+ celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+ //find endpoint
+ export_registration_pt export = NULL;
+ hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ array_list_pt exports = hashMapEntry_getValue(entry);
+ int expIt = 0;
+ for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+ export_registration_pt check = arrayList_get(exports, expIt);
+ if (serviceId == check->endpointDescription->serviceId) {
+ export = check;
+ break;
+ }
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ if (export != NULL) {
+ uint64_t datalength = request_info->content_length;
+ char* data = malloc(datalength + 1);
+ mg_read(conn, data, datalength);
+ data[datalength] = '\0';
+
+ char *response = NULL;
+
+ //FIXME assuming add signature (add(double, double) : double)
+ /*TODO
+ export->endpoint->handleRequest(export->endpoint->endpoint, data, &response);
+ */
+
+
+ //retreive schema.
+ char *schema = NULL;
+ schema = properties_get(export->endpointDescription->properties, "protocol.schema");
+ printf("RSA: got schema %s\n", schema);
+
+
+ printf("Parsing data: %s\n", data);
+ json_error_t error;
+ json_t *js_request = json_loads(data, 0, &error);
+ const char *sig;
+ if (js_request) {
+ if (json_unpack(js_request, "{s:s}", "m", &sig) != 0) {
+ printf("RSA: Got error '%s'\n", error.text);
+ }
+ } else {
+ printf("RSA: got error '%s' for '%s'\n", error.text, data);
+ return 0;
+ }
+
+ printf("RSA: Looking for method %s\n", sig);
+
+ json_t *js_schema = json_loads(schema, 0, &error);
+ int methodIndex = -1;
+ if (js_schema) {
+ //TODO parse schema and create cif
+ size_t index;
+ json_t *value;
+ json_array_foreach(js_schema, index, value) {
+ if (strcmp(sig, json_string_value(value)) == 0) {
+ //found match
+ methodIndex = index;
+ break;
+ }
+ }
+ } else {
+ printf("RSA: got error '%s' for '%s'\n", error.text, schema);
+ return 0;
+ }
+
+ if (methodIndex < 0) {
+ printf("RSA: cannot find method '%s'\n", sig);
+ return 1;
+ }
+
+ size_t sigLength = strlen(sig);
+ char provArgs[sigLength];
+ bool startFound = false;
+ int i = 0;
+ int argIndex = 0;
+ for (; i < sigLength; i += 1) {
+ if (!startFound) {
+ if (sig[i] == '(') {
+ startFound = true;
+ }
+ } else {
+ if (sig[i] != ')') {
+ provArgs[argIndex++] = sig[i];
+ }
+ }
+ }
+ provArgs[argIndex] = '\0';
+ size_t provArgsLength = strlen(provArgs) -1;
+ printf("method index is %i and args are '%s'\n", methodIndex, provArgs);
+
+
+ //FFI part
+ ffi_cif cif;
+ ffi_type *argTypes[provArgsLength + 2]; //e.g. void *handle (extra), double a, double b, double *result (extra)
+ void *valuePointers[provArgsLength + 2];
+ //note assuming doubles!!
+ double values[provArgsLength];
+ double result = 0.0;
+ double *resultPointer = &result;
+ int rvalue = 0;
+
+ argTypes[0] = &ffi_type_pointer;
+ argTypes[provArgsLength +1] = &ffi_type_pointer; //last argument is return value, handled as a pointer
+ for (i = 0; i < provArgsLength; i += 1) {
+ //FIXME for now assuming double as arguments
+ argTypes[i+1] = &ffi_type_double;
+ }
+
+ valuePointers[0] = NULL;
+ valuePointers[provArgsLength+1] = &resultPointer;
+ for (i = 0; i < provArgsLength; i += 1) {
+ values[i] = 0.0;
+ valuePointers[i+1] = &(values[i]);
+ }
+
+ json_t *arguments = json_object_get(js_request, "a");
+ json_t *value;
+ size_t index;
+ json_array_foreach(arguments, index, value) {
+ values[index] = json_real_value(value); //setting values, again assuming double
+ }
+
+ json_decref(js_schema);
+ json_decref(js_request);
+
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, provArgsLength + 2,
+ &ffi_type_sint, argTypes) == FFI_OK)
+ {
+ printf("RSA: FFI PREP OK\n");
+
+ //TRYING TO CALL Calculate service
+ void *service = NULL;
+ bundleContext_getService(rsa->context, export->reference, &service);
+ if (service == NULL) {
+ printf("RSA: Ouch service is NULL\n");
+ return 0;
+ } else {
+ printf("RSA: service ok\n");
+ }
+
+ struct generic_service_layout *serv = service;
+
+ printf("RSA:Trying to call service using ffi\n");
+ valuePointers[0] = serv->handle;
+ ffi_call(&cif, serv->functions[methodIndex], &rvalue, valuePointers);
+ printf("RSA: Done calling service through ffi, got value %f\n", result);
+
+ json_t *resultRoot;
+ resultRoot = json_pack("{s:f}", "r", result);
+ response = json_dumps(resultRoot, 0);
+ json_decref(resultRoot);
+ }
+
+ 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));
+ mg_write(conn, response, strlen(response));
+// mg_send_data(conn, response, strlen(response));
+// mg_write_data(conn, response, strlen(response));
+
+ free(response);
+ } else {
+ mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ }
+ result = 0;
+
+ free(data);
+ } else {
+ //TODO log warning
+ }
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ }
+ }
+
+ return 1;
+}
+
+celix_status_t remoteServiceAdmin_handleRequest(remote_service_admin_pt rsa, char *service, char *data, char **reply) {
+ celixThreadMutex_lock(&rsa->exportedServicesLock);
+
+ hash_map_iterator_pt iter = hashMapIterator_create(rsa->exportedServices);
+ while (hashMapIterator_hasNext(iter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
+ array_list_pt exports = hashMapEntry_getValue(entry);
+ int expIt = 0;
+ for (expIt = 0; expIt < arrayList_size(exports); expIt++) {
+ export_registration_pt export = arrayList_get(exports, expIt);
+ if (strcmp(service, export->endpointDescription->service) == 0) {
+ export->endpoint->handleRequest(export->endpoint->endpoint, data, reply);
+ }
+ }
+ }
+ hashMapIterator_destroy(iter);
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ return CELIX_SUCCESS;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+ celix_status_t status = CELIX_SUCCESS;
+ arrayList_create(registrations);
+ array_list_pt references = NULL;
+ service_reference_pt reference = NULL;
+ char filter [256];
+
+ snprintf(filter, 256, "(%s=%s)", (char *)OSGI_FRAMEWORK_SERVICE_ID, serviceId);
+
+ bundleContext_getServiceReferences(admin->context, NULL, filter, &references); //FIXME not safe
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: exportService called for serviceId %s", serviceId);
+
+ if (arrayList_size(references) >= 1) {
+ reference = arrayList_get(references, 0);
+ }
+
+ if(references!=NULL){
+ arrayList_destroy(references);
+ }
+
+ if (reference == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+ return CELIX_ILLEGAL_STATE;
+ }
+
+ char *exports = NULL;
+ char *provided = NULL;
+ char *schema = NULL;
+ serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+ serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+ serviceReference_getProperty(reference, (char *) "protocol.schema", &schema);
+
+ if (exports == NULL || provided == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ if (schema == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no protocol.schema found.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+
+ char *interface = provided;
+ endpoint_description_pt endpoint = NULL;
+ export_registration_pt registration = NULL;
+
+ remoteServiceAdmin_createEndpointDescription(admin, reference, interface, &endpoint);
+ printf("RSA: Creating export registration with endpoint pointer %p\n", endpoint);
+ exportRegistration_create(admin->loghelper, reference, endpoint, admin, admin->context, ®istration);
+ arrayList_add(*registrations, registration);
+
+ exportRegistration_open(registration);
+ exportRegistration_startTracking(registration);
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ hashMap_put(admin->exportedServices, reference, *registrations);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+ }
+ }
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(export_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ remote_service_admin_pt admin = registration->rsa;
+
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+
+ hashMap_remove(admin->exportedServices, registration->reference);
+
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, char *interface, endpoint_description_pt *endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+ properties_pt endpointProperties = properties_create();
+
+
+ unsigned int size = 0;
+ char **keys;
+
+ serviceReference_getPropertyKeys(reference, &keys, &size);
+ for (int i = 0; i < size; i++) {
+ char *key = keys[i];
+ char *value = NULL;
+
+ if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS
+ && strcmp(key, (char*) OSGI_RSA_SERVICE_EXPORTED_INTERFACES) != 0
+ && strcmp(key, (char*) OSGI_FRAMEWORK_OBJECTCLASS) != 0) {
+ properties_set(endpointProperties, key, value);
+ printf("Added property '%s' with value '%s'\n", key, value);
+ }
+ }
+
+ hash_map_entry_pt entry = hashMap_getEntry(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+
+ char* key = hashMapEntry_getKey(entry);
+ char *serviceId = (char *) hashMap_remove(endpointProperties, (void *) OSGI_FRAMEWORK_SERVICE_ID);
+ char *uuid = NULL;
+
+ char buf[512];
+ snprintf(buf, 512, "/service/%s/%s", serviceId, interface);
+
+ char url[1024];
+ snprintf(url, 1024, "http://%s:%s%s", admin->ip, admin->port, buf);
+
+ uuid_t endpoint_uid;
+ uuid_generate(endpoint_uid);
+ char endpoint_uuid[37];
+ uuid_unparse_lower(endpoint_uid, endpoint_uuid);
+
+ bundleContext_getProperty(admin->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid);
+ properties_set(endpointProperties, (char*) OSGI_FRAMEWORK_OBJECTCLASS, interface);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId);
+ properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid);
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true");
+ properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) CONFIGURATION_TYPE);
+ properties_set(endpointProperties, (char*) ENDPOINT_URL, url);
+
+
+
+ *endpoint = calloc(1, sizeof(**endpoint));
+ if (!*endpoint) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*endpoint)->id = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+ char *serviceId = NULL;
+ serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+ (*endpoint)->frameworkUUID = properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ (*endpoint)->service = interface;
+ (*endpoint)->properties = endpointProperties;
+ }
+
+ free(key);
+ free(serviceId);
+ free(keys);
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_getIpAdress(char* interface, char** ip) {
+ celix_status_t status = CELIX_BUNDLE_EXCEPTION;
+
+ struct ifaddrs *ifaddr, *ifa;
+ char host[NI_MAXHOST];
+
+ if (getifaddrs(&ifaddr) != -1)
+ {
+ for (ifa = ifaddr; ifa != NULL && status != CELIX_SUCCESS; ifa = ifa->ifa_next)
+ {
+ if (ifa->ifa_addr == NULL)
+ continue;
+
+ if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) && (ifa->ifa_addr->sa_family == AF_INET)) {
+ if (interface == NULL) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ else if (strcmp(ifa->ifa_name, interface) == 0) {
+ *ip = strdup(host);
+ status = CELIX_SUCCESS;
+ }
+ }
+ }
+
+ freeifaddrs(ifaddr);
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description)
+{
+ celix_status_t status = CELIX_SUCCESS;
+
+ properties_destroy((*description)->properties);
+ free(*description);
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+
+static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData); //TODO MOVE
+static int remoteServiceAdmin_remoteFunctionProxy(ffi_cif *cif, int *ret, void* args[], void *userData) {
+ void **handle = args[0];
+ remote_service_admin_pt admin = (*handle);
+
+ struct proxy *proxy = userData;
+
+ printf("ffi closure got called for method sig %s with index %i\n", proxy->sig, proxy->index);
+
+ json_t *root = json_object();
+ json_t *sig = json_string(proxy->sig);
+ json_object_set(root, "m", sig);
+
+ json_t *arguments = json_array();
+ int i;
+ for (i = 1; i < proxy->cif.nargs -1; i += 1) {
+ //NOTE assuming double
+ double *dval = args[i];
+ json_t *value = json_real(*dval);
+ json_array_append(arguments, value);
+ }
+ json_object_set(root, "a", arguments);
+
+ char *data = json_dumps(root, 0);
+ char *reply = NULL;
+ int replyStatus;
+
+ remoteServiceAdmin_send(proxy->admin, proxy->endpointDescription, data, &reply, &replyStatus);
+ (*ret) = replyStatus;
+ printf("got reply from server '%s'\n", reply);
+
+ json_error_t error;
+ json_t *js_reply = json_loads(reply, JSON_DECODE_ANY, &error);
+ if (js_reply) {
+ //note assuming double
+ double **result = args[proxy->cif.nargs - 1];
+ json_unpack(js_reply, "{s:f}", "r", *result);
+ json_decref(js_reply);
+ } else {
+ printf("PROXY: got error '%s' for '%s'\n", error.text, reply);
+ }
+
+ json_decref(root);
+
+ free(data);
+ free(reply);
+
+ return 0;
+}
+
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *registration) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+
+ char *schema = properties_get(endpointDescription->properties, "protocol.schema");
+ if (schema == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: protocol schema not found for endpoint\n");
+ return CELIX_SUCCESS;
+ }
+
+ printf("protocol.schema is '%s'\n", schema);
+ json_error_t error;
+ json_t *js_schema = json_loads(schema, 0, &error);
+ if (js_schema) {
+ //TODO parse schema and create cif
+ size_t numOfMethods = json_array_size(js_schema);
+ printf("RSA: num of method for proxy is %i\n", (int) numOfMethods);
+
+ struct generic_service_layout *service = calloc(1, sizeof(*service) + (numOfMethods-1) * sizeof(GEN_FUNC_TYPE));
+ service->handle = admin;
+
+ //struct generic_service_layout {
+ // void *handle;
+ // GEN_FUNC_TYPE functions[];
+ //};
+
+ size_t index;
+ json_t *value;
+ json_array_foreach(js_schema, index, value) {
+ //create closure
+
+ char *sig = json_string_value(value);
+ size_t sigLength = strlen(sig);
+ char provArgs[sigLength];
+ bool startFound = false;
+ int i = 0;
+ int argIndex = 0;
+ for (; i < sigLength; i += 1) {
+ if (!startFound) {
+ if (sig[i] == '(') {
+ startFound = true;
+ }
+ } else {
+ if (sig[i] != ')') {
+ provArgs[argIndex++] = sig[i];
+ }
+ }
+ }
+ provArgs[argIndex] = '\0';
+ printf("method index is %i and args are '%s'\n", index, provArgs);
+
+ int provArgLength = strlen(provArgs) -1;
+
+ struct proxy *proxy = malloc(sizeof(*proxy));
+ proxy->admin = admin;
+ proxy->sig = strdup(sig);
+ proxy->index = index;
+ proxy->endpointDescription = endpointDescription;
+
+ ffi_type **args = calloc(provArgLength +2, sizeof(ffi_type)); //TODO test if this can be on the stack
+
+ void (*function)(void);
+ proxy->closure = ffi_closure_alloc(sizeof(ffi_closure), &function);
+ service->functions[index] = function;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_pointer;
+ args[provArgLength + 1] = &ffi_type_pointer;
+ for (i = 0; i < provArgLength; i += 1) {
+ args[i+1] = &ffi_type_double;
+ }
+
+ if (proxy->closure) {
+ if (ffi_prep_cif(&proxy->cif, FFI_DEFAULT_ABI, provArgLength + 2, &ffi_type_sint, args) == FFI_OK) {
+ if (ffi_prep_closure_loc(proxy->closure, &proxy->cif, remoteServiceAdmin_remoteFunctionProxy, proxy, function) == FFI_OK) {
+ printf("RSA: created closure for method '%s'\n", sig);
+ }
+ }
+ }
+ }
+
+ //TODO register with imported properties
+ char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+ service_registration_pt reg = NULL;
+ bundleContext_registerService(admin->context, objectClass, service, NULL, ®);
+ printf("registered proxy service with objectclass '%s'\n", objectClass);
+
+ } else {
+ printf("RSA: got error '%s' for '%s'\n", error.text, schema);
+ return CELIX_ILLEGAL_STATE;
+ }
+
+
+ //celixThreadMutex_lock(&admin->importedServicesLock);
+ //celixThreadMutex_unlock(&admin->importedServicesLock);
+
+
+ return status;
+ /*
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ import_registration_factory_pt registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
+
+ // check whether we already have a registration_factory registered in the hashmap
+ if (registration_factory == NULL)
+ {
+ status = importRegistrationFactory_install(admin->loghelper, endpointDescription->service, admin->context, ®istration_factory);
+ if (status == CELIX_SUCCESS) {
+ hashMap_put(admin->importedServices, endpointDescription->service, registration_factory);
+ }
+ }
+
+ // factory available
+ if (status != CELIX_SUCCESS || (registration_factory->trackedFactory == NULL))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: no proxyFactory available.");
+ if (status == CELIX_SUCCESS) {
+ status = CELIX_SERVICE_EXCEPTION;
+ }
+ }
+ else
+ {
+ // we create an importRegistration per imported service
+ importRegistration_create(endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send, admin->context, registration);
+ registration_factory->trackedFactory->registerProxyService(registration_factory->trackedFactory->factory, endpointDescription, admin, (sendToHandle) &remoteServiceAdmin_send);
+
+ arrayList_add(registration_factory->registrations, *registration);
+ }
+
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+
+ return status;
+ */
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+ /*
+
+ endpoint_description_pt endpointDescription = (endpoint_description_pt) registration->endpointDescription;
+ import_registration_factory_pt registration_factory = NULL;
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+
+ registration_factory = (import_registration_factory_pt) hashMap_get(admin->importedServices, endpointDescription->service);
+
+ // factory available
+ if ((registration_factory == NULL) || (registration_factory->trackedFactory == NULL))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "RSA: Error while retrieving registration factory for imported service %s", endpointDescription->service);
+ }
+ else
+ {
+ registration_factory->trackedFactory->unregisterProxyService(registration_factory->trackedFactory->factory, endpointDescription);
+ arrayList_removeElement(registration_factory->registrations, registration);
+ importRegistration_destroy(registration);
+
+ if (arrayList_isEmpty(registration_factory->registrations))
+ {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: closing proxy.");
+
+ serviceTracker_close(registration_factory->proxyFactoryTracker);
+ importRegistrationFactory_close(registration_factory);
+
+ hashMap_remove(admin->importedServices, endpointDescription->service);
+
+ importRegistrationFactory_destroy(®istration_factory);
+ }
+ }
+
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ return status;
+ */
+}
+
+
+celix_status_t remoteServiceAdmin_send(remote_service_admin_pt rsa, endpoint_description_pt endpointDescription, char *request, char **reply, int* replyStatus) {
+
+ struct post post;
+ post.readptr = request;
+ post.size = strlen(request);
+
+ struct get get;
+ get.size = 0;
+ get.writeptr = malloc(1);
+
+ char *serviceUrl = properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+ char url[256];
+ snprintf(url, 256, "%s", serviceUrl);
+
+ // assume the default timeout
+ int timeout = DEFAULT_TIMEOUT;
+
+ char *timeoutStr = NULL;
+ // Check if the endpoint has a timeout, if so, use it.
+ timeoutStr = properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT);
+ if (timeoutStr == NULL) {
+ // If not, get the global variable and use that one.
+ bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr);
+ }
+
+ // Update timeout if a property is used to set it.
+ if (timeoutStr != NULL) {
+ timeout = atoi(timeoutStr);
+ }
+
+ celix_status_t status = CELIX_SUCCESS;
+ CURL *curl;
+ CURLcode res;
+
+ curl = curl_easy_init();
+ if(!curl) {
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(curl, CURLOPT_URL, &url[0]);
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, remoteServiceAdmin_readCallback);
+ curl_easy_setopt(curl, CURLOPT_READDATA, &post);
+ 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);
+ res = curl_easy_perform(curl);
+ curl_easy_cleanup(curl);
+
+ *reply = get.writeptr;
+ *replyStatus = res;
+ }
+
+ return status;
+}
+
+static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp) {
+ struct post *post = userp;
+
+ if (post->size) {
+ *(char *) ptr = post->readptr[0];
+ post->readptr++;
+ post->size--;
+ return 1;
+ }
+
+ return 0;
+}
+
+static size_t remoteServiceAdmin_write(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t realsize = size * nmemb;
+ struct get *mem = (struct get *)userp;
+
+ mem->writeptr = realloc(mem->writeptr, mem->size + realsize + 1);
+ if (mem->writeptr == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)");
+ exit(EXIT_FAILURE);
+ }
+
+ memcpy(&(mem->writeptr[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->writeptr[mem->size] = 0;
+
+ return realsize;
+}
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint) {
+ celix_status_t status = CELIX_SUCCESS;
+
+ *endpoint = reference->endpoint;
+
+ return status;
+}
+
+celix_status_t exportReference_getExportedService(export_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
+
+celix_status_t importReference_getImportedService(import_reference_pt reference) {
+ celix_status_t status = CELIX_SUCCESS;
+ return status;
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/CMakeLists.txt b/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
deleted file mode 100644
index 6180ef0..0000000
--- a/remote_services/remote_service_admin_http_ffi/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-celix_subproject(RSA_REMOTE_SERVICE_ADMIN_HTTP "Option to enable building the Remote Service Admin Service HTTP ffi" OFF)
-if (RSA_REMOTE_SERVICE_ADMIN_HTTP)
- find_package(CURL REQUIRED)
- find_package(Jansson REQUIRED)
- find_package(FFI REQUIRED)
-
- include_directories(${FFI_INCLUDE_DIRS})
- include_directories(${CURL_INCLUDE_DIRS})
- include_directories(${JANSSON_INCLUDE_DIRS})
- include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/utils/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/public/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_http/private/include")
- include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
-
- SET_HEADER(BUNDLE_SYMBOLICNAME "apache_celix_remote_service_admin_http_ffi")
- SET(BUNDLE_VERSION "0.0.1")
- SET_HEADERS("Bundle-Name: Apache Celix Remote Service Admin HTTP for ffi")
-
- bundle(remote_service_admin_http SOURCES
- private/src/remote_service_admin_impl
- private/src/remote_service_admin_activator
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/export_registration_impl
- ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/import_registration_impl
- ${PROJECT_SOURCE_DIR}/remote_services/utils/private/src/civetweb.c
- ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c
- )
-
- install_bundle(remote_service_admin_http)
-
- target_link_libraries(remote_service_admin_http celix_framework ${CURL_LIBRARIES} ${JANSSON_LIBRARIES} ${FFI_LIBRARIES})
-endif (RSA_REMOTE_SERVICE_ADMIN_HTTP)
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h b/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
deleted file mode 100644
index dbf71c9..0000000
--- a/remote_services/remote_service_admin_http_ffi/private/include/remote_service_admin_http_impl.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_http_impl.h
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-#define REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_
-
-#include "remote_service_admin_impl.h"
-#include "log_helper.h"
-#include "civetweb.h"
-
-struct remote_service_admin {
- bundle_context_pt context;
- log_helper_pt loghelper;
-
- celix_thread_mutex_t exportedServicesLock;
- hash_map_pt exportedServices;
-
- celix_thread_mutex_t importedServicesLock;
- hash_map_pt importedServices;
-
- char *port;
- char *ip;
-
- struct mg_context *ctx;
-};
-
-celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
-
-#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3d7f7641/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c b/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
deleted file mode 100644
index e4125fc..0000000
--- a/remote_services/remote_service_admin_http_ffi/private/src/remote_service_admin_activator.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements. See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership. The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-/*
- * remote_service_admin_activator.c
- *
- * \date Sep 30, 2011
- * \author <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- * \copyright Apache License, Version 2.0
- */
-#include <stdlib.h>
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
-#include "remote_service_admin_http_impl.h"
-#include "export_registration_impl.h"
-#include "import_registration_impl.h"
-
-struct activator {
- remote_service_admin_pt admin;
- remote_service_admin_service_pt adminService;
- service_registration_pt registration;
-};
-
-celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator;
-
- activator = calloc(1, sizeof(*activator));
- if (!activator) {
- status = CELIX_ENOMEM;
- } else {
- activator->admin = NULL;
- activator->registration = NULL;
-
- *userData = activator;
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
- remote_service_admin_service_pt remoteServiceAdmin = NULL;
-
- status = remoteServiceAdmin_create(context, &activator->admin);
- if (status == CELIX_SUCCESS) {
- remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
- if (!remoteServiceAdmin) {
- status = CELIX_ENOMEM;
- } else {
- remoteServiceAdmin->admin = activator->admin;
- remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
- remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
- remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
- remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
- remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
- remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
- remoteServiceAdmin->exportRegistration_close = exportRegistration_close;
- remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
- remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
- remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
- remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
- remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
- remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
- remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
- status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
- activator->adminService = remoteServiceAdmin;
- }
- }
-
- return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- remoteServiceAdmin_stop(activator->admin);
- serviceRegistration_unregister(activator->registration);
- activator->registration = NULL;
-
- remoteServiceAdmin_destroy(&activator->admin);
-
- free(activator->adminService);
-
- return status;
-}
-
-celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) {
- celix_status_t status = CELIX_SUCCESS;
- struct activator *activator = userData;
-
- free(activator);
-
- return status;
-}
-
-