celix_status_t pubsubAdmin_closeAllSubscriptions(pubsub_admin_pt admin,char* scope,char* topic){ celix_status_t status = CELIX_SUCCESS; printf("PSA_ZMQ: Closing all subscriptions\n"); celixThreadMutex_lock(&admin->subscriptionsLock); char *scope_topic = createScopeTopicKey(scope, topic); hash_map_entry_pt sub_entry = (hash_map_entry_pt)hashMap_getEntry(admin->subscriptions,scope_topic); if(sub_entry!=NULL){ char* topic = (char*)hashMapEntry_getKey(sub_entry); topic_subscription_pt ts = (topic_subscription_pt)hashMapEntry_getValue(sub_entry); status += pubsub_topicSubscriptionStop(ts); disconnectTopicPubSubFromSerializer(admin, ts, false); status += pubsub_topicSubscriptionDestroy(ts); hashMap_remove(admin->subscriptions,scope_topic); free(topic); } free(scope_topic); celixThreadMutex_unlock(&admin->subscriptionsLock); return status; }
/** * Removes an endpoint URL from the list of polled endpoints. */ celix_status_t endpointDiscoveryPoller_removeDiscoveryEndpoint(endpoint_discovery_poller_pt poller, char *url) { celix_status_t status = CELIX_SUCCESS; if (celixThreadMutex_lock(&poller->pollerLock) != CELIX_SUCCESS) { status = CELIX_BUNDLE_EXCEPTION; } else { hash_map_entry_pt entry = hashMap_getEntry(poller->entries, url); if (entry == NULL) { logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: There was no entry found belonging to url %s - maybe already removed?", url); } else { char* origKey = hashMapEntry_getKey(entry); logHelper_log(*poller->loghelper, OSGI_LOGSERVICE_DEBUG, "ENDPOINT_POLLER: remove discovery endpoint with url %s", url); array_list_pt entries = hashMap_remove(poller->entries, url); for (unsigned int i = arrayList_size(entries); i > 0; i--) { endpoint_description_pt endpoint = arrayList_get(entries, i - 1); discovery_removeDiscoveredEndpoint(poller->discovery, endpoint); arrayList_remove(entries, i - 1); endpointDescription_destroy(endpoint); } if (entries != NULL) { arrayList_destroy(entries); } free(origKey); } status = celixThreadMutex_unlock(&poller->pollerLock); } return status; }
/// \TEST_CASE_ID{2} /// \TEST_CASE_TITLE{Test scope initialisation} /// \TEST_CASE_REQ{REQ-2} /// \TEST_CASE_DESC Checks if scopes can be added, but not twice static void testScope(void) { int nr_exported; int nr_imported; array_list_pt epList; printf("\nBegin: %s\n", __func__); scopeInit("scope.json", &nr_exported, &nr_imported); CHECK_EQUAL(1, nr_exported); CHECK_EQUAL(0, nr_imported); discMock->getEPDescriptors(discMock->handle, &epList); // We export two services: Calculator and Calculator2, but only 1 has DFI bundle info CHECK_EQUAL(1, arrayList_size(epList)); for (unsigned int i = 0; i < arrayList_size(epList); i++) { endpoint_description_pt ep = (endpoint_description_pt) arrayList_get(epList, i); properties_pt props = ep->properties; hash_map_entry_pt entry = hashMap_getEntry(props, (void*)"key2"); char* value = (char*) hashMapEntry_getValue(entry); STRCMP_EQUAL("inaetics", value); /* printf("Service: %s ", ep->service); hash_map_iterator_pt iter = hashMapIterator_create(props); while (hashMapIterator_hasNext(iter)) { hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); printf("%s - %s\n", (char*)hashMapEntry_getKey(entry), (char*)hashMapEntry_getValue(entry)); } printf("\n"); hashMapIterator_destroy(iter); */ } printf("End: %s\n", __func__); }
celix_status_t pubsubAdmin_closeAllPublications(pubsub_admin_pt admin, char *scope, char* topic){ celix_status_t status = CELIX_SUCCESS; printf("PSA_ZMQ: Closing all publications\n"); celixThreadMutex_lock(&admin->localPublicationsLock); char *scope_topic = createScopeTopicKey(scope, topic); hash_map_entry_pt pubsvc_entry = (hash_map_entry_pt)hashMap_getEntry(admin->localPublications,scope_topic); if(pubsvc_entry!=NULL){ char* key = (char*)hashMapEntry_getKey(pubsvc_entry); service_factory_pt factory= (service_factory_pt)hashMapEntry_getValue(pubsvc_entry); topic_publication_pt pub = (topic_publication_pt)factory->handle; status += pubsub_topicPublicationStop(pub); disconnectTopicPubSubFromSerializer(admin, pub, true); status += pubsub_topicPublicationDestroy(pub); hashMap_remove(admin->localPublications,scope_topic); free(key); free(factory); } free(scope_topic); celixThreadMutex_unlock(&admin->localPublicationsLock); return status; }
static celix_status_t etcdWatcher_removeEntry(etcd_watcher_pt watcher, char* key, char* value) { celix_status_t status = CELIX_BUNDLE_EXCEPTION; endpoint_discovery_poller_pt poller = watcher->discovery->poller; hash_map_entry_pt entry = hashMap_getEntry(watcher->entries, key); if (entry != NULL) { void* origKey = hashMapEntry_getKey(entry); void* value = hashMap_remove(watcher->entries, key); free(origKey); // check if there is another entry with the same value hash_map_iterator_pt iter = hashMapIterator_create(watcher->entries); unsigned int valueFound = 0; while (hashMapIterator_hasNext(iter) && valueFound <= 1) { if (strcmp(value, hashMapIterator_nextValue(iter)) == 0) valueFound++; } hashMapIterator_destroy(iter); if (valueFound == 0) status = endpointDiscoveryPoller_removeDiscoveryEndpoint(poller, value); free(value); } return status; }
celix_status_t pubsub_discovery_uninterestedInTopic(void *handle, const char* scope, const char* topic) { pubsub_discovery_pt pubsub_discovery = (pubsub_discovery_pt) handle; char *scope_topic_key = createScopeTopicKey(scope, topic); celixThreadMutex_lock(&pubsub_discovery->watchersMutex); hash_map_entry_pt entry = hashMap_getEntry(pubsub_discovery->watchers, scope_topic_key); if(entry) { struct watcher_info * wi = hashMapEntry_getValue(entry); wi->nr_references--; if(wi->nr_references == 0) { char *key = hashMapEntry_getKey(entry); hashMap_remove(pubsub_discovery->watchers, scope_topic_key); free(key); free(scope_topic_key); etcdWatcher_stop(wi->watcher); etcdWatcher_destroy(wi->watcher); free(wi); } } else { fprintf(stderr, "[DISC] Inconsistency error: Removing unknown topic %s\n", topic); } celixThreadMutex_unlock(&pubsub_discovery->watchersMutex); return CELIX_SUCCESS; }
void test_hashMap_getEntry(void) { char * key = "key"; char * value = "value"; char * key2 = "key2"; char * value2 = "value2"; char * neKey = "notExisting"; char * key3 = NULL; char * value3 = "value3"; hash_map_entry_pt entry; hashMap_clear(map, false, false); // Add one entry hashMap_put(map, key, value); // Add second entry hashMap_put(map, key2, value2); entry = hashMap_getEntry(map, key); CU_ASSERT_STRING_EQUAL(entry->key, key); CU_ASSERT_STRING_EQUAL(entry->value, value); entry = hashMap_getEntry(map, key2); CU_ASSERT_STRING_EQUAL(entry->key, key2); CU_ASSERT_STRING_EQUAL(entry->value, value2); entry = hashMap_getEntry(map, neKey); CU_ASSERT_EQUAL(entry, NULL); entry = hashMap_getEntry(map, NULL); CU_ASSERT_EQUAL(entry, NULL); // Add third entry with NULL key hashMap_put(map, key3, value3); entry = hashMap_getEntry(map, key3); CU_ASSERT_EQUAL(entry->key, key3); CU_ASSERT_STRING_EQUAL(entry->value, value3); }
void test_hashMap_removeMapping(void) { char * key = "key"; char * value = "value"; char * key2 = NULL; char * value2 = "value2"; hash_map_entry_pt entry1; hash_map_entry_pt entry2; hash_map_entry_pt removed; hashMap_clear(map, false, false); // Add one entry hashMap_put(map, key, value); // Add second entry with null key hashMap_put(map, key2, value2); entry1 = hashMap_getEntry(map, key); entry2 = hashMap_getEntry(map, key2); CU_ASSERT_PTR_NOT_NULL_FATAL(entry1); CU_ASSERT_PTR_NOT_NULL_FATAL(entry2); removed = hashMap_removeMapping(map, entry1); CU_ASSERT_PTR_EQUAL(entry1, removed); CU_ASSERT_EQUAL(map->size, 1); removed = hashMap_removeMapping(map, entry2); CU_ASSERT_PTR_EQUAL(entry2, removed); CU_ASSERT_EQUAL(map->size, 0); // Remove unexisting entry for empty map hashMap_removeMapping(map, NULL); CU_ASSERT_EQUAL(map->size, 0); CU_ASSERT_TRUE(hashMap_isEmpty(map)); }
/// \TEST_CASE_ID{4} /// \TEST_CASE_TITLE{Test scope initialisation} /// \TEST_CASE_REQ{REQ-4} /// \TEST_CASE_DESC Checks if scopes can be added, but not twice static void testScope3(void) { int nr_exported; int nr_imported; array_list_pt epList; printf("\nBegin: %s\n", __func__); scopeInit("scope3.json", &nr_exported, &nr_imported); CHECK_EQUAL(2, nr_exported); discMock->getEPDescriptors(discMock->handle, &epList); // We export two services: Calculator and Calculator2, but only 1 has DFI bundle info CHECK_EQUAL(1, arrayList_size(epList)); for (unsigned int i = 0; i < arrayList_size(epList); i++) { endpoint_description_pt ep = (endpoint_description_pt) arrayList_get(epList, i); properties_pt props = ep->properties; hash_map_entry_pt entry = hashMap_getEntry(props, (void *)"key2"); char* value = (char*) hashMapEntry_getValue(entry); STRCMP_EQUAL("inaetics", value); } printf("End: %s\n", __func__); }
celix_status_t pubsubAdmin_removePublication(pubsub_admin_pt admin,pubsub_endpoint_pt pubEP){ celix_status_t status = CELIX_SUCCESS; int count = 0; printf("PSA_ZMQ: Removing publication [FWUUID=%s bundleID=%ld topic=%s]\n",pubEP->frameworkUUID,pubEP->serviceID,pubEP->topic); const char* fwUUID = NULL; bundleContext_getProperty(admin->bundle_context,OSGI_FRAMEWORK_FRAMEWORK_UUID,&fwUUID); if(fwUUID==NULL){ printf("PSA_ZMQ: Cannot retrieve fwUUID.\n"); return CELIX_INVALID_BUNDLE_CONTEXT; } char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic); if(strcmp(pubEP->frameworkUUID,fwUUID)==0){ celixThreadMutex_lock(&admin->localPublicationsLock); service_factory_pt factory = (service_factory_pt)hashMap_get(admin->localPublications,scope_topic); if(factory!=NULL){ topic_publication_pt pub = (topic_publication_pt)factory->handle; pubsub_topicPublicationRemovePublisherEP(pub,pubEP); } celixThreadMutex_unlock(&admin->localPublicationsLock); if(factory==NULL){ /* Maybe the endpoint was pending */ celixThreadMutex_lock(&admin->noSerializerPendingsLock); if(!arrayList_removeElement(admin->noSerializerPublications, pubEP)){ status = CELIX_ILLEGAL_STATE; } celixThreadMutex_unlock(&admin->noSerializerPendingsLock); } } else{ celixThreadMutex_lock(&admin->externalPublicationsLock); array_list_pt ext_pub_list = (array_list_pt)hashMap_get(admin->externalPublications,scope_topic); if(ext_pub_list!=NULL){ int i; bool found = false; for(i=0;!found && i<arrayList_size(ext_pub_list);i++){ pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i); found = pubsubEndpoint_equals(pubEP,p); if (found){ arrayList_remove(ext_pub_list,i); } } // Check if there are more publishers on the same endpoint (happens when 1 celix-instance with multiple bundles publish in same topic) for(i=0; i<arrayList_size(ext_pub_list);i++) { pubsub_endpoint_pt p = (pubsub_endpoint_pt)arrayList_get(ext_pub_list,i); if (strcmp(pubEP->endpoint,p->endpoint) == 0) { count++; } } if(arrayList_size(ext_pub_list)==0){ hash_map_entry_pt entry = hashMap_getEntry(admin->externalPublications,scope_topic); char* topic = (char*)hashMapEntry_getKey(entry); array_list_pt list = (array_list_pt)hashMapEntry_getValue(entry); hashMap_remove(admin->externalPublications,topic); arrayList_destroy(list); free(topic); } } celixThreadMutex_unlock(&admin->externalPublicationsLock); } /* Check if this publisher was connected to one of our subscribers*/ celixThreadMutex_lock(&admin->subscriptionsLock); topic_subscription_pt sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,scope_topic); if(sub!=NULL && pubEP->endpoint!=NULL && count == 0){ pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(sub,pubEP->endpoint); } /* And check also for ANY subscription */ topic_subscription_pt any_sub = (topic_subscription_pt)hashMap_get(admin->subscriptions,PUBSUB_ANY_SUB_TOPIC); if(any_sub!=NULL && pubEP->endpoint!=NULL && count == 0){ pubsub_topicSubscriptionAddDisconnectPublisherToPendingList(any_sub,pubEP->endpoint); } free(scope_topic); celixThreadMutex_unlock(&admin->subscriptionsLock); return status; }
celix_status_t pubsubAdmin_addPublication(pubsub_admin_pt admin, pubsub_endpoint_pt pubEP) { celix_status_t status = CELIX_SUCCESS; printf("PSA_ZMQ: Received publication [FWUUID=%s bundleID=%ld scope=%s, topic=%s]\n", pubEP->frameworkUUID, pubEP->serviceID, pubEP->scope, pubEP->topic); const char* fwUUID = NULL; bundleContext_getProperty(admin->bundle_context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID); if (fwUUID == NULL) { printf("PSA_ZMQ: Cannot retrieve fwUUID.\n"); return CELIX_INVALID_BUNDLE_CONTEXT; } char *scope_topic = createScopeTopicKey(pubEP->scope, pubEP->topic); if ((strcmp(pubEP->frameworkUUID, fwUUID) == 0) && (pubEP->endpoint == NULL)) { celixThreadMutex_lock(&admin->localPublicationsLock); service_factory_pt factory = (service_factory_pt) hashMap_get(admin->localPublications, scope_topic); if (factory == NULL) { topic_publication_pt pub = NULL; pubsub_serializer_service_t *best_serializer = NULL; if( (status=pubsubAdmin_getBestSerializer(admin, pubEP, &best_serializer)) == CELIX_SUCCESS){ status = pubsub_topicPublicationCreate(admin->bundle_context, pubEP, best_serializer, admin->ipAddress, admin->basePort, admin->maxPort, &pub); } else{ printf("PSA_ZMQ: Cannot find a serializer for publishing topic %s. Adding it to pending list.\n", pubEP->topic); celixThreadMutex_lock(&admin->noSerializerPendingsLock); arrayList_add(admin->noSerializerPublications,pubEP); celixThreadMutex_unlock(&admin->noSerializerPendingsLock); } if (status == CELIX_SUCCESS) { status = pubsub_topicPublicationStart(admin->bundle_context, pub, &factory); if (status == CELIX_SUCCESS && factory != NULL) { hashMap_put(admin->localPublications, strdup(scope_topic), factory); connectTopicPubSubToSerializer(admin, best_serializer, pub, true); } } else { printf("PSA_ZMQ: Cannot create a topicPublication for scope=%s, topic=%s (bundle %ld).\n", pubEP->scope, pubEP->topic, pubEP->serviceID); } } else { //just add the new EP to the list topic_publication_pt pub = (topic_publication_pt) factory->handle; pubsub_topicPublicationAddPublisherEP(pub, pubEP); } celixThreadMutex_unlock(&admin->localPublicationsLock); } else{ celixThreadMutex_lock(&admin->externalPublicationsLock); array_list_pt ext_pub_list = (array_list_pt) hashMap_get(admin->externalPublications, scope_topic); if (ext_pub_list == NULL) { arrayList_create(&ext_pub_list); hashMap_put(admin->externalPublications, strdup(scope_topic), ext_pub_list); } arrayList_add(ext_pub_list, pubEP); celixThreadMutex_unlock(&admin->externalPublicationsLock); } /* Re-evaluate the pending subscriptions */ celixThreadMutex_lock(&admin->pendingSubscriptionsLock); hash_map_entry_pt pendingSub = hashMap_getEntry(admin->pendingSubscriptions, scope_topic); if (pendingSub != NULL) { //There were pending subscription for the just published topic. Let's connect them. char* topic = (char*) hashMapEntry_getKey(pendingSub); array_list_pt pendingSubList = (array_list_pt) hashMapEntry_getValue(pendingSub); int i; for (i = 0; i < arrayList_size(pendingSubList); i++) { pubsub_endpoint_pt subEP = (pubsub_endpoint_pt) arrayList_get(pendingSubList, i); pubsubAdmin_addSubscription(admin, subEP); } hashMap_remove(admin->pendingSubscriptions, scope_topic); arrayList_clear(pendingSubList); arrayList_destroy(pendingSubList); free(topic); } celixThreadMutex_unlock(&admin->pendingSubscriptionsLock); /* Connect the new publisher to the subscription for his topic, if there is any */ celixThreadMutex_lock(&admin->subscriptionsLock); topic_subscription_pt sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, scope_topic); if (sub != NULL && pubEP->endpoint != NULL) { pubsub_topicSubscriptionAddConnectPublisherToPendingList(sub, pubEP->endpoint); } /* And check also for ANY subscription */ topic_subscription_pt any_sub = (topic_subscription_pt) hashMap_get(admin->subscriptions, PUBSUB_ANY_SUB_TOPIC); if (any_sub != NULL && pubEP->endpoint != NULL) { pubsub_topicSubscriptionAddConnectPublisherToPendingList(any_sub, pubEP->endpoint); } free(scope_topic); celixThreadMutex_unlock(&admin->subscriptionsLock); return status; }