CELIX-239: add serviceTracker for endpointListener, changed order of discovery service registration
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2fb7b063 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2fb7b063 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2fb7b063 Branch: refs/heads/feature/CELIX-237_rsa-ffi Commit: 2fb7b063485e73567a4106372b59dee3fac73933 Parents: e2598c1 Author: Bjoern Petri <bpe...@apache.org> Authored: Mon Jun 8 22:56:05 2015 +0200 Committer: Bjoern Petri <bpe...@apache.org> Committed: Mon Jun 8 22:56:05 2015 +0200 ---------------------------------------------------------------------- .../discovery/private/src/discovery_activator.c | 27 +- .../private/include/topology_manager.h | 5 + .../topology_manager/private/src/activator.c | 295 ++--- .../private/src/topology_manager.c | 1049 ++++++++++-------- 4 files changed, 751 insertions(+), 625 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/2fb7b063/remote_services/discovery/private/src/discovery_activator.c ---------------------------------------------------------------------- diff --git a/remote_services/discovery/private/src/discovery_activator.c b/remote_services/discovery/private/src/discovery_activator.c index 73e5029..fe843e2 100644 --- a/remote_services/discovery/private/src/discovery_activator.c +++ b/remote_services/discovery/private/src/discovery_activator.c @@ -112,23 +112,11 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) logHelper_log(activator->loghelper, OSGI_LOGSERVICE_DEBUG, "using scope %s.", scope); - endpoint_listener_pt endpointListener = malloc(sizeof(struct endpoint_listener)); - - if (!endpointListener) { - return CELIX_ENOMEM; - } - - endpointListener->handle = activator->discovery; - endpointListener->endpointAdded = discovery_endpointAdded; - endpointListener->endpointRemoved = discovery_endpointRemoved; properties_pt props = properties_create(); properties_set(props, "DISCOVERY", "true"); properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); - status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); - - activator->endpointListener = endpointListener; if (status == CELIX_SUCCESS) { status = serviceTracker_open(activator->endpointListenerTracker); @@ -138,6 +126,21 @@ celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) status = discovery_start(activator->discovery); } + if (status == CELIX_SUCCESS) { + endpoint_listener_pt endpointListener = calloc(1, sizeof(struct endpoint_listener)); + + if (endpointListener) { + endpointListener->handle = activator->discovery; + endpointListener->endpointAdded = discovery_endpointAdded; + endpointListener->endpointRemoved = discovery_endpointRemoved; + + status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); + + if (status == CELIX_SUCCESS) { + activator->endpointListener = endpointListener; + } + } + } // We can release the scope, as properties_set makes a copy of the key & value... free(scope); http://git-wip-us.apache.org/repos/asf/celix/blob/2fb7b063/remote_services/topology_manager/private/include/topology_manager.h ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/private/include/topology_manager.h b/remote_services/topology_manager/private/include/topology_manager.h index 1ae5313..f0f9884 100644 --- a/remote_services/topology_manager/private/include/topology_manager.h +++ b/remote_services/topology_manager/private/include/topology_manager.h @@ -43,6 +43,11 @@ celix_status_t topologyManager_rsaAdded(void *handle, service_reference_pt refer celix_status_t topologyManager_rsaModified(void *handle, service_reference_pt reference, void *service); celix_status_t topologyManager_rsaRemoved(void *handle, service_reference_pt reference, void *service); +celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service); +celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service); +celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void* service); +celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void* service); + celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event); celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter); http://git-wip-us.apache.org/repos/asf/celix/blob/2fb7b063/remote_services/topology_manager/private/src/activator.c ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/private/src/activator.c b/remote_services/topology_manager/private/src/activator.c index 39441b0..a23a9b0 100644 --- a/remote_services/topology_manager/private/src/activator.c +++ b/remote_services/topology_manager/private/src/activator.c @@ -40,184 +40,215 @@ #include "log_helper.h" struct activator { - bundle_context_pt context; + bundle_context_pt context; - topology_manager_pt manager; + topology_manager_pt manager; - service_tracker_pt remoteServiceAdminTracker; - service_listener_pt serviceListener; + service_tracker_pt endpointListenerTracker; + service_tracker_pt remoteServiceAdminTracker; + service_listener_pt serviceListener; - endpoint_listener_pt endpointListener; - service_registration_pt endpointListenerService; + endpoint_listener_pt endpointListener; + service_registration_pt endpointListenerService; - listener_hook_service_pt hookService; - service_registration_pt hook; + listener_hook_service_pt hookService; + service_registration_pt hook; - log_helper_pt loghelper; + log_helper_pt loghelper; }; + +static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker); static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker); static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener); celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = NULL; - - activator = malloc(sizeof(struct activator)); - - if (!activator) { - return CELIX_ENOMEM; - } - - activator->context = context; - activator->endpointListenerService = NULL; - activator->hook = NULL; - activator->manager = NULL; - activator->remoteServiceAdminTracker = NULL; - activator->serviceListener = NULL; - - logHelper_create(context, &activator->loghelper); - logHelper_start(activator->loghelper); - - status = topologyManager_create(context, activator->loghelper, &activator->manager); - if (status == CELIX_SUCCESS) { - status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker); - if (status == CELIX_SUCCESS) { - status = bundleActivator_createServiceListener(activator, &activator->serviceListener); - if (status == CELIX_SUCCESS) { - *userData = activator; - } - } - } - - return status; + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = NULL; + + activator = malloc(sizeof(struct activator)); + + if (!activator) { + return CELIX_ENOMEM; + } + + activator->context = context; + activator->endpointListenerService = NULL; + activator->endpointListenerTracker = NULL; + activator->hook = NULL; + activator->manager = NULL; + activator->remoteServiceAdminTracker = NULL; + activator->serviceListener = NULL; + + logHelper_create(context, &activator->loghelper); + logHelper_start(activator->loghelper); + + status = topologyManager_create(context, activator->loghelper, &activator->manager); + if (status == CELIX_SUCCESS) { + status = bundleActivator_createEPLTracker(activator, &activator->endpointListenerTracker); + if (status == CELIX_SUCCESS) { + status = bundleActivator_createRSATracker(activator, &activator->remoteServiceAdminTracker); + if (status == CELIX_SUCCESS) { + status = bundleActivator_createServiceListener(activator, &activator->serviceListener); + if (status == CELIX_SUCCESS) { + *userData = activator; + } + } + } + } + + return status; } -static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) { - celix_status_t status = CELIX_SUCCESS; +static celix_status_t bundleActivator_createEPLTracker(struct activator *activator, service_tracker_pt *tracker) { + celix_status_t status; - service_tracker_customizer_pt customizer = NULL; + service_tracker_customizer_pt customizer = NULL; - status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, - topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer); + status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified, + topologyManager_endpointListenerRemoved, &customizer); - if (status == CELIX_SUCCESS) { - status = serviceTracker_create(activator->context, "remote_service_admin", customizer, tracker); - } + if (status == CELIX_SUCCESS) { + status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker); + } - return status; + return status; } -static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) { - celix_status_t status = CELIX_SUCCESS; - - *listener = malloc(sizeof(**listener)); - if (!*listener) { - return CELIX_ENOMEM; - } - - (*listener)->handle = activator->manager; - (*listener)->serviceChanged = topologyManager_serviceChanged; - - return status; -} - -celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - - endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener)); - endpointListener->handle = activator->manager; - endpointListener->endpointAdded = topologyManager_addImportedService; - endpointListener->endpointRemoved = topologyManager_removeImportedService; - activator->endpointListener = endpointListener; - - char *uuid = NULL; - status = bundleContext_getProperty(activator->context, (char *)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid); - if (!uuid) { - logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!"); - return CELIX_ILLEGAL_STATE; - } - - size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); - char *scope = malloc(len); - if (!scope) { - return CELIX_ENOMEM; - } +static celix_status_t bundleActivator_createRSATracker(struct activator *activator, service_tracker_pt *tracker) { + celix_status_t status = CELIX_SUCCESS; - snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + service_tracker_customizer_pt customizer = NULL; - logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope); + status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer); - properties_pt props = properties_create(); - properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); + if (status == CELIX_SUCCESS) { + status = serviceTracker_create(activator->context, "remote_service_admin", customizer, tracker); + } - // We can release the scope, as properties_set makes a copy of the key & value... - free(scope); + return status; +} - bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); +static celix_status_t bundleActivator_createServiceListener(struct activator *activator, service_listener_pt *listener) { + celix_status_t status = CELIX_SUCCESS; - listener_hook_service_pt hookService = malloc(sizeof(*hookService)); - hookService->handle = activator->manager; - hookService->added = topologyManager_listenerAdded; - hookService->removed = topologyManager_listenerRemoved; - activator->hookService = hookService; + *listener = malloc(sizeof(**listener)); + if (!*listener) { + return CELIX_ENOMEM; + } - bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook); + (*listener)->handle = activator->manager; + (*listener)->serviceChanged = topologyManager_serviceChanged; - bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)"); - serviceTracker_open(activator->remoteServiceAdminTracker); + return status; +} - array_list_pt references = NULL; - bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references); - int i; - for (i = 0; i < arrayList_size(references); i++) { - service_reference_pt reference = arrayList_get(references, i); +celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + endpoint_listener_pt endpointListener = malloc(sizeof(*endpointListener)); + endpointListener->handle = activator->manager; + endpointListener->endpointAdded = topologyManager_addImportedService; + endpointListener->endpointRemoved = topologyManager_removeImportedService; + activator->endpointListener = endpointListener; + + char *uuid = NULL; + status = bundleContext_getProperty(activator->context, (char *) OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid); + if (!uuid) { + logHelper_log(activator->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!"); + return CELIX_ILLEGAL_STATE; + } + + size_t len = 14 + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); + char *scope = malloc(len); + if (!scope) { + return CELIX_ENOMEM; + } + + snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", OSGI_FRAMEWORK_OBJECTCLASS, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + + logHelper_log(activator->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope); + + properties_pt props = properties_create(); + properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); + + // We can release the scope, as properties_set makes a copy of the key & value... + free(scope); + + bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); + + listener_hook_service_pt hookService = malloc(sizeof(*hookService)); + hookService->handle = activator->manager; + hookService->added = topologyManager_listenerAdded; + hookService->removed = topologyManager_listenerRemoved; + activator->hookService = hookService; + + bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook); + bundleContext_addServiceListener(context, activator->serviceListener, "(service.exported.interfaces=*)"); + + if (status == CELIX_SUCCESS) { + serviceTracker_open(activator->remoteServiceAdminTracker); + } + + if (status == CELIX_SUCCESS) { + status = serviceTracker_open(activator->endpointListenerTracker); + } + + array_list_pt references = NULL; + bundleContext_getServiceReferences(context, NULL, "(service.exported.interfaces=*)", &references); + int i; + for (i = 0; i < arrayList_size(references); i++) { + service_reference_pt reference = arrayList_get(references, i); char *serviceId = NULL; status = CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *)OSGI_FRAMEWORK_SERVICE_ID, &serviceId)); status = CELIX_DO_IF(status, topologyManager_addExportedService(activator->manager, reference, serviceId)); - } + } - arrayList_destroy(references); + arrayList_destroy(references); - return status; + return status; } celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; + celix_status_t status = CELIX_SUCCESS; + struct activator *activator = userData; + + if (serviceTracker_close(activator->endpointListenerTracker) == CELIX_SUCCESS) { + serviceTracker_destroy(activator->endpointListenerTracker); + } - serviceTracker_close(activator->remoteServiceAdminTracker); - serviceTracker_destroy(activator->remoteServiceAdminTracker); + if (serviceTracker_close(activator->remoteServiceAdminTracker) == CELIX_SUCCESS) { + serviceTracker_destroy(activator->remoteServiceAdminTracker); + } - bundleContext_removeServiceListener(context, activator->serviceListener); - free(activator->serviceListener); + bundleContext_removeServiceListener(context, activator->serviceListener); + free(activator->serviceListener); - serviceRegistration_unregister(activator->hook); - free(activator->hookService); + serviceRegistration_unregister(activator->hook); + free(activator->hookService); - serviceRegistration_unregister(activator->endpointListenerService); - free(activator->endpointListener); + serviceRegistration_unregister(activator->endpointListenerService); + free(activator->endpointListener); - topologyManager_closeImports(activator->manager); + topologyManager_closeImports(activator->manager); - return status; + return status; } celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - struct activator *activator = userData; - if (!activator || !activator->manager) { - status = CELIX_BUNDLE_EXCEPTION; - } - else { - logHelper_stop(activator->loghelper); - logHelper_destroy(&activator->loghelper); + struct activator *activator = userData; + if (!activator || !activator->manager) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + logHelper_stop(activator->loghelper); + logHelper_destroy(&activator->loghelper); - status = topologyManager_destroy(activator->manager); - free(activator); - } + status = topologyManager_destroy(activator->manager); + free(activator); + } - return status; + return status; } http://git-wip-us.apache.org/repos/asf/celix/blob/2fb7b063/remote_services/topology_manager/private/src/topology_manager.c ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/private/src/topology_manager.c b/remote_services/topology_manager/private/src/topology_manager.c index c0ec7d1..adb6abe 100644 --- a/remote_services/topology_manager/private/src/topology_manager.c +++ b/remote_services/topology_manager/private/src/topology_manager.c @@ -41,687 +41,774 @@ #include "log_service.h" #include "log_helper.h" - struct topology_manager { - bundle_context_pt context; + bundle_context_pt context; + + celix_thread_mutex_t rsaListLock; + array_list_pt rsaList; - celix_thread_mutex_t rsaListLock; - array_list_pt rsaList; + celix_thread_mutex_t listenerListLock; + hash_map_pt listenerList; - celix_thread_mutex_t exportedServicesLock; - hash_map_pt exportedServices; + celix_thread_mutex_t exportedServicesLock; + hash_map_pt exportedServices; - celix_thread_mutex_t importedServicesLock; - hash_map_pt importedServices; + celix_thread_mutex_t importedServicesLock; + hash_map_pt importedServices; - celix_thread_mutex_t importInterestsLock; - hash_map_pt importInterests; + celix_thread_mutex_t importInterestsLock; + hash_map_pt importInterests; - log_helper_pt loghelper; + log_helper_pt loghelper; }; struct import_interest { - char *filter; - int refs; + char *filter; + int refs; }; -celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations); -celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export); +celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations); +celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export); celix_status_t topologyManager_create(bundle_context_pt context, log_helper_pt logHelper, topology_manager_pt *manager) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - *manager = malloc(sizeof(**manager)); - if (!*manager) { - return CELIX_ENOMEM; - } + *manager = malloc(sizeof(**manager)); + if (!*manager) { + return CELIX_ENOMEM; + } - (*manager)->context = context; - (*manager)->rsaList = NULL; - arrayList_create(&(*manager)->rsaList); + (*manager)->context = context; + (*manager)->rsaList = NULL; + arrayList_create(&(*manager)->rsaList); - status = celixThreadMutex_create(&(*manager)->rsaListLock, NULL); - status = celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL); - status = celixThreadMutex_create(&(*manager)->importedServicesLock, NULL); - status = celixThreadMutex_create(&(*manager)->importInterestsLock, NULL); + status = celixThreadMutex_create(&(*manager)->rsaListLock, NULL); + status = celixThreadMutex_create(&(*manager)->exportedServicesLock, NULL); + status = celixThreadMutex_create(&(*manager)->importedServicesLock, NULL); + status = celixThreadMutex_create(&(*manager)->importInterestsLock, NULL); + status = celixThreadMutex_create(&(*manager)->listenerListLock, NULL); - (*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL); - (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL); - (*manager)->importInterests = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + (*manager)->listenerList = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL); + (*manager)->exportedServices = hashMap_create(serviceReference_hashCode, NULL, serviceReference_equals2, NULL); + (*manager)->importedServices = hashMap_create(NULL, NULL, NULL, NULL); + (*manager)->importInterests = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); - (*manager)->loghelper = logHelper; + (*manager)->loghelper = logHelper; - return status; + return status; } celix_status_t topologyManager_destroy(topology_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - status = celixThreadMutex_lock(&manager->rsaListLock); + status = celixThreadMutex_lock(&manager->rsaListLock); - arrayList_destroy(manager->rsaList); + arrayList_destroy(manager->rsaList); - status = celixThreadMutex_unlock(&manager->rsaListLock); - status = celixThreadMutex_destroy(&manager->rsaListLock); + status = celixThreadMutex_unlock(&manager->rsaListLock); + status = celixThreadMutex_destroy(&manager->rsaListLock); - status = celixThreadMutex_lock(&manager->exportedServicesLock); + status = celixThreadMutex_lock(&manager->exportedServicesLock); - hashMap_destroy(manager->exportedServices, false, false); + hashMap_destroy(manager->exportedServices, false, false); - status = celixThreadMutex_unlock(&manager->exportedServicesLock); - status = celixThreadMutex_destroy(&manager->exportedServicesLock); + status = celixThreadMutex_unlock(&manager->exportedServicesLock); + status = celixThreadMutex_destroy(&manager->exportedServicesLock); - status = celixThreadMutex_lock(&manager->importedServicesLock); + status = celixThreadMutex_lock(&manager->importedServicesLock); - hashMap_destroy(manager->importedServices, false, false); + hashMap_destroy(manager->importedServices, false, false); - status = celixThreadMutex_unlock(&manager->importedServicesLock); - status = celixThreadMutex_destroy(&manager->importedServicesLock); + status = celixThreadMutex_unlock(&manager->importedServicesLock); + status = celixThreadMutex_destroy(&manager->importedServicesLock); - status = celixThreadMutex_lock(&manager->importInterestsLock); + status = celixThreadMutex_lock(&manager->importInterestsLock); - hashMap_destroy(manager->importInterests, true, true); + hashMap_destroy(manager->importInterests, true, true); - status = celixThreadMutex_unlock(&manager->importInterestsLock); - status = celixThreadMutex_destroy(&manager->importInterestsLock); + status = celixThreadMutex_unlock(&manager->importInterestsLock); + status = celixThreadMutex_destroy(&manager->importInterestsLock); - free(manager); + free(manager); - return status; + return status; } celix_status_t topologyManager_closeImports(topology_manager_pt manager) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - status = celixThreadMutex_lock(&manager->importedServicesLock); + status = celixThreadMutex_lock(&manager->importedServicesLock); - hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - endpoint_description_pt ep = hashMapEntry_getKey(entry); - hash_map_pt imports = hashMapEntry_getValue(entry); + hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices); + while (hashMapIterator_hasNext(iter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); + endpoint_description_pt ep = hashMapEntry_getKey(entry); + hash_map_pt imports = hashMapEntry_getValue(entry); - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id); - hash_map_iterator_pt importsIter = hashMapIterator_create(imports); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", ep->service, ep->id); + hash_map_iterator_pt importsIter = hashMapIterator_create(imports); - while (hashMapIterator_hasNext(importsIter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter); + while (hashMapIterator_hasNext(importsIter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter); - remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); - import_registration_pt import = hashMapEntry_getValue(entry); + remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); + import_registration_pt import = hashMapEntry_getValue(entry); - status = rsa->importRegistration_close(rsa->admin, import); - if (status == CELIX_SUCCESS) { - hashMapIterator_remove(importsIter); - } - } - hashMapIterator_destroy(importsIter); + status = rsa->importRegistration_close(rsa->admin, import); + if (status == CELIX_SUCCESS) { + hashMapIterator_remove(importsIter); + } + } + hashMapIterator_destroy(importsIter); - hashMapIterator_remove(iter); + hashMapIterator_remove(iter); - if (imports != NULL) { - hashMap_destroy(imports, false, false); - } - } - hashMapIterator_destroy(iter); + if (imports != NULL) { + hashMap_destroy(imports, false, false); + } + } + hashMapIterator_destroy(iter); - status = celixThreadMutex_unlock(&manager->importedServicesLock); + status = celixThreadMutex_unlock(&manager->importedServicesLock); - return status; + return status; } - celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt reference, void **service) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; - status = bundleContext_getService(manager->context, reference, service); + status = bundleContext_getService(manager->context, reference, service); - return status; + return status; } celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt reference, void * service) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; - remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA"); + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; + remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service; + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added RSA"); - status = celixThreadMutex_lock(&manager->rsaListLock); - arrayList_add(manager->rsaList, rsa); - status = celixThreadMutex_unlock(&manager->rsaListLock); + status = celixThreadMutex_lock(&manager->rsaListLock); + arrayList_add(manager->rsaList, rsa); + status = celixThreadMutex_unlock(&manager->rsaListLock); - // add already imported services to new rsa - status = celixThreadMutex_lock(&manager->importedServicesLock); - hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices); + // add already imported services to new rsa + status = celixThreadMutex_lock(&manager->importedServicesLock); + hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices); - while (hashMapIterator_hasNext(importedServicesIterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator); - endpoint_description_pt endpoint = hashMapEntry_getKey(entry); - import_registration_pt import = NULL; + while (hashMapIterator_hasNext(importedServicesIterator)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(importedServicesIterator); + endpoint_description_pt endpoint = hashMapEntry_getKey(entry); + import_registration_pt import = NULL; - status = rsa->importService(rsa->admin, endpoint, &import); + status = rsa->importService(rsa->admin, endpoint, &import); - if (status == CELIX_SUCCESS) { - hash_map_pt imports = hashMapEntry_getValue(entry); + if (status == CELIX_SUCCESS) { + hash_map_pt imports = hashMapEntry_getValue(entry); - if (imports == NULL) { - imports = hashMap_create(NULL, NULL, NULL, NULL); - } + if (imports == NULL) { + imports = hashMap_create(NULL, NULL, NULL, NULL); + } - hashMap_put(imports, service, import); - } - } + hashMap_put(imports, service, import); + } + } - hashMapIterator_destroy(importedServicesIterator); + hashMapIterator_destroy(importedServicesIterator); - status = celixThreadMutex_unlock(&manager->importedServicesLock); + status = celixThreadMutex_unlock(&manager->importedServicesLock); - // add already exported services to new rsa - status = celixThreadMutex_lock(&manager->exportedServicesLock); - hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices); + // add already exported services to new rsa + status = celixThreadMutex_lock(&manager->exportedServicesLock); + hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices); - while (hashMapIterator_hasNext(exportedServicesIterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator); - service_reference_pt reference = hashMapEntry_getKey(entry); - char *serviceId = NULL; + while (hashMapIterator_hasNext(exportedServicesIterator)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator); + service_reference_pt reference = hashMapEntry_getKey(entry); + char *serviceId = NULL; - serviceReference_getProperty(reference, (char *)OSGI_FRAMEWORK_SERVICE_ID, &serviceId); + serviceReference_getProperty(reference, (char *) OSGI_FRAMEWORK_SERVICE_ID, &serviceId); - array_list_pt endpoints = NULL; - status = rsa->exportService(rsa->admin, serviceId, NULL, &endpoints); + array_list_pt endpoints = NULL; + status = rsa->exportService(rsa->admin, serviceId, NULL, &endpoints); - if (status == CELIX_SUCCESS) { - hash_map_pt exports = hashMapEntry_getValue(entry); + if (status == CELIX_SUCCESS) { + hash_map_pt exports = hashMapEntry_getValue(entry); - if (exports == NULL) { - exports = hashMap_create(NULL, NULL, NULL, NULL); - } + if (exports == NULL) { + exports = hashMap_create(NULL, NULL, NULL, NULL); + } - hashMap_put(exports, rsa, endpoints); - status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); - } - } + hashMap_put(exports, rsa, endpoints); + status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); + } + } - hashMapIterator_destroy(exportedServicesIterator); + hashMapIterator_destroy(exportedServicesIterator); - status = celixThreadMutex_unlock(&manager->exportedServicesLock); + status = celixThreadMutex_unlock(&manager->exportedServicesLock); - return status; + return status; } celix_status_t topologyManager_rsaModified(void * handle, service_reference_pt reference, void * service) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - // Nop... + // Nop... - return status; + return status; } celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt reference, void * service) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA"); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA"); - remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service; + remote_service_admin_service_pt rsa = (remote_service_admin_service_pt) service; + status = celixThreadMutex_lock(&manager->exportedServicesLock); - status = celixThreadMutex_lock(&manager->exportedServicesLock); + hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices); - hash_map_iterator_pt iter = hashMapIterator_create(manager->exportedServices); + while (hashMapIterator_hasNext(iter)) { + int exportsIter = 0; - while (hashMapIterator_hasNext(iter)) { - int exportsIter = 0; + hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); + service_reference_pt key = hashMapEntry_getKey(entry); + hash_map_pt exports = hashMapEntry_getValue(entry); - service_reference_pt key = hashMapEntry_getKey(entry); - hash_map_pt exports = hashMapEntry_getValue(entry); + array_list_pt exports_list = hashMap_get(exports, rsa); - array_list_pt exports_list = hashMap_get(exports, rsa); + if (exports_list != NULL) { + for (exportsIter = 0; exportsIter < arrayList_size(exports_list); exportsIter++) { + export_registration_pt export = arrayList_get(exports_list, exportsIter); + topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); + rsa->exportRegistration_close(export); + } - if (exports_list != NULL) { - for (exportsIter = 0; exportsIter < arrayList_size(exports_list); exportsIter++) { - export_registration_pt export = arrayList_get(exports_list, exportsIter); - topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); - rsa->exportRegistration_close(export); - } + arrayList_destroy(exports_list); + exports_list = NULL; + } - arrayList_destroy(exports_list); - exports_list = NULL; - } + hashMap_remove(exports, rsa); - hashMap_remove(exports, rsa); + if (hashMap_size(exports) == 0) { + hashMap_remove(manager->exportedServices, key); + hashMap_destroy(exports, false, false); - if (hashMap_size(exports) == 0) { - hashMap_remove(manager->exportedServices, key); - hashMap_destroy(exports, false, false); + hashMapIterator_destroy(iter); + iter = hashMapIterator_create(manager->exportedServices); + } - hashMapIterator_destroy(iter); - iter = hashMapIterator_create(manager->exportedServices); } - } - - hashMapIterator_destroy(iter); + hashMapIterator_destroy(iter); - status = celixThreadMutex_unlock(&manager->exportedServicesLock); + status = celixThreadMutex_unlock(&manager->exportedServicesLock); - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA"); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Removed RSA"); - status = celixThreadMutex_lock(&manager->rsaListLock); - arrayList_removeElement(manager->rsaList, rsa); - status = celixThreadMutex_unlock(&manager->rsaListLock); + status = celixThreadMutex_lock(&manager->rsaListLock); + arrayList_removeElement(manager->rsaList, rsa); + status = celixThreadMutex_unlock(&manager->rsaListLock); - return status; + return status; } celix_status_t topologyManager_getRSAs(topology_manager_pt manager, array_list_pt *rsaList) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - status = arrayList_create(rsaList); - if (status != CELIX_SUCCESS) { - return CELIX_ENOMEM; - } + status = arrayList_create(rsaList); + if (status != CELIX_SUCCESS) { + return CELIX_ENOMEM; + } - status = celixThreadMutex_lock(&manager->rsaListLock); - arrayList_addAll(*rsaList, manager->rsaList); - status = celixThreadMutex_unlock(&manager->rsaListLock); + status = celixThreadMutex_lock(&manager->rsaListLock); + arrayList_addAll(*rsaList, manager->rsaList); + status = celixThreadMutex_unlock(&manager->rsaListLock); - return status; + return status; } celix_status_t topologyManager_serviceChanged(void *listener, service_event_pt event) { - celix_status_t status = CELIX_SUCCESS; - service_listener_pt listen = listener; - topology_manager_pt manager = listen->handle; - - char *export = NULL; - char *serviceId = NULL; - serviceReference_getProperty(event->reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export); - serviceReference_getProperty(event->reference, (char *)OSGI_FRAMEWORK_SERVICE_ID, &serviceId); - - if (!export) { - // Nothing needs to be done: we're not interested... - return status; - } - - switch (event->type) { - case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED: - status = topologyManager_addExportedService(manager, event->reference, serviceId); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED: - status = topologyManager_removeExportedService(manager, event->reference, serviceId); - status = topologyManager_addExportedService(manager, event->reference, serviceId); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING: - status = topologyManager_removeExportedService(manager, event->reference, serviceId); - break; - case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH: - break; - } - - return status; + celix_status_t status = CELIX_SUCCESS; + service_listener_pt listen = listener; + topology_manager_pt manager = listen->handle; + + char *export = NULL; + char *serviceId = NULL; + serviceReference_getProperty(event->reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export); + serviceReference_getProperty(event->reference, (char *) OSGI_FRAMEWORK_SERVICE_ID, &serviceId); + + if (!export) { + // Nothing needs to be done: we're not interested... + return status; + } + + switch (event->type) { + case OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED: + status = topologyManager_addExportedService(manager, event->reference, serviceId); + break; + case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED: + status = topologyManager_removeExportedService(manager, event->reference, serviceId); + status = topologyManager_addExportedService(manager, event->reference, serviceId); + break; + case OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING: + status = topologyManager_removeExportedService(manager, event->reference, serviceId); + break; + case OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH: + break; + } + + return status; } celix_status_t topologyManager_addImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add imported service (%s; %s).", endpoint->service, endpoint->id); - // Create a local copy of the current list of RSAs, to ensure we do not run into threading issues... - array_list_pt localRSAs = NULL; - topologyManager_getRSAs(manager, &localRSAs); + // Create a local copy of the current list of RSAs, to ensure we do not run into threading issues... + array_list_pt localRSAs = NULL; + topologyManager_getRSAs(manager, &localRSAs); - status = celixThreadMutex_lock(&manager->importedServicesLock); + status = celixThreadMutex_lock(&manager->importedServicesLock); - hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL); - hashMap_put(manager->importedServices, endpoint, imports); + hash_map_pt imports = hashMap_create(NULL, NULL, NULL, NULL); + hashMap_put(manager->importedServices, endpoint, imports); - int size = arrayList_size(localRSAs); - for (int iter = 0; iter < size; iter++) { - remote_service_admin_service_pt rsa = arrayList_get(localRSAs, iter); + int size = arrayList_size(localRSAs); + for (int iter = 0; iter < size; iter++) { + remote_service_admin_service_pt rsa = arrayList_get(localRSAs, iter); - import_registration_pt import = NULL; - status = rsa->importService(rsa->admin, endpoint, &import); - if (status == CELIX_SUCCESS) { - hashMap_put(imports, rsa, import); - } - } + import_registration_pt import = NULL; + status = rsa->importService(rsa->admin, endpoint, &import); + if (status == CELIX_SUCCESS) { + hashMap_put(imports, rsa, import); + } + } - arrayList_destroy(localRSAs); + arrayList_destroy(localRSAs); - status = celixThreadMutex_unlock(&manager->importedServicesLock); + status = celixThreadMutex_unlock(&manager->importedServicesLock); - return status; + return status; } celix_status_t topologyManager_removeImportedService(void *handle, endpoint_description_pt endpoint, char *matchedFilter) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove imported service (%s; %s).", endpoint->service, endpoint->id); - status = celixThreadMutex_lock(&manager->importedServicesLock); + status = celixThreadMutex_lock(&manager->importedServicesLock); - hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - endpoint_description_pt ep = hashMapEntry_getKey(entry); - hash_map_pt imports = hashMapEntry_getValue(entry); + hash_map_iterator_pt iter = hashMapIterator_create(manager->importedServices); + while (hashMapIterator_hasNext(iter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); + endpoint_description_pt ep = hashMapEntry_getKey(entry); + hash_map_pt imports = hashMapEntry_getValue(entry); - if (strcmp(endpoint->id, ep->id) == 0) { - hash_map_iterator_pt importsIter = hashMapIterator_create(imports); + if (strcmp(endpoint->id, ep->id) == 0) { + hash_map_iterator_pt importsIter = hashMapIterator_create(imports); - while (hashMapIterator_hasNext(importsIter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter); + while (hashMapIterator_hasNext(importsIter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(importsIter); - remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); - import_registration_pt import = hashMapEntry_getValue(entry); + remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); + import_registration_pt import = hashMapEntry_getValue(entry); - status = rsa->importRegistration_close(rsa->admin, import); - if (status == CELIX_SUCCESS) { - hashMapIterator_remove(importsIter); - } - } - hashMapIterator_destroy(importsIter); + status = rsa->importRegistration_close(rsa->admin, import); + if (status == CELIX_SUCCESS) { + hashMapIterator_remove(importsIter); + } + } + hashMapIterator_destroy(importsIter); - hashMapIterator_remove(iter); + hashMapIterator_remove(iter); - if (imports != NULL) { - hashMap_destroy(imports, false, false); - } + if (imports != NULL) { + hashMap_destroy(imports, false, false); + } - } - } - hashMapIterator_destroy(iter); + } + } + hashMapIterator_destroy(iter); - status = celixThreadMutex_unlock(&manager->importedServicesLock); + status = celixThreadMutex_unlock(&manager->importedServicesLock); - return status; + return status; } celix_status_t topologyManager_addExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Add exported service (%s).", serviceId); - // Create a local copy of the current list of RSAs, to ensure we do not run into threading issues... - array_list_pt localRSAs = NULL; - topologyManager_getRSAs(manager, &localRSAs); + // Create a local copy of the current list of RSAs, to ensure we do not run into threading issues... + array_list_pt localRSAs = NULL; + topologyManager_getRSAs(manager, &localRSAs); - status = celixThreadMutex_lock(&manager->exportedServicesLock); + status = celixThreadMutex_lock(&manager->exportedServicesLock); - hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL); - hashMap_put(manager->exportedServices, reference, exports); + hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL); + hashMap_put(manager->exportedServices, reference, exports); - int size = arrayList_size(localRSAs); - if (size == 0) { - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet."); - } + int size = arrayList_size(localRSAs); + if (size == 0) { + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_WARNING, "TOPOLOGY_MANAGER: No RSA available yet."); + } - for (int iter = 0; iter < size; iter++) { - remote_service_admin_service_pt rsa = arrayList_get(localRSAs, iter); + for (int iter = 0; iter < size; iter++) { + remote_service_admin_service_pt rsa = arrayList_get(localRSAs, iter); - array_list_pt endpoints = NULL; - status = rsa->exportService(rsa->admin, serviceId, NULL, &endpoints); + array_list_pt endpoints = NULL; + status = rsa->exportService(rsa->admin, serviceId, NULL, &endpoints); - if (status == CELIX_SUCCESS) { - hashMap_put(exports, rsa, endpoints); - status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); - } - } + if (status == CELIX_SUCCESS) { + hashMap_put(exports, rsa, endpoints); + status = topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); + } + } - arrayList_destroy(localRSAs); + arrayList_destroy(localRSAs); - status = celixThreadMutex_unlock(&manager->exportedServicesLock); + status = celixThreadMutex_unlock(&manager->exportedServicesLock); - return status; + return status; } celix_status_t topologyManager_removeExportedService(topology_manager_pt manager, service_reference_pt reference, char *serviceId) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId); + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Remove exported service (%s).", serviceId); - status = celixThreadMutex_lock(&manager->exportedServicesLock); + status = celixThreadMutex_lock(&manager->exportedServicesLock); - hash_map_pt exports = hashMap_get(manager->exportedServices, reference); - if (exports) { - hash_map_iterator_pt iter = hashMapIterator_create(exports); - while (hashMapIterator_hasNext(iter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); + hash_map_pt exports = hashMap_get(manager->exportedServices, reference); + if (exports) { + hash_map_iterator_pt iter = hashMapIterator_create(exports); + while (hashMapIterator_hasNext(iter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); - remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); - array_list_pt exportRegistrations = hashMapEntry_getValue(entry); + remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); + array_list_pt exportRegistrations = hashMapEntry_getValue(entry); - for (int exportsIter = 0; exportsIter < arrayList_size(exportRegistrations); exportsIter++) { - export_registration_pt export = arrayList_get(exportRegistrations, exportsIter); - topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); - rsa->exportRegistration_close(export); - } - arrayList_destroy(exportRegistrations); - exportRegistrations = NULL; + for (int exportsIter = 0; exportsIter < arrayList_size(exportRegistrations); exportsIter++) { + export_registration_pt export = arrayList_get(exportRegistrations, exportsIter); + topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); + rsa->exportRegistration_close(export); + } + arrayList_destroy(exportRegistrations); + exportRegistrations = NULL; - hashMap_remove(exports, rsa); - hashMapIterator_destroy(iter); - iter = hashMapIterator_create(exports); + hashMap_remove(exports, rsa); + hashMapIterator_destroy(iter); + iter = hashMapIterator_create(exports); - } - hashMapIterator_destroy(iter); - } + } + hashMapIterator_destroy(iter); + } - exports = hashMap_remove(manager->exportedServices, reference); + exports = hashMap_remove(manager->exportedServices, reference); - if (exports != NULL) { - hashMap_destroy(exports, false, false); - } + if (exports != NULL) { + hashMap_destroy(exports, false, false); + } - status = celixThreadMutex_unlock(&manager->exportedServicesLock); + status = celixThreadMutex_unlock(&manager->exportedServicesLock); - return status; + return status; } celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_pt rsa, export_registration_pt export, endpoint_description_pt *endpoint) { - celix_status_t status = CELIX_SUCCESS; + celix_status_t status = CELIX_SUCCESS; + + export_reference_pt reference = NULL; + status = rsa->exportRegistration_getExportReference(export, &reference); + + if (status == CELIX_SUCCESS) { + status = rsa->exportReference_getExportedEndpoint(reference, endpoint); + } + + free(reference); + + return status; +} + +celix_status_t topologyManager_endpointListenerAdding(void* handle, service_reference_pt reference, void** service) { + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; + + bundleContext_getService(manager->context, reference, service); + + return status; +} + +celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) { + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; + char *scope = NULL; + + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: Added ENDPOINT_LISTENER"); + + celixThreadMutex_lock(&manager->listenerListLock); + hashMap_put(manager->listenerList, reference, NULL); + celixThreadMutex_unlock(&manager->listenerListLock); + + serviceReference_getProperty(reference, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + + filter_pt filter = filter_create(scope); + hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices); - export_reference_pt reference = NULL; - status = rsa->exportRegistration_getExportReference(export, &reference); + while (hashMapIterator_hasNext(refIter)) { + hash_map_pt rsaExports = hashMapIterator_nextValue(refIter); + hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports); - if (status == CELIX_SUCCESS) { - status = rsa->exportReference_getExportedEndpoint(reference, endpoint); - } + while (hashMapIterator_hasNext(rsaIter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter); + remote_service_admin_service_pt rsa = hashMapEntry_getKey(entry); + array_list_pt registrations = hashMapEntry_getValue(entry); - free(reference); + int arrayListSize = arrayList_size(registrations); + int cnt = 0; - return status; + for (; cnt < arrayListSize; cnt++) { + export_registration_pt export = arrayList_get(registrations, cnt); + endpoint_description_pt endpoint = NULL; + + status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); + if (status == CELIX_SUCCESS) { + bool matchResult = false; + filter_match(filter, endpoint->properties, &matchResult); + if (matchResult) { + endpoint_listener_pt listener = (endpoint_listener_pt) service; + status = listener->endpointAdded(listener->handle, endpoint, scope); + } + } + } + } + hashMapIterator_destroy(rsaIter); + } + hashMapIterator_destroy(refIter); + + filter_destroy(filter); + + return status; +} + +celix_status_t topologyManager_endpointListenerModified(void * handle, service_reference_pt reference, void * service) { + celix_status_t status; + + status = topologyManager_endpointListenerRemoved(handle, reference, service); + if (status == CELIX_SUCCESS) { + status = topologyManager_endpointListenerAdded(handle, reference, service); + } + + return status; +} + +celix_status_t topologyManager_endpointListenerRemoved(void * handle, service_reference_pt reference, void * service) { + celix_status_t status; + topology_manager_pt manager = handle; + + status = celixThreadMutex_lock(&manager->listenerListLock); + + if (status == CELIX_SUCCESS) { + if (hashMap_remove(manager->listenerList, reference)) { + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "EndpointListener Removed"); + } + + status = celixThreadMutex_unlock(&manager->listenerListLock); + } + + return status; } celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_pt rsa, array_list_pt registrations) { - celix_status_t status = CELIX_SUCCESS; - - array_list_pt endpointListeners = NULL; - status = bundleContext_getServiceReferences(manager->context, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, &endpointListeners); - if (status != CELIX_SUCCESS || !endpointListeners) { - return CELIX_BUNDLE_EXCEPTION; - } - - int eplSize = arrayList_size(endpointListeners); - for (int eplIt = 0; eplIt < eplSize; eplIt++) { - service_reference_pt eplRef = arrayList_get(endpointListeners, eplIt); - - char *scope = NULL; - serviceReference_getProperty(eplRef, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, &scope); - - endpoint_listener_pt epl = NULL; - status = bundleContext_getService(manager->context, eplRef, (void **) &epl); - if (status != CELIX_SUCCESS || !epl) { - continue; - } - - filter_pt filter = filter_create(scope); - - int regSize = arrayList_size(registrations); - for (int regIt = 0; regIt < regSize; regIt++) { - export_registration_pt export = arrayList_get(registrations, regIt); - - endpoint_description_pt endpoint = NULL; - status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); - if (status != CELIX_SUCCESS || !endpoint) { - continue; - } - - bool matchResult = false; - filter_match(filter, endpoint->properties, &matchResult); - if (matchResult) { - status = epl->endpointAdded(epl->handle, endpoint, scope); - } - } - - filter_destroy(filter); - } - - if (endpointListeners) { - arrayList_destroy(endpointListeners); - } - - return status; + celix_status_t status; + + status = celixThreadMutex_lock(&manager->listenerListLock); + + if (status == CELIX_SUCCESS) { + hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList); + while (hashMapIterator_hasNext(iter)) { + char *scope = NULL; + endpoint_listener_pt epl = NULL; + service_reference_pt reference = hashMapIterator_nextKey(iter); + + serviceReference_getProperty(reference, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + + status = bundleContext_getService(manager->context, reference, (void **) &epl); + if (status == CELIX_SUCCESS) { + filter_pt filter = filter_create(scope); + + int regSize = arrayList_size(registrations); + for (int regIt = 0; regIt < regSize; regIt++) { + export_registration_pt export = arrayList_get(registrations, regIt); + + endpoint_description_pt endpoint = NULL; + status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); + if (status == CELIX_SUCCESS) { + bool matchResult = false; + filter_match(filter, endpoint->properties, &matchResult); + if (matchResult) { + status = epl->endpointAdded(epl->handle, endpoint, scope); + } + } + } + + filter_destroy(filter); + } + } + + hashMapIterator_destroy(iter); + + status = celixThreadMutex_unlock(&manager->listenerListLock); + } + + return status; } -celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) { - celix_status_t status = CELIX_SUCCESS; +celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_pt rsa, export_registration_pt export) { - array_list_pt endpointListeners = NULL; - status = bundleContext_getServiceReferences(manager->context, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, &endpointListeners); - if (status != CELIX_SUCCESS || !endpointListeners) { - return CELIX_BUNDLE_EXCEPTION; - } + celix_status_t status; - for (int eplIt = 0; eplIt < arrayList_size(endpointListeners); eplIt++) { - service_reference_pt eplRef = arrayList_get(endpointListeners, eplIt); + status = celixThreadMutex_lock(&manager->listenerListLock); - endpoint_listener_pt epl = NULL; - status = bundleContext_getService(manager->context, eplRef, (void **) &epl); - if (status != CELIX_SUCCESS || !epl) { - continue; - } + if (status == CELIX_SUCCESS) { + hash_map_iterator_pt iter = hashMapIterator_create(manager->listenerList); + while (hashMapIterator_hasNext(iter)) { + endpoint_description_pt endpoint = NULL; + endpoint_listener_pt epl = NULL; + char *scope = NULL; - endpoint_description_pt endpoint = NULL; - status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); - if (status != CELIX_SUCCESS || !endpoint) { - continue; - } + service_reference_pt reference = hashMapIterator_nextKey(iter); + serviceReference_getProperty(reference, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, &scope); - status = epl->endpointRemoved(epl->handle, endpoint, NULL); - } + status = bundleContext_getService(manager->context, reference, (void **) &epl); + + if (status == CELIX_SUCCESS) { + status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); + } + + if (status == CELIX_SUCCESS) { + status = epl->endpointRemoved(epl->handle, endpoint, NULL); + } + } - if (endpointListeners) { - arrayList_destroy(endpointListeners); - } + hashMapIterator_destroy(iter); - return status; + status = celixThreadMutex_unlock(&manager->listenerListLock); + + } + + return status; } celix_status_t topologyManager_extendFilter(topology_manager_pt manager, char *filter, char **updatedFilter) { - celix_status_t status = CELIX_SUCCESS; - bundle_context_pt context = manager->context; - char* uuid = NULL; - - status = bundleContext_getProperty(context, (char *)OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid); - if (!uuid) { - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!"); - return CELIX_BUNDLE_EXCEPTION; - } + celix_status_t status = CELIX_SUCCESS; + bundle_context_pt context = manager->context; + char* uuid = NULL; + + status = bundleContext_getProperty(context, (char *) OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid); + if (!uuid) { + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_ERROR, "TOPOLOGY_MANAGER: no framework UUID defined?!"); + return CELIX_BUNDLE_EXCEPTION; + } - int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); - *updatedFilter = malloc(len); - if (!*updatedFilter) { - return CELIX_ENOMEM; - } + int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); + *updatedFilter = malloc(len); + if (!*updatedFilter) { + return CELIX_ENOMEM; + } - snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + snprintf(*updatedFilter, len, "(&%s(!(%s=%s)))", filter, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); - return status; + return status; } celix_status_t topologyManager_listenerAdded(void *handle, array_list_pt listeners) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; - - for (int i = 0; i < arrayList_size(listeners); i++) { - listener_hook_info_pt info = arrayList_get(listeners, i); - - bundle_pt bundle = NULL, self = NULL; - bundleContext_getBundle(info->context, &bundle); - bundleContext_getBundle(manager->context, &self); - if (bundle == self) { - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself."); - continue; - } - - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter); - - char *filter = NULL; - topologyManager_extendFilter(manager, info->filter, &filter); - - status = celixThreadMutex_lock(&manager->importInterestsLock); - - struct import_interest *interest = hashMap_get(manager->importInterests, filter); - if (interest) { - interest->refs++; - free(filter); - } else { - interest = malloc(sizeof(*interest)); - interest->filter = filter; - interest->refs = 1; - hashMap_put(manager->importInterests, filter, interest); - } - - status = celixThreadMutex_unlock(&manager->importInterestsLock); - } - - return status; + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; + + for (int i = 0; i < arrayList_size(listeners); i++) { + listener_hook_info_pt info = arrayList_get(listeners, i); + + bundle_pt bundle = NULL, self = NULL; + bundleContext_getBundle(info->context, &bundle); + bundleContext_getBundle(manager->context, &self); + if (bundle == self) { + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself."); + continue; + } + + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" added", info->filter); + + char *filter = NULL; + topologyManager_extendFilter(manager, info->filter, &filter); + + status = celixThreadMutex_lock(&manager->importInterestsLock); + + struct import_interest *interest = hashMap_get(manager->importInterests, filter); + if (interest) { + interest->refs++; + free(filter); + } else { + interest = malloc(sizeof(*interest)); + interest->filter = filter; + interest->refs = 1; + hashMap_put(manager->importInterests, filter, interest); + } + + status = celixThreadMutex_unlock(&manager->importInterestsLock); + } + + return status; } celix_status_t topologyManager_listenerRemoved(void *handle, array_list_pt listeners) { - celix_status_t status = CELIX_SUCCESS; - topology_manager_pt manager = handle; - - for (int i = 0; i < arrayList_size(listeners); i++) { - listener_hook_info_pt info = arrayList_get(listeners, i); - - bundle_pt bundle = NULL, self = NULL; - bundleContext_getBundle(info->context, &bundle); - bundleContext_getBundle(manager->context, &self); - if (bundle == self) { - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself."); - continue; - } - - logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter); - - char *filter = NULL; - topologyManager_extendFilter(manager, info->filter, &filter); - - status = celixThreadMutex_lock(&manager->importInterestsLock); - - struct import_interest *interest = hashMap_get(manager->importInterests, filter); - if (interest != NULL && --interest->refs <= 0) { - // last reference, remove from scope - hash_map_entry_pt entry = hashMap_getEntry(manager->importInterests, filter); - char* key = (char*) hashMapEntry_getKey(entry); - interest = hashMap_remove(manager->importInterests, filter); - free(key); - free(interest); - } + celix_status_t status = CELIX_SUCCESS; + topology_manager_pt manager = handle; + + for (int i = 0; i < arrayList_size(listeners); i++) { + listener_hook_info_pt info = arrayList_get(listeners, i); + + bundle_pt bundle = NULL, self = NULL; + bundleContext_getBundle(info->context, &bundle); + bundleContext_getBundle(manager->context, &self); + if (bundle == self) { + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_DEBUG, "TOPOLOGY_MANAGER: Ignore myself."); + continue; + } - if (filter != NULL) { - free(filter); - } + logHelper_log(manager->loghelper, OSGI_LOGSERVICE_INFO, "TOPOLOGY_MANAGER: listener with filter \"%s\" removed.", info->filter); + + char *filter = NULL; + topologyManager_extendFilter(manager, info->filter, &filter); - status = celixThreadMutex_unlock(&manager->importInterestsLock); - } + status = celixThreadMutex_lock(&manager->importInterestsLock); + + struct import_interest *interest = hashMap_get(manager->importInterests, filter); + if (interest != NULL && --interest->refs <= 0) { + // last reference, remove from scope + hash_map_entry_pt entry = hashMap_getEntry(manager->importInterests, filter); + char* key = (char*) hashMapEntry_getKey(entry); + interest = hashMap_remove(manager->importInterests, filter); + free(key); + free(interest); + } + + if (filter != NULL) { + free(filter); + } + + status = celixThreadMutex_unlock(&manager->importInterestsLock); + } - return status; + return status; }