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 2018/05/27 18:37:13 UTC
[30/51] [partial] celix git commit: CELIX-424: Cleans up the
directory structure. Moves all libraries to the libs subdir and all bundles
to the bundles subdir
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
new file mode 100644
index 0000000..6effc94
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
@@ -0,0 +1,771 @@
+/**
+ *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 <netdb.h>
+#include <ifaddrs.h>
+#include <string.h>
+#include <uuid/uuid.h>
+#include <curl/curl.h>
+
+#include <jansson.h>
+#include "json_serializer.h"
+#include "remote_service_admin.h"
+
+#include "import_registration_dfi.h"
+#include "export_registration_dfi.h"
+#include "remote_service_admin_dfi.h"
+#include "json_rpc.h"
+
+#include "remote_constants.h"
+#include "constants.h"
+#include "civetweb.h"
+
+// defines how often the webserver is restarted (with an increased port number)
+#define MAX_NUMBER_OF_RESTARTS 5
+
+
+#define RSA_LOG_ERROR(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_WARNING(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+#define RSA_LOG_DEBUG(admin, msg, ...) \
+ logHelper_log((admin)->loghelper, OSGI_LOGSERVICE_ERROR, (msg), ##__VA_ARGS__)
+
+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;
+ array_list_pt importedServices;
+
+ char *port;
+ char *ip;
+
+ struct mg_context *ctx;
+};
+
+struct post {
+ const char *readptr;
+ int size;
+};
+
+struct get {
+ char *writeptr;
+ int size;
+};
+
+#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory"
+#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout"
+
+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, properties_pt props, 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, ...);
+
+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;
+ const char *port = NULL;
+ const char *ip = NULL;
+ char *detectedIp = NULL;
+ (*admin)->context = context;
+ (*admin)->exportedServices = hashMap_create(NULL, NULL, NULL, NULL);
+ arrayList_create(&(*admin)->importedServices);
+
+ celixThreadMutex_create(&(*admin)->exportedServicesLock, NULL);
+ celixThreadMutex_create(&(*admin)->importedServicesLock, NULL);
+
+ if (logHelper_create(context, &(*admin)->loghelper) == CELIX_SUCCESS) {
+ logHelper_start((*admin)->loghelper);
+ dynCommon_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynType_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynFunction_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ dynInterface_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonSerializer_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ jsonRpc_logSetup((void *)remoteServiceAdmin_log, *admin, 1);
+ }
+
+ bundleContext_getProperty(context, "RSA_PORT", &port);
+ if (port == NULL) {
+ port = (char *)DEFAULT_PORT;
+ }
+
+ bundleContext_getProperty(context, "RSA_IP", &ip);
+ if (ip == NULL) {
+ const char *interface = NULL;
+
+ bundleContext_getProperty(context, "RSA_INTERFACE", &interface);
+ if ((interface != NULL) && (remoteServiceAdmin_getIpAdress((char*)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 = strdup((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;
+
+ char newPort[10];
+
+ do {
+
+ const char *options[] = { "listening_ports", port, "num_threads", "5", 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 {
+ errno = 0;
+ char* endptr = (char*)port;
+ int currentPort = strtol(port, &endptr, 10);
+
+ 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);
+
+ //TODO destroy exports/imports
+
+ *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);
+ if (export != NULL) {
+ exportRegistration_stop(export);
+ exportRegistration_destroy(export);
+ }
+ }
+ arrayList_destroy(exports);
+ }
+ hashMapIterator_destroy(iter);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ for (i = 0; i < size ; i += 1) {
+ import_registration_pt import = arrayList_get(admin->importedServices, i);
+ if (import != NULL) {
+ importRegistration_stop(import);
+ importRegistration_destroy(import);
+ }
+ }
+ 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);
+ arrayList_destroy(admin->importedServices);
+
+ 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) {
+
+celix_status_t importRegistration_getFactory(import_registration_pt import, service_factory_pt *factory);
+
+static int remoteServiceAdmin_callback(struct mg_connection *conn) {
+ 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) {
+ 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';
+ unsigned long serviceId = strtoul(service,NULL,10);
+
+ 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);
+ export_reference_pt ref = NULL;
+ exportRegistration_getExportReference(check, &ref);
+ endpoint_description_pt checkEndpoint = NULL;
+ exportReference_getExportedEndpoint(ref, &checkEndpoint);
+ if (serviceId == checkEndpoint->serviceId) {
+ export = check;
+ free(ref);
+ break;
+ }
+ free(ref);
+ }
+ }
+ 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;
+ int responceLength = 0;
+ int rc = exportRegistration_call(export, data, -1, &response, &responceLength);
+ if (rc != CELIX_SUCCESS) {
+ RSA_LOG_ERROR(rsa, "Error trying to invoke remove service, got error %i\n", rc);
+ }
+
+ if (rc == CELIX_SUCCESS && response != NULL) {
+ mg_write(conn, data_response_headers, strlen(data_response_headers));
+ mg_write(conn, response, strlen(response));
+ free(response);
+ } else {
+ mg_write(conn, no_content_response_headers, strlen(no_content_response_headers));
+ }
+ result = 1;
+
+ free(data);
+ } else {
+ result = 0;
+ RSA_LOG_WARNING(rsa, "NO export registration found for service id %lu", serviceId);
+ }
+
+ celixThreadMutex_unlock(&rsa->exportedServicesLock);
+
+ }
+ }
+
+ return result;
+}
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations) {
+ celix_status_t status;
+
+ 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);
+
+ status = bundleContext_getServiceReferences(admin->context, NULL, filter, &references);
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: exportService called for serviceId %s", serviceId);
+
+ int i;
+ int size = arrayList_size(references);
+ for (i = 0; i < size; i += 1) {
+ if (i == 0) {
+ reference = arrayList_get(references, i);
+ } else {
+ bundleContext_ungetServiceReference(admin->context, arrayList_get(references, i));
+ }
+ }
+ arrayList_destroy(references);
+
+ if (reference == NULL) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "ERROR: expected a reference for service id %s.", serviceId);
+ status = CELIX_ILLEGAL_STATE;
+ }
+
+ const char *exports = NULL;
+ const char *provided = NULL;
+ if (status == CELIX_SUCCESS) {
+ serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports);
+ serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_OBJECTCLASS, &provided);
+
+ if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_WARNING, "RSA: No Services to export.");
+ status = CELIX_ILLEGAL_STATE;
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Export service (%s)", provided);
+ }
+ }
+
+ if (status == CELIX_SUCCESS) {
+ const char *interface = provided;
+ endpoint_description_pt endpoint = NULL;
+ export_registration_pt registration = NULL;
+
+ remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char*)interface, &endpoint);
+ //TODO precheck if descriptor exists
+ status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, ®istration);
+ if (status == CELIX_SUCCESS) {
+ status = exportRegistration_start(registration);
+ if (status == CELIX_SUCCESS) {
+ arrayList_add(*registrations, registration);
+ }
+ }
+ }
+
+
+ if (status == CELIX_SUCCESS) {
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ hashMap_put(admin->exportedServices, reference, *registrations);
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+ }
+ else{
+ arrayList_destroy(*registrations);
+ *registrations = NULL;
+ }
+
+ return status;
+}
+
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration) {
+ celix_status_t status;
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing exported service");
+
+ export_reference_pt ref = NULL;
+ status = exportRegistration_getExportReference(registration, &ref);
+
+ if (status == CELIX_SUCCESS && ref != NULL) {
+ service_reference_pt servRef;
+ celixThreadMutex_lock(&admin->exportedServicesLock);
+ exportReference_getExportedService(ref, &servRef);
+
+ array_list_pt exports = (array_list_pt)hashMap_remove(admin->exportedServices, servRef);
+ if(exports!=NULL){
+ arrayList_destroy(exports);
+ }
+
+ exportRegistration_close(registration);
+ exportRegistration_destroy(registration);
+
+ celixThreadMutex_unlock(&admin->exportedServicesLock);
+
+ free(ref);
+
+ } else {
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_ERROR, "Cannot find reference for registration");
+ }
+
+ return status;
+}
+
+static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_pt admin, service_reference_pt reference, properties_pt props, 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];
+ const 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);
+ }
+ }
+
+ 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);
+ const 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);
+
+ if (props != NULL) {
+ hash_map_iterator_pt propIter = hashMapIterator_create(props);
+ while (hashMapIterator_hasNext(propIter)) {
+ hash_map_entry_pt entry = hashMapIterator_nextEntry(propIter);
+ properties_set(endpointProperties, (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry));
+ }
+ hashMapIterator_destroy(propIter);
+ }
+
+ *endpoint = calloc(1, sizeof(**endpoint));
+ if (!*endpoint) {
+ status = CELIX_ENOMEM;
+ } else {
+ (*endpoint)->id = (char*)properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID);
+ const char *serviceId = NULL;
+ serviceReference_getProperty(reference, (char*) OSGI_FRAMEWORK_SERVICE_ID, &serviceId);
+ (*endpoint)->serviceId = strtoull(serviceId, NULL, 0);
+ (*endpoint)->frameworkUUID = (char*) properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID);
+ (*endpoint)->service = strndup(interface, 1024*10);
+ (*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)->service);
+ 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;
+}
+
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpointDescription, import_registration_pt *out) {
+ celix_status_t status = CELIX_SUCCESS;
+ import_registration_pt import = NULL;
+
+ const char *objectClass = properties_get(endpointDescription->properties, "objectClass");
+ const char *serviceVersion = properties_get(endpointDescription->properties, (char*) CELIX_FRAMEWORK_SERVICE_VERSION);
+
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA: Import service %s", endpointDescription->service);
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "Registering service factory (proxy) for service '%s'\n", objectClass);
+
+ if (objectClass != NULL) {
+ status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion, &import);
+ }
+ if (status == CELIX_SUCCESS && import != NULL) {
+ importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
+ }
+
+ if (status == CELIX_SUCCESS && import != NULL) {
+ status = importRegistration_start(import);
+ }
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ arrayList_add(admin->importedServices, import);
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ if (status == CELIX_SUCCESS) {
+ *out = import;
+ }
+
+ return status;
+}
+
+
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration) {
+ celix_status_t status = CELIX_SUCCESS;
+ logHelper_log(admin->loghelper, OSGI_LOGSERVICE_INFO, "RSA_DFI: Removing imported service");
+
+ celixThreadMutex_lock(&admin->importedServicesLock);
+ int i;
+ int size = arrayList_size(admin->importedServices);
+ import_registration_pt current = NULL;
+ for (i = 0; i < size; i += 1) {
+ current = arrayList_get(admin->importedServices, i);
+ if (current == registration) {
+ arrayList_remove(admin->importedServices, i);
+ importRegistration_close(current);
+ importRegistration_destroy(current);
+ break;
+ }
+ }
+ celixThreadMutex_unlock(&admin->importedServicesLock);
+
+ return status;
+}
+
+
+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);
+
+ struct get get;
+ get.size = 0;
+ get.writeptr = malloc(1);
+
+ char *serviceUrl = (char*)properties_get(endpointDescription->properties, (char*) ENDPOINT_URL);
+ char url[256];
+ snprintf(url, 256, "%s", serviceUrl);
+
+ // assume the default timeout
+ int timeout = DEFAULT_TIMEOUT;
+
+ const char *timeoutStr = NULL;
+ // Check if the endpoint has a timeout, if so, use it.
+ timeoutStr = (char*) 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_NOSIGNAL, 1);
+ curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
+ curl_easy_setopt(curl, CURLOPT_URL, url);
+ 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);
+ logHelper_log(rsa->loghelper, OSGI_LOGSERVICE_DEBUG, "RSA: Performing curl post\n");
+ res = curl_easy_perform(curl);
+
+ *reply = get.writeptr;
+ *replyStatus = res;
+
+ curl_easy_cleanup(curl);
+ }
+
+ 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;
+}
+
+
+static void remoteServiceAdmin_log(remote_service_admin_pt admin, int level, const char *file, int line, const char *msg, ...) {
+ va_list ap;
+ va_start(ap, msg);
+ int levels[5] = {0, OSGI_LOGSERVICE_ERROR, OSGI_LOGSERVICE_WARNING, OSGI_LOGSERVICE_INFO, OSGI_LOGSERVICE_DEBUG};
+
+ char buf1[256];
+ snprintf(buf1, 256, "FILE:%s, LINE:%i, MSG:", file, line);
+
+ char buf2[256];
+ vsnprintf(buf2, 256, msg, ap);
+ logHelper_log(admin->loghelper, levels[level], "%s%s", buf1, buf2);
+ va_end(ap);
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
new file mode 100644
index 0000000..8b282f1
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.h
@@ -0,0 +1,57 @@
+/**
+ *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 "bundle_context.h"
+#include "endpoint_description.h"
+
+//typedef struct remote_service_admin *remote_service_admin_pt;
+
+celix_status_t remoteServiceAdmin_create(bundle_context_pt context, remote_service_admin_pt *admin);
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_pt *admin);
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+celix_status_t remoteServiceAdmin_exportService(remote_service_admin_pt admin, char *serviceId, properties_pt properties, array_list_pt *registrations);
+celix_status_t remoteServiceAdmin_removeExportedService(remote_service_admin_pt admin, export_registration_pt registration);
+celix_status_t remoteServiceAdmin_getExportedServices(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_pt admin, array_list_pt *services);
+celix_status_t remoteServiceAdmin_importService(remote_service_admin_pt admin, endpoint_description_pt endpoint, import_registration_pt *registration);
+celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_pt admin, import_registration_pt registration);
+
+
+celix_status_t exportReference_getExportedEndpoint(export_reference_pt reference, endpoint_description_pt *endpoint);
+celix_status_t exportReference_getExportedService(export_reference_pt reference, service_reference_pt *service);
+
+celix_status_t importReference_getImportedEndpoint(import_reference_pt reference);
+celix_status_t importReference_getImportedService(import_reference_pt reference);
+
+celix_status_t remoteServiceAdmin_destroyEndpointDescription(endpoint_description_pt *description);
+
+#endif /* REMOTE_SERVICE_ADMIN_HTTP_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt b/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
new file mode 100644
index 0000000..aa10ec3
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/CMakeLists.txt
@@ -0,0 +1,60 @@
+# 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.
+
+find_package(CppUTest REQUIRED)
+include_directories(${CPPUTEST_INCLUDE_DIR})
+
+add_celix_bundle(rsa_dfi_tst_bundle
+ VERSION 0.0.1
+ SOURCES
+ src/tst_activator.c
+)
+get_target_property(DESCR calculator_api INTERFACE_CALCULATOR_DESCRIPTOR)
+celix_bundle_files(rsa_dfi_tst_bundle ${DESCR} DESTINATION .)
+target_link_libraries(rsa_dfi_tst_bundle PRIVATE ${CPPUTEST_LIBRARY} calculator_api)
+target_include_directories(rsa_dfi_tst_bundle PRIVATE src)
+
+add_executable(test_rsa_dfi
+ src/run_tests.cpp
+ src/rsa_tests.cpp
+ src/rsa_client_server_tests.cpp
+)
+target_include_directories(test_rsa_dfi PRIVATE src)
+target_link_libraries(test_rsa_dfi PRIVATE ${CURL_LIBRARIES} ${CPPUTEST_LIBRARY}
+ Celix::framework
+ Celix::rsa_common
+ calculator_api)
+
+get_property(rsa_bundle_file TARGET rsa_dfi PROPERTY BUNDLE_FILE)
+get_property(calc_bundle_file TARGET calculator PROPERTY BUNDLE_FILE)
+get_property(calculator_shell_bundle_file TARGET calculator_shell PROPERTY BUNDLE_FILE)
+get_property(discovery_configured_bundle_file TARGET rsa_discovery_configured PROPERTY BUNDLE_FILE)
+get_property(topology_manager_bundle_file TARGET Celix::rsa_topology_manager PROPERTY BUNDLE_FILE)
+get_property(tst_bundle_file TARGET rsa_dfi_tst_bundle PROPERTY BUNDLE_FILE)
+
+configure_file(config.properties.in config.properties)
+configure_file(client.properties.in client.properties)
+configure_file(server.properties.in server.properties)
+
+add_dependencies(test_rsa_dfi
+ rsa_dfi_bundle #note depend on the target creating the bundle zip not the lib target
+ calculator_bundle
+)
+
+add_test(NAME run_test_rsa_dfi COMMAND test_rsa_dfi)
+SETUP_TARGET_FOR_COVERAGE(test_rsa_dfi_cov test_rsa_dfi ${CMAKE_BINARY_DIR}/coverage/test_rsa_dfi/test_rsa_dfi)
+
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/client.properties.in
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/client.properties.in b/bundles/remote_services/remote_service_admin_dfi/test/client.properties.in
new file mode 100644
index 0000000..a9a06fb
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/client.properties.in
@@ -0,0 +1,8 @@
+cosgi.auto.start.1=@rsa_bundle_file@ @calculator_shell_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@ @tst_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+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/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/config.properties.in
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/config.properties.in b/bundles/remote_services/remote_service_admin_dfi/test/config.properties.in
new file mode 100644
index 0000000..5776ad8
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/config.properties.in
@@ -0,0 +1,20 @@
+# 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.
+
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+org.osgi.framework.storage.clean=onFirstInit
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in b/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
new file mode 100644
index 0000000..707c7e6
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/server.properties.in
@@ -0,0 +1,23 @@
+# 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.
+cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@
+LOGHELPER_ENABLE_STDOUT_FALLBACK=true
+RSA_PORT=50882
+DISCOVERY_CFG_SERVER_PORT=50992
+org.osgi.framework.storage.clean=onFirstInit
+org.osgi.framework.storage=.cacheServer
+DISCOVERY_CFG_POLL_INTERVAL=1
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
new file mode 100644
index 0000000..528e6b7
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_client_server_tests.cpp
@@ -0,0 +1,133 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <remote_constants.h>
+#include <constants.h>
+#include <tst_service.h>
+#include "CppUTest/CommandLineTestRunner.h"
+#include "calculator_service.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "celix_launcher.h"
+#include "framework.h"
+#include "remote_service_admin.h"
+#include "calculator_service.h"
+
+ static framework_pt serverFramework = NULL;
+ static bundle_context_pt serverContext = NULL;
+
+ static framework_pt clientFramework = NULL;
+ static bundle_context_pt clientContext = NULL;
+
+ static void setupFm(void) {
+ int rc = 0;
+ bundle_pt bundle = NULL;
+
+ //server
+ rc = celixLauncher_launch("server.properties", &serverFramework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle = NULL;
+ rc = framework_getFrameworkBundle(serverFramework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &serverContext);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+
+ //client
+ rc = celixLauncher_launch("client.properties", &clientFramework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle = NULL;
+ rc = framework_getFrameworkBundle(clientFramework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &clientContext);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ }
+
+ static void teardownFm(void) {
+ celixLauncher_stop(serverFramework);
+ celixLauncher_waitForShutdown(serverFramework);
+ celixLauncher_destroy(serverFramework);
+
+ celixLauncher_stop(clientFramework);
+ celixLauncher_waitForShutdown(clientFramework);
+ celixLauncher_destroy(clientFramework);
+
+ serverContext = NULL;
+ serverFramework = NULL;
+ clientContext = NULL;
+ clientFramework = NULL;
+ }
+
+ static void test1(void) {
+ celix_status_t rc;
+ service_reference_pt ref = NULL;
+ tst_service_pt tst = NULL;
+ int retries = 4;
+
+ while (ref == NULL && retries > 0) {
+ printf("Waiting for service .. %d\n", retries);
+ rc = bundleContext_getServiceReference(clientContext, (char *) TST_SERVICE_NAME, &ref);
+ usleep(1000000);
+ --retries;
+ }
+
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(ref != NULL);
+
+ rc = bundleContext_getService(clientContext, ref, (void **)&tst);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(tst != NULL);
+
+ rc = tst->test(tst->handle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bool result;
+ bundleContext_ungetService(clientContext, ref, &result);
+ bundleContext_ungetServiceReference(clientContext, ref);
+ }
+
+}
+
+
+TEST_GROUP(RsaDfiClientServerTests) {
+ void setup() {
+ setupFm();
+ }
+
+ void teardown() {
+ teardownFm();
+ }
+};
+
+TEST(RsaDfiClientServerTests, Test1) {
+ test1();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
new file mode 100644
index 0000000..6026ac6
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/rsa_tests.cpp
@@ -0,0 +1,234 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include <remote_constants.h>
+#include <constants.h>
+#include "CppUTest/CommandLineTestRunner.h"
+#include "calculator_service.h"
+
+extern "C" {
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "celix_launcher.h"
+#include "framework.h"
+#include "remote_service_admin.h"
+#include "calculator_service.h"
+
+
+ static framework_pt framework = NULL;
+ static bundle_context_pt context = NULL;
+
+ static service_reference_pt rsaRef = NULL;
+ static remote_service_admin_service_pt rsa = NULL;
+
+ static service_reference_pt calcRef = NULL;
+ static calculator_service_pt calc = NULL;
+
+ static void setupFm(void) {
+ int rc = 0;
+
+ rc = celixLauncher_launch("config.properties", &framework);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ bundle_pt bundle = NULL;
+ rc = framework_getFrameworkBundle(framework, &bundle);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundle_getContext(bundle, &context);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(rsaRef != NULL);
+
+ rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_getServiceReference(context, (char *)CALCULATOR2_SERVICE, &calcRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(calcRef != NULL);
+
+ rc = bundleContext_getService(context, calcRef, (void **)&calc);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ }
+
+ static void teardownFm(void) {
+ int rc = 0;
+ rc = bundleContext_ungetService(context, rsaRef, NULL);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetServiceReference(context, rsaRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetService(context, calcRef, NULL);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = bundleContext_ungetServiceReference(context, calcRef);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ celixLauncher_stop(framework);
+ celixLauncher_waitForShutdown(framework);
+ celixLauncher_destroy(framework);
+
+ rsaRef = NULL;
+ rsa = NULL;
+ calcRef = NULL;
+ calc = NULL;
+ context = NULL;
+ framework = NULL;
+ }
+
+ static void testServices(void) {
+ int rc = 0;
+ array_list_pt exported = NULL;
+ array_list_pt imported = NULL;
+ arrayList_create(&exported);
+ arrayList_create(&imported);
+
+ rc = rsa->getExportedServices(rsa->admin, &exported);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(0, arrayList_size(exported));
+
+ rc = rsa->getImportedEndpoints(rsa->admin, &imported);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(0, arrayList_size(imported));
+
+ double result = 0;
+ rc = calc->add(calc->calculator, 2.0, 5.0, &result);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK_EQUAL(7.0, result);
+
+ arrayList_destroy(imported);
+ arrayList_destroy(exported);
+ }
+
+ static void testExportService(void) {
+ int rc = 0;
+ const char *calcId = NULL;
+ array_list_pt regs = NULL;
+
+ rc = serviceReference_getProperty(calcRef, (char *)"service.id", &calcId);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = rsa->exportService(rsa->admin, (char*)calcId, NULL, ®s);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ CHECK_EQUAL(1, arrayList_size(regs));
+
+ rc = rsa->exportRegistration_close(rsa->admin,(export_registration_pt)(arrayList_get(regs,0)));
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ }
+
+ static void testImportService(void) {
+ int rc = 0;
+ import_registration_pt reg = NULL;
+ endpoint_description_pt endpoint = NULL;
+
+ properties_pt props = properties_create();
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_SERVICE_ID, (char *)"42");
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42");
+ properties_set(props, (char *)OSGI_RSA_ENDPOINT_ID, (char *)"eec5404d-51d0-47ef-8d86-c825a8beda42-42");
+ properties_set(props, (char *)OSGI_FRAMEWORK_OBJECTCLASS,(char *)"org.apache.celix.Example");
+ properties_set(props, (char *)"service.version",(char *)"1.0.0"); //TODO find out standard in osgi spec
+
+ rc = endpointDescription_create(props, &endpoint);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = rsa->importService(rsa->admin, endpoint, ®);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(reg != NULL);
+
+ service_reference_pt ref = NULL;
+ rc = bundleContext_getServiceReference(context, (char *)"org.apache.celix.Example", &ref);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(ref != NULL);
+
+ rc = bundleContext_ungetServiceReference(context, ref);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ rc = endpointDescription_destroy(endpoint);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+
+ /* Cannot test. uses requesting bundles descriptor
+ void *service = NULL;
+ rc = bundleContext_getService(context, ref, &service);
+ CHECK_EQUAL(CELIX_SUCCESS, rc);
+ CHECK(service != NULL);
+ */
+ }
+
+ static void testBundles(void) {
+ array_list_pt bundles = NULL;
+
+ int rc = bundleContext_getBundles(context, &bundles);
+ CHECK_EQUAL(0, rc);
+ CHECK_EQUAL(3, arrayList_size(bundles)); //framework, rsa_dfi & calc
+
+ /*
+ int size = arrayList_size(bundles);
+ int i;
+ for (i = 0; i < size; i += 1) {
+ bundle_pt bundle = NULL;
+ module_pt module = NULL;
+ char *name = NULL;
+
+ bundle = (bundle_pt) arrayList_get(bundles, i);
+ bundle_getCurrentModule(bundle, &module);
+ module_getSymbolicName(module, &name);
+ printf("got bundle with symbolic name '%s'", name);
+ }*/
+
+ arrayList_destroy(bundles);
+ }
+
+}
+
+
+TEST_GROUP(RsaDfiTests) {
+ void setup() {
+ setupFm();
+ }
+
+ void teardown() {
+ teardownFm();
+ }
+};
+
+TEST(RsaDfiTests, InfoTest) {
+ testServices();
+}
+
+TEST(RsaDfiTests, ExportService) {
+ testExportService();
+}
+
+TEST(RsaDfiTests, ImportService) {
+ testImportService();
+}
+
+TEST(RsaDfiTests, TestBundles) {
+ testBundles();
+}
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp b/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
new file mode 100644
index 0000000..b5fd502
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/run_tests.cpp
@@ -0,0 +1,25 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <CppUTest/TestHarness.h>
+#include "CppUTest/CommandLineTestRunner.h"
+
+int main(int argc, char** argv) {
+ return RUN_ALL_TESTS(argc, argv);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
new file mode 100644
index 0000000..3db38fb
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_activator.c
@@ -0,0 +1,162 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <service_tracker_customizer.h>
+#include <service_tracker.h>
+
+#include "bundle_activator.h"
+#include "bundle_context.h"
+#include "service_registration.h"
+#include "service_reference.h"
+#include "celix_errno.h"
+
+#include "tst_service.h"
+#include "calculator_service.h"
+#include <unistd.h>
+
+
+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 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;
+ struct activator *act = calloc(1, sizeof(*act));
+ if (act != NULL) {
+ 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;
+
+ 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;
+}
+
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) {
+ celix_status_t status = CELIX_SUCCESS;
+ 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) {
+ struct activator *act = userData;
+ if (act != NULL) {
+ if (act->tracker != NULL) {
+ serviceTracker_destroy(act->tracker);
+ act->tracker = NULL;
+ }
+ free(act);
+ }
+ return CELIX_SUCCESS;
+}
+
+static int test(void *handle) {
+ int status = 0;
+ struct activator *act = handle;
+
+ double result = -1.0;
+
+ int retries = 40;
+
+ while (act->calc == NULL) {
+ printf("Waiting for calc service .. %d\n", retries);
+ usleep(100000);
+ --retries;
+ }
+
+ int rc = 1;
+ if (act->calc != NULL) {
+ rc = act->calc->sqrt(act->calc->calculator, 4, &result);
+ printf("calc result is %f\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/3bce889b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
new file mode 100644
index 0000000..c8ca2e7
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_dfi/test/src/tst_service.h
@@ -0,0 +1,32 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements. See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership. The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_TST_SERVICE_H
+#define CELIX_TST_SERVICE_H
+
+#define TST_SERVICE_NAME "tst_service"
+
+struct tst_service {
+ void *handle;
+ int (*test)(void *handle);
+};
+
+typedef struct tst_service *tst_service_pt;
+
+#endif //CELIX_TST_SERVICE_H
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_shm/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_shm/CMakeLists.txt b/bundles/remote_services/remote_service_admin_shm/CMakeLists.txt
new file mode 100644
index 0000000..11cda6a
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_shm/CMakeLists.txt
@@ -0,0 +1,56 @@
+# 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_SHM "Option to enable building the Remote Service Admin Service SHM bundle" OFF)
+if (RSA_REMOTE_SERVICE_ADMIN_SHM)
+ link_directories("/opt/local/lib")
+ include_directories("/opt/local/include")
+ include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/framework/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/framework/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_shm/public/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin_shm/private/include")
+ include_directories("${PROJECT_SOURCE_DIR}/remote_services/endpoint_listener/public/include")
+
+ add_celix_bundle(remote_service_admin_shm
+ VERSION 0.9.0
+ SYMBOLIC_NAME "apache_celix_remote_service_admin_shm"
+ NAME "Apache Celix Remote Service Admin SHM"
+ 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}/log_service/public/src/log_helper.c
+ )
+ target_link_libraries(remote_service_admin_shm celix_framework)
+
+ install_celix_bundle(remote_service_admin_shm EXPORT celix COMPONENT rsa)
+ add_library(Celix::remote_service_admin_shm ALIAS remote_service_admin_shm)
+
+ if (ENABLE_TESTING)
+ find_package(CppUTest REQUIRED)
+ include_directories(${CPPUTEST_INCLUDE_DIR})
+ add_subdirectory(private/test)
+ endif()
+
+endif (RSA_REMOTE_SERVICE_ADMIN_SHM)
+
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h b/bundles/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h
new file mode 100644
index 0000000..1f88e8f
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_shm/private/include/remote_service_admin_shm_impl.h
@@ -0,0 +1,92 @@
+/**
+ *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_shm_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_SHM_IMPL_H_
+#define REMOTE_SERVICE_ADMIN_SHM_IMPL_H_
+
+#include "remote_service_admin_impl.h"
+#include "log_helper.h"
+
+#define RSA_SHM_MEMSIZE 1310720
+#define RSA_SHM_PATH_PROPERTYNAME "shmPath"
+#define RSA_SEM_PATH_PROPERTYNAME "semPath"
+#define RSA_SHM_FTOK_ID_PROPERTYNAME "shmFtokId"
+#define RSA_SEM_FTOK_ID_PROPERTYNAME "semFtokId"
+#define RSA_SHM_DEFAULTPATH "/dev/null"
+#define RSA_SEM_DEFAULTPATH "/dev/null"
+#define RSA_SHM_DEFAULT_FTOK_ID "52"
+#define RSA_SEM_DEFAULT_FTOK_ID "54"
+
+#define RSA_FILEPATH_LENGTH 255
+
+/** Define P_tmpdir if not defined (this is normally a POSIX symbol) */
+#ifndef P_tmpdir
+#define P_tmpdir "/tmp"
+#endif
+
+union semun {
+ int val; /* Value for SETVAL */
+ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
+ unsigned short *array; /* Array for GETALL, SETALL */
+ struct seminfo *__buf; /* Buffer for IPC_INFO */
+};
+
+struct recv_shm_thread {
+ remote_service_admin_pt admin;
+ endpoint_description_pt endpointDescription;
+};
+
+struct ipc_segment {
+ int semId;
+ int shmId;
+ void *shmBaseAdress;
+};
+
+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;
+
+ hash_map_pt exportedIpcSegment;
+ hash_map_pt importedIpcSegment;
+
+ hash_map_pt pollThread;
+ hash_map_pt pollThreadRunning;
+
+ struct mg_context *ctx;
+};
+
+typedef struct recv_shm_thread *recv_shm_thread_pt;
+typedef struct ipc_segment *ipc_segment_pt;
+
+celix_status_t remoteServiceAdmin_stop(remote_service_admin_pt admin);
+
+#endif /* REMOTE_SERVICE_ADMIN_SHM_IMPL_H_ */
http://git-wip-us.apache.org/repos/asf/celix/blob/3bce889b/bundles/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c
----------------------------------------------------------------------
diff --git a/bundles/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c b/bundles/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c
new file mode 100644
index 0000000..a2b72d0
--- /dev/null
+++ b/bundles/remote_services/remote_service_admin_shm/private/src/remote_service_admin_activator.c
@@ -0,0 +1,123 @@
+/**
+ *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_shm_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;
+ 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 = remoteServiceAdmin_removeExportedService;
+ 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;
+
+ serviceRegistration_unregister(activator->registration);
+ activator->registration = NULL;
+
+ remoteServiceAdmin_stop(activator->admin);
+
+ 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;
+}
+
+