From a38a77af0ca118bef1362ed5977edbe5d71526c9 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Tue, 28 Nov 2023 15:04:36 +0800 Subject: [PATCH 01/29] Use the real hostname for remote service --- .../gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc | 6 +++++- .../gtest/src/DiscoveryZeroconfWatcherTestSuite.cc | 8 ++++---- .../src/discovery_zeroconf_announcer.c | 6 +++++- .../src/discovery_zeroconf_constants.h | 11 ++++------- .../src/remote_service_admin_dfi.c | 1 + .../rsa_spi/include/remote_constants.h | 5 +++++ 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index 66caf1fbf..606b38bdf 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -150,7 +150,11 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, (void)context; EXPECT_EQ(errorCode, kDNSServiceErr_NoError); - EXPECT_STREQ(host, DZC_HOST_DEFAULT); + char hostname[UINT8_MAX+1] = {0}; + gethostname(hostname, UINT8_MAX); + char expectHost[NI_MAXHOST]= {0}; + (void)snprintf(expectHost, NI_MAXHOST, "%s.local.", hostname); + EXPECT_STREQ(host, expectHost); EXPECT_EQ(port, ntohs(DZC_PORT_DEFAULT)); celix_properties_t *prop = (celix_properties_t *)context; int cnt = TXTRecordGetCount(txtLen, txtRecord); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 677d7c8bd..5778f78c6 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -196,7 +196,7 @@ static DNSServiceRef RegisterTestService(void) { TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", DZC_HOST_DEFAULT, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); return dsRef; @@ -305,7 +305,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_self_fw_service", DZC_SERVICE_PRIMARY_TYPE, "local", DZC_HOST_DEFAULT, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_self_fw_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); @@ -333,7 +333,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", DZC_HOST_DEFAULT, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); TXTRecordDeallocate(&txtRecord); @@ -379,7 +379,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", DZC_HOST_DEFAULT, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index f0cf81eb1..b51b6898e 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -77,6 +77,7 @@ typedef struct announce_endpoint_entry { DNSServiceRef registerRef; unsigned int uid; int ifIndex; + int port; const char *serviceName; char serviceType[64]; bool announced; @@ -260,6 +261,8 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en entry->ifIndex = DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT; } + entry->port = celix_properties_getAsLong(endpoint->properties, CELIX_RSA_NETWORK_PORT, DZC_PORT_DEFAULT); + const char *serviceSubType = celix_properties_get(endpoint->properties, DZC_SERVICE_TYPE_KEY, NULL); if (serviceSubType != NULL) { int bytes = snprintf(entry->serviceType, sizeof(entry->serviceType), DZC_SERVICE_PRIMARY_TYPE",%s", serviceSubType); @@ -275,6 +278,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en //Remove properties that remote service does not need celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_INTERFACES); + celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_PORT); celix_properties_unset(entry->properties, DZC_SERVICE_TYPE_KEY); entry->serviceName = celix_properties_get(entry->properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL); if (entry->serviceName == NULL) { @@ -398,7 +402,7 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno break; } celix_logHelper_info(announcer->logHelper, "Announcer: Register service %s on interface %d.", instanceName, entry->ifIndex); - dnsErr = DNSServiceRegister(&dsRef, kDNSServiceFlagsShareConnection, entry->ifIndex, instanceName, entry->serviceType, "local", DZC_HOST_DEFAULT, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, announcer); + dnsErr = DNSServiceRegister(&dsRef, kDNSServiceFlagsShareConnection, entry->ifIndex, instanceName, entry->serviceType, "local", NULL, htons(entry->port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, announcer); if (dnsErr == kDNSServiceErr_NoError) { registered = true; } else { diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h index d061aee44..f41bcbcc7 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h @@ -33,13 +33,13 @@ extern "C" { /** * mDNS service name for celix service. - * About mDNS service name, see rfc6363 section 4.1.2 and section 7 + * About mDNS service name, see rfc6763 section 4.1.2 and section 7 */ #define DZC_SERVICE_PRIMARY_TYPE "_celix-rpc._udp" /** * mDNS service subtype for celix.service, it can be null. - * About mDNS service subtype, see rfc6363 section 7.1 + * About mDNS service subtype, see rfc6763 section 7.1 * The subtype mechanism can be illustrated with some examples using the dns-sd command-line tool: * If we register the following three services: * % dns-sd -R service1 _celix-rpc._udp local 1001 @@ -53,13 +53,10 @@ extern "C" { #define DZC_SERVICE_TYPE_KEY "DZC_SERVICE_TYPE_KEY" /** - * Host name and port for mDNS service. + * The default port for mDNS service. * - * To reduce the operation of conversion between host name and address info(ip and port). - * we set the address info to txt record, and set a dummy value("celix_rpc_dumb_host.local." - * and "50009") to the host name and port for mDNS service. + * It is a dummy value, it is used for the remote service that IPC is not network based(eg:shared memory). */ -#define DZC_HOST_DEFAULT "celix_rpc_dumb_host.local." #define DZC_PORT_DEFAULT 50009 /** 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 index e8c34e3ec..dc9a02f47 100644 --- 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 @@ -770,6 +770,7 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic if (admin->discoveryInterface != NULL) { celix_properties_set(endpointProperties, CELIX_RSA_NETWORK_INTERFACES, admin->discoveryInterface); } + celix_properties_set(endpointProperties, CELIX_RSA_NETWORK_PORT, admin->port); if (props != NULL) { CELIX_PROPERTIES_ITERATE(props, iter) { diff --git a/bundles/remote_services/rsa_spi/include/remote_constants.h b/bundles/remote_services/rsa_spi/include/remote_constants.h index efc490157..cc9de6f11 100644 --- a/bundles/remote_services/rsa_spi/include/remote_constants.h +++ b/bundles/remote_services/rsa_spi/include/remote_constants.h @@ -46,4 +46,9 @@ static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location"; static const char * const CELIX_RSA_NETWORK_INTERFACES = "org.apache.celix.rsa.network.interfaces"; +/** + * Remote service admin property identifying the network port of the exported service. + */ +#define CELIX_RSA_NETWORK_PORT "org.apache.celix.rsa.network.port" + #endif /* REMOTE_CONSTANTS_H_ */ From 0a92022763c51c3a8911cf4a97cedc83e411e9e8 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 1 Dec 2023 16:15:24 +0800 Subject: [PATCH 02/29] Remove uuid in the service instance name --- .../src/discovery_zeroconf_announcer.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index b51b6898e..d49b0e671 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -75,7 +75,6 @@ struct discovery_zeroconf_announcer { typedef struct announce_endpoint_entry { celix_properties_t *properties; DNSServiceRef registerRef; - unsigned int uid; int ifIndex; int port; const char *serviceName; @@ -238,13 +237,6 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en } entry->registerRef = NULL; entry->announced = false; - // The entry->uid is used in mDNS instance name. - // To avoid instance name conflicts on localonly interface, - // in our code, the instance name consists of the service name and the UID. - // Because the maximum size of an mDNS instance name is 64 bytes, so we use the hash of endpoint->id. - // Don't worry about the uniqueness of the endpoint->id hash, it is only used to reduce the probability of instance name conflicts. - // If a conflict occurs, mDNS daemon will resolve it. - entry->uid = celix_utils_stringHash(endpoint->id); const char *ifName = celix_properties_get(endpoint->properties, CELIX_RSA_NETWORK_INTERFACES, NULL); if (ifName != NULL) { if (strcmp(ifName, "all") == 0) { @@ -392,11 +384,16 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno DNSServiceErrorType dnsErr; char instanceName[64] = {0}; bool registered = false; - int conflictCnt = 0; + int conflictCnt = 1; DNSServiceRef dsRef; do { dsRef = announcer->sharedRef;//DNSServiceRegister will set a new value for dsRef - int bytes = snprintf(instanceName, sizeof(instanceName), "%s-%X", entry->serviceName, entry->uid + conflictCnt); + int bytes = 0; + if (conflictCnt == 1) { + bytes = snprintf(instanceName, sizeof(instanceName), "%s", entry->serviceName); + } else { + bytes = snprintf(instanceName, sizeof(instanceName), "%s(%d)", entry->serviceName, conflictCnt); + } if (bytes >= sizeof(instanceName)) { celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service name for %s.", entry->serviceName); break; From 28e775bb0e6590c971bfecb0eb48e2a558069edf Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Tue, 5 Dec 2023 15:28:46 +0800 Subject: [PATCH 03/29] Add process ID to service instance name for easier debugging --- .../discovery_zeroconf/src/discovery_zeroconf_announcer.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index d49b0e671..b3f5c0473 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +61,7 @@ struct discovery_zeroconf_announcer { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; + pid_t pid; char fwUuid[64]; endpoint_listener_t epListener; long epListenerSvcId; @@ -98,6 +100,7 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce } announcer->ctx = ctx; announcer->logHelper = logHelper; + announcer->pid = getpid(); announcer->sharedRef = NULL; announcer->eventFd = eventfd(0, 0); @@ -390,9 +393,9 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno dsRef = announcer->sharedRef;//DNSServiceRegister will set a new value for dsRef int bytes = 0; if (conflictCnt == 1) { - bytes = snprintf(instanceName, sizeof(instanceName), "%s", entry->serviceName); + bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld", entry->serviceName, (long)announcer->pid); } else { - bytes = snprintf(instanceName, sizeof(instanceName), "%s(%d)", entry->serviceName, conflictCnt); + bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld(%d)", entry->serviceName, (long)announcer->pid, conflictCnt); } if (bytes >= sizeof(instanceName)) { celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service name for %s.", entry->serviceName); From 92ce33ad8efe915c45bf84e6eac80bd00ce560da Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 8 Dec 2023 17:07:36 +0800 Subject: [PATCH 04/29] Resolve ip addresses and set it to endpoint description --- .../src/discovery_zeroconf_announcer.c | 41 +- .../src/discovery_zeroconf_constants.h | 2 +- .../src/discovery_zeroconf_watcher.c | 420 ++++++++++++++++-- 3 files changed, 410 insertions(+), 53 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index b3f5c0473..3dcb1874b 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -233,6 +233,34 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en celix_logHelper_info(announcer->logHelper, "Announcer: Add endpoint for %s(%s).", endpoint->serviceName, endpoint->id); + const char *importedConfigs = celix_properties_get(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + if (importedConfigs == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: No imported configs for %s.", endpoint->serviceName); + return CELIX_ILLEGAL_ARGUMENT; + } + + const char *ifName = NULL; + int port = DZC_PORT_DEFAULT; + celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); + char *savePtr = NULL; + char *token = strtok_r(importedConfigsCopy, ",", &savePtr); + while (token != NULL && port == DZC_PORT_DEFAULT) { + //We only need to get one imported config, because all imported configs listed in this property must be synonymous(see https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#d0e1152). + celix_autofree char *importedConfigPortKey = NULL; + if(asprintf(&importedConfigPortKey, "%s.port", celix_utils_trimInPlace(token)) < 0) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create imported config port key."); + return CELIX_ENOMEM; + } + celix_autofree char *importedConfigIfNameKey = NULL; + if(asprintf(&importedConfigIfNameKey, "%s.ifname", celix_utils_trimInPlace(token)) < 0) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create imported config ifname key."); + return CELIX_ENOMEM; + } + port = celix_properties_getAsLong(endpoint->properties, importedConfigPortKey, DZC_PORT_DEFAULT); + ifName = celix_properties_get(endpoint->properties, importedConfigIfNameKey, NULL); + token = strtok_r(NULL, ",", &savePtr); + } + celix_autofree announce_endpoint_entry_t *entry = (announce_endpoint_entry_t *)calloc(1, sizeof(*entry)); if (entry == NULL) { celix_logHelper_error(announcer->logHelper, "Announcer: Failed to alloc endpoint entry."); @@ -240,7 +268,6 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en } entry->registerRef = NULL; entry->announced = false; - const char *ifName = celix_properties_get(endpoint->properties, CELIX_RSA_NETWORK_INTERFACES, NULL); if (ifName != NULL) { if (strcmp(ifName, "all") == 0) { entry->ifIndex = kDNSServiceInterfaceIndexAny; @@ -250,13 +277,15 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en entry->ifIndex = kDNSServiceInterfaceIndexLocalOnly; } else { entry->ifIndex = if_nametoindex(ifName); - entry->ifIndex = entry->ifIndex == 0 ? DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT : entry->ifIndex; + if (entry->ifIndex == 0) { + celix_logHelper_error(announcer->logHelper, "Announcer: Invalid network interface name %s.", ifName); + return CELIX_ILLEGAL_ARGUMENT; + } } } else { entry->ifIndex = DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT; } - - entry->port = celix_properties_getAsLong(endpoint->properties, CELIX_RSA_NETWORK_PORT, DZC_PORT_DEFAULT); + entry->port = port; const char *serviceSubType = celix_properties_get(endpoint->properties, DZC_SERVICE_TYPE_KEY, NULL); if (serviceSubType != NULL) { @@ -272,7 +301,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en celix_autoptr(celix_properties_t) properties = entry->properties = celix_properties_copy(endpoint->properties); //Remove properties that remote service does not need - celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_INTERFACES); + celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_INTERFACES);//TODO celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_PORT); celix_properties_unset(entry->properties, DZC_SERVICE_TYPE_KEY); entry->serviceName = celix_properties_get(entry->properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL); @@ -378,7 +407,7 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%zu", celix_properties_size(entry->properties) + 1); - (void)TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + (void)TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr);//TODO add txtver if (!discoveryZeroconfAnnouncer_copyPropertiesToTxtRecord(announcer, &propIter, &txtRecord, sizeof(txtBuf), splitTxtRecord)) { TXTRecordDeallocate(&txtRecord); continue; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h index f41bcbcc7..d208e5a99 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h @@ -57,7 +57,7 @@ extern "C" { * * It is a dummy value, it is used for the remote service that IPC is not network based(eg:shared memory). */ -#define DZC_PORT_DEFAULT 50009 +#define DZC_PORT_DEFAULT 65535 /** * The size of celix service properties. diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index f2380eff1..7ee49579f 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -41,11 +43,14 @@ #include #include #include +#include #define DZC_EP_JITTER_INTERVAL 10 #define DZC_MAX_RESOLVED_TIMEOUT 5 #define DZC_MAX_RESOLVED_CNT 10 +#define DZC_MAX_HOSTNAME_LEN 255 //The fully qualified domain name of the host, eg: "MyComputer.local". RFC 1034 specifies that this name is limited to 255 bytes. + struct discovery_zeroconf_watcher { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; @@ -56,6 +61,7 @@ struct discovery_zeroconf_watcher { int eventFd; celix_thread_t watchEPThread; celix_string_hash_map_t *watchedServices;//key:instanceName+interfaceId, val:watched_service_entry_t* + celix_string_hash_map_t *watchedHosts;//key:hostname+interfaceId, val:watched_host_entry_t* celix_thread_mutex_t mutex;//projects below bool running; celix_string_hash_map_t *watchedEndpoints;//key:endpoint id, val:watched_endpoint_entry_t* @@ -64,6 +70,9 @@ struct discovery_zeroconf_watcher { typedef struct watched_endpoint_entry { endpoint_description_t *endpoint; + char *hostname; + int ifIndex; + const char *ipAddressesStr; struct timespec expiredTime; }watched_endpoint_entry_t; @@ -72,6 +81,7 @@ typedef struct watched_service_entry { const char *endpointId; int ifIndex; char instanceName[64];//The instanceName must be 1-63 bytes + char *hostname; bool resolved; struct timespec resolvedStartTime; int resolvedCnt; @@ -83,6 +93,16 @@ typedef struct watched_epl_entry { celix_filter_t *filter; }watched_epl_entry_t; +typedef struct watched_host_entry { + DNSServiceRef sdRef; + char *hostname; + int ifIndex; + celix_string_hash_map_t *ipAddresses;//key:ip address, val:true(ipv4)/false(ipv6) + struct timespec activeStartTime; + bool markDeleted; +}watched_host_entry_t; + +//TODO use subtypes to browse static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props); static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props); static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context); @@ -249,14 +269,38 @@ static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const ce return; } +static bool shouldResolveHostInfo(celix_properties_t *properties) { + const char *importedConfigs = celix_properties_get(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + if (importedConfigs == NULL) { + return false; + } + celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); + if (importedConfigsCopy == NULL) { + return true; + } + char *savePtr = NULL; + char *token = strtok_r(importedConfigsCopy, ",", &savePtr); + while (token != NULL) { + char *configType = celix_utils_trimInPlace(token); + celix_autofree char *importedConfigPortKey = NULL; + if (asprintf(&importedConfigPortKey, "%s.port", configType) < 0) { + return true; + } + if (celix_properties_get(properties, importedConfigPortKey, NULL) != NULL) { + return true; + } + token = strtok_r(NULL, ",", &savePtr); + } + return false; +} + static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { (void)sdRef;//unused (void)flags;//unused (void)interfaceIndex;//unused - (void)host;//unused (void)port;//unused (void)fullname;//unused - if (errorCode != kDNSServiceErr_NoError) { + if (errorCode != kDNSServiceErr_NoError || strlen(host) > DZC_MAX_HOSTNAME_LEN) { return; } watched_service_entry_t *svcEntry = (watched_service_entry_t *)context; @@ -280,6 +324,12 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, long propSize = celix_properties_getAsLong(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0); if (propSize == celix_properties_size(properties)) { + if (shouldResolveHostInfo(properties)) { + svcEntry->hostname = celix_utils_strdup(host); + if (svcEntry->hostname == NULL) { + return; + } + } celix_properties_unset(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY);//Service endpoint do not need it svcEntry->resolved = true; } @@ -322,6 +372,7 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, svcEntry->endpointId = NULL; svcEntry->resolved = false; strcpy(svcEntry->instanceName, instanceName); + svcEntry->hostname = NULL; svcEntry->ifIndex = (int)interfaceIndex; svcEntry->resolvedStartTime.tv_sec = INT_MAX; svcEntry->resolvedCnt = 0; @@ -334,6 +385,7 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceRefDeallocate(svcEntry->resolveRef); } celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry->hostname); free(svcEntry); } } @@ -365,6 +417,251 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ return; } +static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, + const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { + (void)sdRef;//unused + (void)ttl;//unused + watched_host_entry_t *hostEntry = (watched_host_entry_t *)context; + assert(hostEntry != NULL); + if (errorCode == kDNSServiceErr_NoSuchRecord) { + //If localonly interface cannot found record, then add localhost address.Because the mDNSResponder will skip the loopback interface,if it found a normal interface. + if (ifIndex == kDNSServiceInterfaceIndexLocalOnly) { + if (celix_stringHashMap_size(hostEntry->ipAddresses) == 0) { + celix_stringHashMap_putBool(hostEntry->ipAddresses, "127.0.0.1", true); + } + hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); + } + return; + } + if (errorCode != kDNSServiceErr_NoError || address != NULL || (address->sa_family != AF_INET && address->sa_family != AF_INET6)) { + return; + } + + char ip[INET6_ADDRSTRLEN] = {0}; + if (address->sa_family == AF_INET) { + inet_ntop(AF_INET, &((struct sockaddr_in *)address)->sin_addr, ip, sizeof(ip)); + } else if (address->sa_family == AF_INET6) { + inet_ntop(AF_INET6, &((struct sockaddr_in6 *)address)->sin6_addr, ip, sizeof(ip)); + } + + if (flags & kDNSServiceFlagsAdd) { + celix_stringHashMap_putBool(hostEntry->ipAddresses, ip, address->sa_family == AF_INET); + } else { + celix_stringHashMap_remove(hostEntry->ipAddresses, ip); + } + + if (celix_stringHashMap_size(hostEntry->ipAddresses) > 0) { + hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); + hostEntry->activeStartTime.tv_sec += 2;//If the host information does not change within 2 seconds, we will use the host information to create endpoint description. + } else { + hostEntry->activeStartTime.tv_sec = INT_MAX; + hostEntry->activeStartTime.tv_nsec = 0; + } + + return; +} + +static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher) { + //mark deleted hosts + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { + watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue; + hostEntry->markDeleted = true; + } + + //add new hosts + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { + watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; + if (svcEntry->resolved && svcEntry->hostname != NULL) { + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); + if (celix_stringHashMap_hasKey(watcher->watchedHosts, key)) { + watched_host_entry_t *hostEntry = celix_stringHashMap_get(watcher->watchedHosts, key); + hostEntry->markDeleted = false; + continue; + } else { + celix_autofree watched_host_entry_t *hostEntry = (watched_host_entry_t *)calloc(1, sizeof(*hostEntry)); + if (hostEntry == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc host entry for %s.", svcEntry->instanceName); + continue; + } + celix_autoptr(celix_string_hash_map_t) ipAddresses = hostEntry->ipAddresses = celix_stringHashMap_create(); + if (ipAddresses == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc ip address list for %s.", svcEntry->instanceName); + continue; + } + celix_autofree char *hostname = hostEntry->hostname = celix_utils_strdup(svcEntry->hostname); + if (hostname == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create hostname for endpoint %s.", svcEntry->instanceName); + continue; + } + hostEntry->sdRef = NULL; + hostEntry->activeStartTime.tv_sec = INT_MAX; + hostEntry->ifIndex = svcEntry->ifIndex; + hostEntry->markDeleted = false; + if (celix_stringHashMap_put(watcher->watchedHosts, key, hostEntry) == CELIX_SUCCESS) { + celix_steal_ptr(hostname); + celix_steal_ptr(ipAddresses); + celix_steal_ptr(hostEntry); + } + } + } + } + + //delete hosts + celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedHosts); + while (!celix_stringHashMapIterator_isEnd(&iter)) { + watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue; + if (hostEntry->markDeleted) { + celix_stringHashMapIterator_remove(&iter); + if (hostEntry->sdRef) { + DNSServiceRefDeallocate(hostEntry->sdRef); + } + celix_stringHashMap_destroy(hostEntry->ipAddresses); + free(hostEntry->hostname); + free(hostEntry); + } else { + celix_stringHashMapIterator_next(&iter); + } + } + + //resolve hosts + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter1) { + watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; + if (watcher->sharedRef && hostEntry->sdRef == NULL) { + hostEntry->sdRef = watcher->sharedRef; + DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); + if (dnsErr != kDNSServiceErr_NoError) { + hostEntry->sdRef = NULL; + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get address info for %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, dnsErr); + } + } + } + return; +} + +static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", hostname, ifIndex); + watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + if (hostEntry == NULL) { + return false; + } + if (celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime) > 0) { + return true; + } + return false; +} + +static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zeroconf_watcher_t *watcher, watched_service_entry_t *svcEntry, watched_endpoint_entry_t **epOut) { + celix_autoptr(celix_properties_t) properties = celix_properties_copy(svcEntry->txtRecord); + if (properties == NULL) { + return CELIX_ENOMEM; + } + celix_autoptr(endpoint_description_t) ep = NULL; + int status = endpointDescription_create(properties, &ep); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create endpoint description."); + return status; + } + celix_steal_ptr(properties);//properties now owned by ep + + celix_autofree watched_endpoint_entry_t *epEntry = (watched_endpoint_entry_t *)calloc(1, sizeof(*epEntry)); + if (epEntry == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher:Failed to alloc endpoint entry."); + return CELIX_ENOMEM; + } + epEntry->endpoint = ep; + epEntry->ifIndex = svcEntry->ifIndex; + epEntry->expiredTime.tv_sec = INT_MAX; + epEntry->ipAddressesStr = NULL; + epEntry->hostname = NULL; + + if (svcEntry->hostname == NULL) {//if no need to resolve host info, then return + celix_steal_ptr(ep); + *epOut = celix_steal_ptr(epEntry); + return CELIX_SUCCESS; + } + + celix_autofree char *hostname = epEntry->hostname = celix_utils_strdup(svcEntry->hostname); + if (hostname == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create hostname for endpoint %s.", svcEntry->instanceName); + return CELIX_ENOMEM; + } + + //fill ip address list property + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); + celix_autofree char *ipAddressesStr = NULL; + watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + if (hostEntry != NULL) { + CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { + const char *ip = iter.key; + char *tmp= NULL; + if (ipAddressesStr == NULL) { + tmp = celix_utils_strdup(ip); + } else { + asprintf(&tmp, "%s,%s", ipAddressesStr, ip); + } + if (tmp == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); + return CELIX_ENOMEM; + } + free(ipAddressesStr); + ipAddressesStr = tmp; + } + } + if (ipAddressesStr == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get ip address list."); + return CELIX_ILLEGAL_STATE; + } + + const char *importedConfigs = celix_properties_get(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + if (importedConfigs == NULL) { + return CELIX_ILLEGAL_ARGUMENT; + } + celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); + if (importedConfigsCopy == NULL) { + return CELIX_ENOMEM; + } + char *savePtr = NULL; + char *token = strtok_r(importedConfigsCopy, ",", &savePtr); + while (token != NULL && ipAddressesStr != NULL) { + char *configType = celix_utils_trimInPlace(token); + celix_autofree char *importedConfigPortKey = NULL; + if(asprintf(&importedConfigPortKey, "%s.port", configType) < 0) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create imported config port key."); + return CELIX_ENOMEM; + } + celix_autofree char *importedConfigIpAddressListKey = NULL; + if(asprintf(&importedConfigIpAddressListKey, "%s.ipaddresses", configType) < 0) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create imported config ip address list key."); + return CELIX_ENOMEM; + } + //If the service.imported.configs contains the port property, then add the ipaddresses property + if (celix_properties_get(properties, importedConfigPortKey, NULL) != NULL) { + celix_autofree char *tmp = celix_utils_strdup(ipAddressesStr); + if (tmp == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); + return CELIX_ENOMEM; + } + status = celix_properties_setWithoutCopy(properties, importedConfigIpAddressListKey, tmp); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); + return status; + } + epEntry->ipAddressesStr = tmp; + celix_steal_ptr(tmp); + celix_steal_ptr(importedConfigIpAddressListKey); + } + } + + celix_steal_ptr(hostname); + celix_steal_ptr(ep); + *epOut = celix_steal_ptr(epEntry); + + return CELIX_SUCCESS; +} + static void discoveryZeroConfWatcher_informEPLs(discovery_zeroconf_watcher_t *watcher, endpoint_description_t *endpoint, bool epAdded) { CELIX_LONG_HASH_MAP_ITERATE(watcher->epls, iter) { watched_epl_entry_t *eplEntry = (watched_epl_entry_t *)iter.value.ptrValue; @@ -381,11 +678,36 @@ static void discoveryZeroConfWatcher_informEPLs(discovery_zeroconf_watcher_t *wa return; } -static bool discoveryZeroconfWatcher_hasWatchedServiceForEndpoint(discovery_zeroconf_watcher_t *watcher, const char *endpointId) { - CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { - watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; - if (svcEntry->endpointId != NULL && strcmp(svcEntry->endpointId, endpointId) == 0) { - return true; +static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_zeroconf_watcher_t *watcher, watched_endpoint_entry_t *endpointEntry) { + if (endpointEntry->hostname == NULL) { + return false; + } + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", endpointEntry->hostname, endpointEntry->ifIndex); + watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + if (hostEntry == NULL) { + return true; + } + if (celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime) < 0) { + return false; + } + if (endpointEntry->ipAddressesStr != NULL) { + celix_autofree char *ipAddresses = celix_utils_strdup(endpointEntry->ipAddressesStr); + if (ipAddresses != NULL) { + char *savePtr = NULL; + char *token = strtok_r(ipAddresses, ",", &savePtr); + int ipCnt = 0; + while (token != NULL) { + ipCnt ++; + char *ip = celix_utils_trimInPlace(token); + if (!celix_stringHashMap_hasKey(hostEntry->ipAddresses, ip)) { + return true; + } + token = strtok_r(NULL, ",", &savePtr); + } + if (ipCnt != celix_stringHashMap_size(hostEntry->ipAddresses)) { + return true; + } } } return false; @@ -408,6 +730,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher DNSServiceRefDeallocate(svcEntry->resolveRef); } celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry->hostname); free(svcEntry); continue; } @@ -417,56 +740,51 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher celixThreadMutex_lock(&watcher->mutex); + //remove expired endpoint + celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); + while (!celix_stringHashMapIterator_isEnd(&epIter)) { + epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; + if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry) + || celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime) >= DZC_EP_JITTER_INTERVAL) { + epEntry->expiredTime.tv_sec = INT_MAX; + celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); + celix_stringHashMap_remove(watcher->watchedEndpoints, svcEntry->endpointId); + discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); + endpointDescription_destroy(epEntry->endpoint); + free(epEntry); + continue; + } else if (epEntry->expiredTime.tv_sec == INT_MAX) { + epEntry->expiredTime = celix_gettime(CLOCK_MONOTONIC); + } + celix_stringHashMapIterator_next(&epIter); + } + //add new endpoint CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { svcEntry = (watched_service_entry_t *)iter.value.ptrValue; - if (svcEntry->endpointId != NULL && svcEntry->resolved) { + if (svcEntry->endpointId != NULL && svcEntry->resolved && (svcEntry->hostname == NULL || discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex))) { epEntry = (watched_endpoint_entry_t *)celix_stringHashMap_get(watcher->watchedEndpoints, svcEntry->endpointId); if (epEntry == NULL) { - celix_properties_t *properties = celix_properties_copy(svcEntry->txtRecord); - endpoint_description_t *ep = NULL; - celix_status_t status = endpointDescription_create(properties,&ep); - if (status != CELIX_SUCCESS) { - celix_properties_destroy(properties); + celix_status_t status = discoveryZeroConfWatcher_createEndpointEntryForService(watcher, svcEntry, &epEntry); + if (status != CELIX_SUCCESS && status != CELIX_ENOMEM) { // If properties invalid,endpointDescription_create will return error. // Avoid endpointDescription_create again, set svcEntry->resolved false. svcEntry->resolved = false; continue; } - celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %s.", ep->serviceName,ep->frameworkUUID); - epEntry = (watched_endpoint_entry_t *)calloc(1, sizeof(*epEntry)); - if (epEntry == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher:Failed to alloc endpoint entry."); - //It will free ep and properties - endpointDescription_destroy(ep); - continue; + celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s.", svcEntry->instanceName); + if (celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry) == CELIX_SUCCESS) { + discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, true); + } else { + endpointDescription_destroy(epEntry->endpoint); + free(epEntry->hostname); + free(epEntry); } - epEntry->endpoint = ep; - discoveryZeroConfWatcher_informEPLs(watcher, ep, true); - celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry); - } - epEntry->expiredTime.tv_sec = INT_MAX; - } - } - - //remove expired endpoint - celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); - while (!celix_stringHashMapIterator_isEnd(&epIter)) { - epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; - const char *endpointId = epIter.key; - if (!discoveryZeroconfWatcher_hasWatchedServiceForEndpoint(watcher, endpointId)) { - if (epEntry->expiredTime.tv_sec == INT_MAX) { - epEntry->expiredTime = celix_gettime(CLOCK_MONOTONIC); - } else if (celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime) >= DZC_EP_JITTER_INTERVAL) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); - celix_stringHashMapIterator_remove(&epIter); - discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); - endpointDescription_destroy(epEntry->endpoint); - free(epEntry); - continue; + } else { + epEntry->expiredTime.tv_sec = INT_MAX; + epEntry->expiredTime.tv_nsec = 0; } } - celix_stringHashMapIterator_next(&epIter); } celixThreadMutex_unlock(&watcher->mutex); @@ -495,10 +813,18 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc } CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; - //no need free svcEntry->resolveRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has do it. + //no need free svcEntry->resolveRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry->hostname); free(svcEntry); } + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { + watched_host_entry_t *hostEntry = (watched_host_entry_t *) iter.value.ptrValue; + //no need free hostEntry->sdRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. + celix_stringHashMap_destroy(hostEntry->ipAddresses); + free(hostEntry->hostname); + free(hostEntry); + } celix_stringHashMap_clear(watcher->watchedServices); return; } @@ -550,7 +876,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { assert(dsFd >= 0); FD_SET(dsFd, &readfds); maxFd = MAX(maxFd, dsFd); - timeout.tv_sec = 1; + timeout.tv_sec = 1;//TODO get next timeout timeout.tv_usec = 0; } else { dsFd = -1; @@ -570,9 +896,11 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { } } else if (result == -1 && errno != EINTR) { celix_logHelper_error(watcher->logHelper, "Watcher: Error Selecting event, %d.", errno); + sleep(1);//avoid busy loop } discoveryZeroconfWatcher_resolveServices(watcher); + discoveryZeroconfWatcher_refreshHostsInfo(watcher); discoveryZeroconfWatcher_refreshEndpoints(watcher); celixThreadMutex_lock(&watcher->mutex); From 0705bf5ffb9e94857b6f96bb7bdcb8d5b9d8405e Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 8 Dec 2023 19:23:56 +0800 Subject: [PATCH 05/29] Resolve ip addresses and set it to endpoint description --- .../src/discovery_zeroconf_watcher.c | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 7ee49579f..1e965341b 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -145,6 +145,8 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi celix_autoptr(celix_string_hash_map_t) watchedEndpoints = watcher->watchedEndpoints = celix_stringHashMap_createWithOptions(&epOpts); assert(watcher->watchedEndpoints); + watcher->watchedHosts = celix_stringHashMap_create(); + assert(watcher->watchedHosts != NULL); celix_string_hash_map_create_options_t svcOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; celix_autoptr(celix_string_hash_map_t) watchedServices = watcher->watchedServices = celix_stringHashMap_createWithOptions(&svcOpts); @@ -195,6 +197,8 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { celix_longHashMap_destroy(watcher->epls); assert(celix_stringHashMap_size(watcher->watchedServices) == 0); celix_stringHashMap_destroy(watcher->watchedServices); + assert(celix_stringHashMap_size(watcher->watchedHosts) == 0); + celix_stringHashMap_destroy(watcher->watchedHosts); assert(celix_stringHashMap_size(watcher->watchedEndpoints) == 0); celix_stringHashMap_destroy(watcher->watchedEndpoints); celixThreadMutex_destroy(&watcher->mutex); @@ -461,6 +465,12 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ return; } +static watched_host_entry_t *discoveryZeroconfWatcher_getHostEntry(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", hostname, ifIndex); + return (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); +} + static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher) { //mark deleted hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { @@ -471,15 +481,13 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher //add new hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; - if (svcEntry->resolved && svcEntry->hostname != NULL) { - char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int - (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); - if (celix_stringHashMap_hasKey(watcher->watchedHosts, key)) { - watched_host_entry_t *hostEntry = celix_stringHashMap_get(watcher->watchedHosts, key); + if (svcEntry->hostname != NULL) { + celix_autofree watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, svcEntry->hostname, svcEntry->ifIndex); + if (hostEntry != NULL) { hostEntry->markDeleted = false; - continue; + celix_steal_ptr(hostEntry); } else { - celix_autofree watched_host_entry_t *hostEntry = (watched_host_entry_t *)calloc(1, sizeof(*hostEntry)); + hostEntry = (watched_host_entry_t *)calloc(1, sizeof(*hostEntry)); if (hostEntry == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc host entry for %s.", svcEntry->instanceName); continue; @@ -498,11 +506,15 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher hostEntry->activeStartTime.tv_sec = INT_MAX; hostEntry->ifIndex = svcEntry->ifIndex; hostEntry->markDeleted = false; - if (celix_stringHashMap_put(watcher->watchedHosts, key, hostEntry) == CELIX_SUCCESS) { - celix_steal_ptr(hostname); - celix_steal_ptr(ipAddresses); - celix_steal_ptr(hostEntry); + char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int + (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); + if (celix_stringHashMap_put(watcher->watchedHosts, key, hostEntry) != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to add host entry for %s.", svcEntry->instanceName); + continue; } + celix_steal_ptr(hostname); + celix_steal_ptr(ipAddresses); + celix_steal_ptr(hostEntry); } } } @@ -540,9 +552,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher } static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { - char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int - (void)snprintf(key, sizeof(key), "%s%d", hostname, ifIndex); - watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, hostname, ifIndex); if (hostEntry == NULL) { return false; } @@ -589,10 +599,8 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero } //fill ip address list property - char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int - (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); celix_autofree char *ipAddressesStr = NULL; - watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, svcEntry->hostname, svcEntry->ifIndex); if (hostEntry != NULL) { CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { const char *ip = iter.key; @@ -682,9 +690,7 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z if (endpointEntry->hostname == NULL) { return false; } - char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int - (void)snprintf(key, sizeof(key), "%s%d", endpointEntry->hostname, endpointEntry->ifIndex); - watched_host_entry_t *hostEntry = (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); + watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, endpointEntry->hostname, endpointEntry->ifIndex); if (hostEntry == NULL) { return true; } @@ -798,6 +804,7 @@ static void discoveryZeroconfWatcher_clearEndpoints(discovery_zeroconf_watcher_t watched_endpoint_entry_t *epEntry = (watched_endpoint_entry_t *)iter.value.ptrValue; discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); endpointDescription_destroy(epEntry->endpoint); + free(epEntry->hostname); free(epEntry); } celix_stringHashMap_clear(watcher->watchedEndpoints); @@ -809,7 +816,7 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc if (watcher->sharedRef) { DNSServiceRefDeallocate(watcher->sharedRef); watcher->sharedRef = NULL; - watcher->browseRef = NULL;//no need free entry->browseRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has do it. + watcher->browseRef = NULL;//no need free entry->browseRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. } CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; @@ -818,6 +825,7 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc free(svcEntry->hostname); free(svcEntry); } + celix_stringHashMap_clear(watcher->watchedServices); CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { watched_host_entry_t *hostEntry = (watched_host_entry_t *) iter.value.ptrValue; //no need free hostEntry->sdRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. @@ -825,7 +833,7 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc free(hostEntry->hostname); free(hostEntry); } - celix_stringHashMap_clear(watcher->watchedServices); + celix_stringHashMap_clear(watcher->watchedHosts); return; } From 4fdeadeff32ac385e6db6124ef58dfb246e51a71 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sat, 9 Dec 2023 18:25:58 +0800 Subject: [PATCH 06/29] Add the interval time of endpoint watcher thead loop --- .../src/discovery_zeroconf_watcher.c | 120 +++++++++++++----- 1 file changed, 87 insertions(+), 33 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 1e965341b..7bd0403b6 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -396,17 +396,23 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, return; } -static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_t *watcher) { +static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; //If resolving is not completed for a long time,then close it, and try again later. - if (svcEntry->resolved == false && svcEntry->resolveRef != NULL && celix_elapsedtime(CLOCK_MONOTONIC, svcEntry->resolvedStartTime) > DZC_MAX_RESOLVED_TIMEOUT) { + double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, svcEntry->resolvedStartTime); + if (svcEntry->resolved == false && svcEntry->resolveRef != NULL && elapsed >= DZC_MAX_RESOLVED_TIMEOUT) { DNSServiceRefDeallocate(svcEntry->resolveRef); svcEntry->resolveRef = NULL; svcEntry->resolvedStartTime.tv_sec = INT_MAX; svcEntry->resolvedStartTime.tv_nsec = 0; celix_logHelper_error(watcher->logHelper, "Watcher: resolve %s on %d timeout.", svcEntry->instanceName, svcEntry->ifIndex); + } else if (svcEntry->resolved == false && svcEntry->resolveRef != NULL) { + unsigned int tmp = DZC_MAX_RESOLVED_TIMEOUT - elapsed; + nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; } + if (watcher->sharedRef && svcEntry->resolveRef == NULL && svcEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { svcEntry->resolveRef = watcher->sharedRef; DNSServiceErrorType dnsErr = DNSServiceResolve(&svcEntry->resolveRef, kDNSServiceFlagsShareConnection , svcEntry->ifIndex, svcEntry->instanceName, DZC_SERVICE_PRIMARY_TYPE, "local", OnServiceResolveCallback, svcEntry); @@ -416,8 +422,10 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ } svcEntry->resolvedStartTime = celix_gettime(CLOCK_MONOTONIC); svcEntry->resolvedCnt ++; + nextWorkIntervalTime = nextWorkIntervalTime < DZC_MAX_RESOLVED_TIMEOUT ? nextWorkIntervalTime : DZC_MAX_RESOLVED_TIMEOUT; } } + *pNextWorkIntervalTime = nextWorkIntervalTime; return; } @@ -425,6 +433,7 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { (void)sdRef;//unused (void)ttl;//unused + (void)hostname;//unused watched_host_entry_t *hostEntry = (watched_host_entry_t *)context; assert(hostEntry != NULL); if (errorCode == kDNSServiceErr_NoSuchRecord) { @@ -454,7 +463,7 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ celix_stringHashMap_remove(hostEntry->ipAddresses, ip); } - if (celix_stringHashMap_size(hostEntry->ipAddresses) > 0) { + if (!(flags & kDNSServiceFlagsMoreComing) && celix_stringHashMap_size(hostEntry->ipAddresses) > 0) { hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); hostEntry->activeStartTime.tv_sec += 2;//If the host information does not change within 2 seconds, we will use the host information to create endpoint description. } else { @@ -471,7 +480,8 @@ static watched_host_entry_t *discoveryZeroconfWatcher_getHostEntry(discovery_zer return (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); } -static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher) { +static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; //mark deleted hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue; @@ -547,11 +557,21 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get address info for %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, dnsErr); } } + if (hostEntry->activeStartTime.tv_sec != INT_MAX) { + double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); + unsigned int tmp = abs((int)elapsed); + nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; + } } + + *pNextWorkIntervalTime = nextWorkIntervalTime; return; } static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { + if (hostname == NULL) {//if no need to resolve host info, then return true + return true; + } watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, hostname, ifIndex); if (hostEntry == NULL) { return false; @@ -670,6 +690,13 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero return CELIX_SUCCESS; } +static void endpointEntry_destroy(watched_endpoint_entry_t *entry) { + endpointDescription_destroy(entry->endpoint); + free(entry->hostname); + free(entry); + return; +} + static void discoveryZeroConfWatcher_informEPLs(discovery_zeroconf_watcher_t *watcher, endpoint_description_t *endpoint, bool epAdded) { CELIX_LONG_HASH_MAP_ITERATE(watcher->epls, iter) { watched_epl_entry_t *eplEntry = (watched_epl_entry_t *)iter.value.ptrValue; @@ -719,9 +746,10 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z return false; } -static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher_t *watcher) { +static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { watched_endpoint_entry_t *epEntry = NULL; watched_service_entry_t *svcEntry = NULL; + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; //remove self endpoints celix_string_hash_map_iterator_t svcIter = celix_stringHashMap_begin(watcher->watchedServices); @@ -746,29 +774,28 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher celixThreadMutex_lock(&watcher->mutex); - //remove expired endpoint + //remove the endpoint which ip address list changed, and mark expired time of the endpoint. celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); while (!celix_stringHashMapIterator_isEnd(&epIter)) { epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; - if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry) - || celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime) >= DZC_EP_JITTER_INTERVAL) { - epEntry->expiredTime.tv_sec = INT_MAX; + if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry)) { celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); - celix_stringHashMap_remove(watcher->watchedEndpoints, svcEntry->endpointId); + celix_stringHashMap_remove(watcher->watchedEndpoints, epEntry->endpoint->id); discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); - endpointDescription_destroy(epEntry->endpoint); - free(epEntry); - continue; - } else if (epEntry->expiredTime.tv_sec == INT_MAX) { - epEntry->expiredTime = celix_gettime(CLOCK_MONOTONIC); + endpointEntry_destroy(epEntry); + } else { + if (epEntry->expiredTime.tv_sec == INT_MAX) { + epEntry->expiredTime = celix_gettime(CLOCK_MONOTONIC); + epEntry->expiredTime.tv_sec += DZC_EP_JITTER_INTERVAL; + } + celix_stringHashMapIterator_next(&epIter); } - celix_stringHashMapIterator_next(&epIter); } //add new endpoint CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { svcEntry = (watched_service_entry_t *)iter.value.ptrValue; - if (svcEntry->endpointId != NULL && svcEntry->resolved && (svcEntry->hostname == NULL || discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex))) { + if (svcEntry->endpointId != NULL && svcEntry->resolved && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex)) { epEntry = (watched_endpoint_entry_t *)celix_stringHashMap_get(watcher->watchedEndpoints, svcEntry->endpointId); if (epEntry == NULL) { celix_status_t status = discoveryZeroConfWatcher_createEndpointEntryForService(watcher, svcEntry, &epEntry); @@ -778,13 +805,11 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher svcEntry->resolved = false; continue; } - celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s.", svcEntry->instanceName); + celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); if (celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry) == CELIX_SUCCESS) { discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, true); } else { - endpointDescription_destroy(epEntry->endpoint); - free(epEntry->hostname); - free(epEntry); + endpointEntry_destroy(epEntry); } } else { epEntry->expiredTime.tv_sec = INT_MAX; @@ -793,8 +818,28 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher } } + //remove expired endpoint + epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); + while (!celix_stringHashMapIterator_isEnd(&epIter)) { + epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; + double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime); + if (elapsed >= 0) { + celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); + celix_stringHashMapIterator_remove(&epIter); + discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); + endpointEntry_destroy(epEntry); + } else { + if (epEntry->expiredTime.tv_sec != INT_MAX) { + unsigned int tmp = abs((int)elapsed); + nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; + } + celix_stringHashMapIterator_next(&epIter); + } + } + celixThreadMutex_unlock(&watcher->mutex); + *pNextWorkIntervalTime = nextWorkIntervalTime; return; } @@ -803,9 +848,7 @@ static void discoveryZeroconfWatcher_clearEndpoints(discovery_zeroconf_watcher_t CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedEndpoints, iter) { watched_endpoint_entry_t *epEntry = (watched_endpoint_entry_t *)iter.value.ptrValue; discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); - endpointDescription_destroy(epEntry->endpoint); - free(epEntry->hostname); - free(epEntry); + endpointEntry_destroy(epEntry); } celix_stringHashMap_clear(watcher->watchedEndpoints); celixThreadMutex_unlock(&watcher->mutex); @@ -857,7 +900,9 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { eventfd_t val; int dsFd; int maxFd; - struct timeval timeout; + struct timeval timeoutVal; + struct timeval *timeout = NULL; + unsigned int nextWorkIntervalTimeInS = UINT_MAX; bool running = watcher->running; while (running) { if (watcher->sharedRef == NULL) { @@ -884,15 +929,23 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { assert(dsFd >= 0); FD_SET(dsFd, &readfds); maxFd = MAX(maxFd, dsFd); - timeout.tv_sec = 1;//TODO get next timeout - timeout.tv_usec = 0; + if (nextWorkIntervalTimeInS == UINT_MAX) { + timeout = NULL;//wait until eventfd or dsFd ready + } else { + timeoutVal.tv_sec = nextWorkIntervalTimeInS; + timeoutVal.tv_usec = 0; + timeout = &timeoutVal; + } } else { dsFd = -1; - timeout.tv_sec = 5; - timeout.tv_usec = 0; + //if failed to create connection, then wait 5 seconds to try again. + nextWorkIntervalTimeInS = nextWorkIntervalTimeInS < 5 ? nextWorkIntervalTimeInS : 5; + timeoutVal.tv_sec = nextWorkIntervalTimeInS; + timeoutVal.tv_usec = 0; + timeout = &timeoutVal; } - int result = select(maxFd+1, &readfds, NULL, NULL, &timeout); + int result = select(maxFd+1, &readfds, NULL, NULL, timeout); if (result > 0) { if (FD_ISSET(watcher->eventFd, &readfds)) { eventfd_read(watcher->eventFd, &val); @@ -907,9 +960,10 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { sleep(1);//avoid busy loop } - discoveryZeroconfWatcher_resolveServices(watcher); - discoveryZeroconfWatcher_refreshHostsInfo(watcher); - discoveryZeroconfWatcher_refreshEndpoints(watcher); + nextWorkIntervalTimeInS = UINT_MAX; + discoveryZeroconfWatcher_resolveServices(watcher, &nextWorkIntervalTimeInS); + discoveryZeroconfWatcher_refreshHostsInfo(watcher, &nextWorkIntervalTimeInS); + discoveryZeroconfWatcher_refreshEndpoints(watcher, &nextWorkIntervalTimeInS); celixThreadMutex_lock(&watcher->mutex); running = watcher->running; From f92eb6c4ec8c490bc1edd08e5b72e4c41e64ca8b Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sun, 10 Dec 2023 22:21:59 +0800 Subject: [PATCH 07/29] Add the interval time of endpoint watcher thead loop --- .../src/discovery_zeroconf_watcher.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 7bd0403b6..ab945f2c7 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -902,13 +902,14 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { int maxFd; struct timeval timeoutVal; struct timeval *timeout = NULL; - unsigned int nextWorkIntervalTimeInS = UINT_MAX; + unsigned int timeoutInS = UINT_MAX; bool running = watcher->running; while (running) { if (watcher->sharedRef == NULL) { dnsErr = DNSServiceCreateConnection(&watcher->sharedRef); if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create connection for DNS service, %d.", dnsErr); + timeoutInS = MIN(5, timeoutInS);//retry after 5 seconds } } @@ -918,6 +919,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); watcher->browseRef = NULL; + timeoutInS = MIN(5, timeoutInS);//retry after 5 seconds } } @@ -929,18 +931,14 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { assert(dsFd >= 0); FD_SET(dsFd, &readfds); maxFd = MAX(maxFd, dsFd); - if (nextWorkIntervalTimeInS == UINT_MAX) { - timeout = NULL;//wait until eventfd or dsFd ready - } else { - timeoutVal.tv_sec = nextWorkIntervalTimeInS; - timeoutVal.tv_usec = 0; - timeout = &timeoutVal; - } } else { dsFd = -1; - //if failed to create connection, then wait 5 seconds to try again. - nextWorkIntervalTimeInS = nextWorkIntervalTimeInS < 5 ? nextWorkIntervalTimeInS : 5; - timeoutVal.tv_sec = nextWorkIntervalTimeInS; + } + + if (timeoutInS == UINT_MAX) { + timeout = NULL;//wait until eventfd or dsFd ready + } else { + timeoutVal.tv_sec = timeoutInS; timeoutVal.tv_usec = 0; timeout = &timeoutVal; } @@ -960,10 +958,10 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { sleep(1);//avoid busy loop } - nextWorkIntervalTimeInS = UINT_MAX; - discoveryZeroconfWatcher_resolveServices(watcher, &nextWorkIntervalTimeInS); - discoveryZeroconfWatcher_refreshHostsInfo(watcher, &nextWorkIntervalTimeInS); - discoveryZeroconfWatcher_refreshEndpoints(watcher, &nextWorkIntervalTimeInS); + timeoutInS = UINT_MAX; + discoveryZeroconfWatcher_resolveServices(watcher, &timeoutInS); + discoveryZeroconfWatcher_refreshHostsInfo(watcher, &timeoutInS); + discoveryZeroconfWatcher_refreshEndpoints(watcher, &timeoutInS); celixThreadMutex_lock(&watcher->mutex); running = watcher->running; From 73308d5d88d53d5863b6fe258a3fbf6a4f7db500 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 11 Dec 2023 10:02:00 +0800 Subject: [PATCH 08/29] Remove the service resolved timeout mechanism, it is not necessary --- .../src/discovery_zeroconf_watcher.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index ab945f2c7..b73be6dcb 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -46,7 +46,6 @@ #include #define DZC_EP_JITTER_INTERVAL 10 -#define DZC_MAX_RESOLVED_TIMEOUT 5 #define DZC_MAX_RESOLVED_CNT 10 #define DZC_MAX_HOSTNAME_LEN 255 //The fully qualified domain name of the host, eg: "MyComputer.local". RFC 1034 specifies that this name is limited to 255 bytes. @@ -83,7 +82,6 @@ typedef struct watched_service_entry { char instanceName[64];//The instanceName must be 1-63 bytes char *hostname; bool resolved; - struct timespec resolvedStartTime; int resolvedCnt; DNSServiceRef resolveRef; }watched_service_entry_t; @@ -378,7 +376,6 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, strcpy(svcEntry->instanceName, instanceName); svcEntry->hostname = NULL; svcEntry->ifIndex = (int)interfaceIndex; - svcEntry->resolvedStartTime.tv_sec = INT_MAX; svcEntry->resolvedCnt = 0; celix_stringHashMap_put(watcher->watchedServices, key, svcEntry); } else { @@ -400,29 +397,15 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; - //If resolving is not completed for a long time,then close it, and try again later. - double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, svcEntry->resolvedStartTime); - if (svcEntry->resolved == false && svcEntry->resolveRef != NULL && elapsed >= DZC_MAX_RESOLVED_TIMEOUT) { - DNSServiceRefDeallocate(svcEntry->resolveRef); - svcEntry->resolveRef = NULL; - svcEntry->resolvedStartTime.tv_sec = INT_MAX; - svcEntry->resolvedStartTime.tv_nsec = 0; - celix_logHelper_error(watcher->logHelper, "Watcher: resolve %s on %d timeout.", svcEntry->instanceName, svcEntry->ifIndex); - } else if (svcEntry->resolved == false && svcEntry->resolveRef != NULL) { - unsigned int tmp = DZC_MAX_RESOLVED_TIMEOUT - elapsed; - nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; - } - if (watcher->sharedRef && svcEntry->resolveRef == NULL && svcEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { svcEntry->resolveRef = watcher->sharedRef; DNSServiceErrorType dnsErr = DNSServiceResolve(&svcEntry->resolveRef, kDNSServiceFlagsShareConnection , svcEntry->ifIndex, svcEntry->instanceName, DZC_SERVICE_PRIMARY_TYPE, "local", OnServiceResolveCallback, svcEntry); if (dnsErr != kDNSServiceErr_NoError) { svcEntry->resolveRef = NULL; celix_logHelper_error(watcher->logHelper, "Watcher: Failed to resolve %s on %d, %d.", svcEntry->instanceName, svcEntry->ifIndex, dnsErr); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, 5);//retry resolve after 5 seconds } - svcEntry->resolvedStartTime = celix_gettime(CLOCK_MONOTONIC); svcEntry->resolvedCnt ++; - nextWorkIntervalTime = nextWorkIntervalTime < DZC_MAX_RESOLVED_TIMEOUT ? nextWorkIntervalTime : DZC_MAX_RESOLVED_TIMEOUT; } } *pNextWorkIntervalTime = nextWorkIntervalTime; From 89e4dbcf7f15e6ec58a520f62f9bb0c6c2980180 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 11 Dec 2023 14:55:19 +0800 Subject: [PATCH 09/29] Add retry cnt for DNSServiceGetAddrInfo --- .../src/discovery_zeroconf_watcher.c | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index b73be6dcb..2a7e8ccf2 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -45,8 +45,9 @@ #include #include -#define DZC_EP_JITTER_INTERVAL 10 -#define DZC_MAX_RESOLVED_CNT 10 +#define DZC_EP_JITTER_INTERVAL 3//The jitter interval for endpoint.Avoid updating endpoint description on all network interfaces when only one network interface is updated.The endpoint description will be removed when the service is removed for 3 seconds. +#define DZC_MAX_RESOLVED_CNT 10 //Max resolved count for each service when resolve service failed +#define DZC_MAX_RETRY_INTERVAL 5 //Max retry interval when resolve service failed #define DZC_MAX_HOSTNAME_LEN 255 //The fully qualified domain name of the host, eg: "MyComputer.local". RFC 1034 specifies that this name is limited to 255 bytes. @@ -97,6 +98,7 @@ typedef struct watched_host_entry { int ifIndex; celix_string_hash_map_t *ipAddresses;//key:ip address, val:true(ipv4)/false(ipv6) struct timespec activeStartTime; + int resolvedCnt; bool markDeleted; }watched_host_entry_t; @@ -403,7 +405,7 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ if (dnsErr != kDNSServiceErr_NoError) { svcEntry->resolveRef = NULL; celix_logHelper_error(watcher->logHelper, "Watcher: Failed to resolve %s on %d, %d.", svcEntry->instanceName, svcEntry->ifIndex, dnsErr); - nextWorkIntervalTime = MIN(nextWorkIntervalTime, 5);//retry resolve after 5 seconds + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry resolve after 5 seconds } svcEntry->resolvedCnt ++; } @@ -498,6 +500,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher hostEntry->sdRef = NULL; hostEntry->activeStartTime.tv_sec = INT_MAX; hostEntry->ifIndex = svcEntry->ifIndex; + hostEntry->resolvedCnt = 0; hostEntry->markDeleted = false; char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); @@ -532,18 +535,20 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher //resolve hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter1) { watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; - if (watcher->sharedRef && hostEntry->sdRef == NULL) { + if (watcher->sharedRef && hostEntry->sdRef == NULL && hostEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { hostEntry->sdRef = watcher->sharedRef; DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); if (dnsErr != kDNSServiceErr_NoError) { hostEntry->sdRef = NULL; celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get address info for %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, dnsErr); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry resolve after 5 seconds } + hostEntry->resolvedCnt ++; } - if (hostEntry->activeStartTime.tv_sec != INT_MAX) { - double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); + double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); + if (hostEntry->activeStartTime.tv_sec != INT_MAX && elapsed < 0) { unsigned int tmp = abs((int)elapsed); - nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; + nextWorkIntervalTime = MIN(nextWorkIntervalTime, tmp); } } @@ -892,7 +897,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { dnsErr = DNSServiceCreateConnection(&watcher->sharedRef); if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create connection for DNS service, %d.", dnsErr); - timeoutInS = MIN(5, timeoutInS);//retry after 5 seconds + timeoutInS = MIN(DZC_MAX_RETRY_INTERVAL, timeoutInS);//retry after 5 seconds } } @@ -902,7 +907,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); watcher->browseRef = NULL; - timeoutInS = MIN(5, timeoutInS);//retry after 5 seconds + timeoutInS = MIN(DZC_MAX_RETRY_INTERVAL, timeoutInS);//retry after 5 seconds } } From f5e276e3ff91d2a48911ec86c114e72fc50e564c Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Tue, 12 Dec 2023 16:12:51 +0800 Subject: [PATCH 10/29] Map the config type to mDNS service subtype and improve some code --- .../discovery_zeroconf/CMakeLists.txt | 4 +- .../DiscoveryZeroconfAnnouncerTestSuite.cc | 6 +- .../src/discovery_zeroconf_announcer.c | 99 +++++-- .../src/discovery_zeroconf_constants.h | 22 +- .../src/discovery_zeroconf_watcher.c | 259 ++++++++++++++---- .../src/remote_service_admin_dfi.c | 1 - .../rsa_spi/include/remote_constants.h | 6 +- 7 files changed, 286 insertions(+), 111 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/CMakeLists.txt b/bundles/remote_services/discovery_zeroconf/CMakeLists.txt index 990c55237..bf1fa6c20 100644 --- a/bundles/remote_services/discovery_zeroconf/CMakeLists.txt +++ b/bundles/remote_services/discovery_zeroconf/CMakeLists.txt @@ -37,7 +37,7 @@ if (RSA_DISCOVERY_ZEROCONF) add_celix_bundle(rsa_discovery_zeroconf SYMBOLIC_NAME "apache_celix_rsa_discovery_zeroconf" - VERSION "1.0.0" + VERSION "2.0.0" NAME "Apache Celix Multicast zeroconf service discovery" GROUP "Celix/RSA" SOURCES @@ -45,6 +45,7 @@ if (RSA_DISCOVERY_ZEROCONF) ) celix_deprecated_utils_headers(rsa_discovery_zeroconf) + celix_deprecated_framework_headers(rsa_discovery_zeroconf) target_link_libraries(rsa_discovery_zeroconf PRIVATE ${RSA_DISCOVERY_ZEROCONF_DEPS}) @@ -58,6 +59,7 @@ if (RSA_DISCOVERY_ZEROCONF) if (ENABLE_TESTING) add_library(rsa_discovery_zeroconf_cut STATIC ${RSA_DISCOVERY_ZEROCONF_SRC}) celix_deprecated_utils_headers(rsa_discovery_zeroconf_cut) + celix_deprecated_framework_headers(rsa_discovery_zeroconf_cut) target_include_directories(rsa_discovery_zeroconf_cut PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src) target_link_libraries(rsa_discovery_zeroconf_cut PUBLIC ${RSA_DISCOVERY_ZEROCONF_DEPS}) add_subdirectory(gtest) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index 606b38bdf..dfefa0182 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -183,7 +183,7 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, EXPECT_TRUE(celix_properties_getAsLong(prop, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0) > 0); //The txt record should not include DZC_SERVICE_ANNOUNCED_IF_INDEX_KEY,DZC_SERVICE_TYPE_KEY EXPECT_EQ(nullptr, celix_properties_get(prop, CELIX_RSA_NETWORK_INTERFACES, nullptr)); - EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_SERVICE_TYPE_KEY, nullptr)); + //EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_SERVICE_TYPE_KEY, nullptr));TODO DNSServiceRefDeallocate(dsRef); celix_properties_destroy(prop); } @@ -474,7 +474,7 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); - celix_properties_set(properties, DZC_SERVICE_TYPE_KEY, "invalid_service_type_because_the_size_large_than_48"); + //celix_properties_set(properties, DZC_SERVICE_TYPE_KEY, "invalid_service_type_because_the_size_large_than_48");TODO endpoint_description_t *endpoint{}; status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -484,7 +484,7 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //lost service name - celix_properties_unset(properties, DZC_SERVICE_TYPE_KEY); + //celix_properties_unset(properties, DZC_SERVICE_TYPE_KEY);//TODO celix_properties_unset(properties, CELIX_FRAMEWORK_SERVICE_NAME); status = epl->endpointAdded(epl->handle, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index 3dcb1874b..a61e7f2e3 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -58,6 +58,9 @@ //According to rfc6763, Using TXT records larger than 1300 bytes is NOT RECOMMENDED #define DZC_MAX_TXT_RECORD_SIZE 1300 +//It is enough to store three subtypes. +#define DZC_MAX_SERVICE_TYPE_LEN 256 + struct discovery_zeroconf_announcer { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; @@ -80,7 +83,7 @@ typedef struct announce_endpoint_entry { int ifIndex; int port; const char *serviceName; - char serviceType[64]; + char *serviceType;//it is enough to cache the service type bool announced; }announce_endpoint_entry_t; @@ -181,6 +184,7 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce for (int i = 0; i < size; ++i) { entry = (announce_endpoint_entry_t *)celix_arrayList_get(announcer->revokedEndpoints, i); celix_properties_destroy(entry->properties); + free(entry->serviceType); free(entry); } celix_arrayList_destroy(announcer->revokedEndpoints); @@ -188,6 +192,7 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce CELIX_STRING_HASH_MAP_ITERATE(announcer->endpoints,iter) { entry = (announce_endpoint_entry_t *) iter.value.ptrValue; celix_properties_destroy(entry->properties); + free(entry->serviceType); free(entry); } celix_stringHashMap_destroy(announcer->endpoints); @@ -239,25 +244,60 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en return CELIX_ILLEGAL_ARGUMENT; } + celix_autoptr(celix_properties_t) properties = celix_properties_copy(endpoint->properties); + if (properties == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy endpoint properties."); + return CELIX_ENOMEM; + } + celix_string_hash_map_create_options_t opts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; + opts.storeKeysWeakly = true; + celix_autoptr(celix_string_hash_map_t) svcSubTypes = celix_stringHashMap_createWithOptions(&opts); + if (svcSubTypes == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create svc sub types map."); + return CELIX_ENOMEM; + } + const char *ifName = NULL; int port = DZC_PORT_DEFAULT; celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); char *savePtr = NULL; char *token = strtok_r(importedConfigsCopy, ",", &savePtr); - while (token != NULL && port == DZC_PORT_DEFAULT) { - //We only need to get one imported config, because all imported configs listed in this property must be synonymous(see https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#d0e1152). - celix_autofree char *importedConfigPortKey = NULL; - if(asprintf(&importedConfigPortKey, "%s.port", celix_utils_trimInPlace(token)) < 0) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create imported config port key."); - return CELIX_ENOMEM; + while (token != NULL) { + token = celix_utils_trimInPlace(token); + char key[128] = {0}; + if(snprintf(key, sizeof(key), "%s.port", token) >= sizeof(key)) { + celix_logHelper_error(announcer->logHelper, "Announcer: The length of imported config type %s is too long.", token); + return CELIX_ILLEGAL_ARGUMENT; } - celix_autofree char *importedConfigIfNameKey = NULL; - if(asprintf(&importedConfigIfNameKey, "%s.ifname", celix_utils_trimInPlace(token)) < 0) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create imported config ifname key."); - return CELIX_ENOMEM; + //We only need to get one imported config port/ifname property, because all imported configs listed in this property must be synonymous(see https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1710847). + port = celix_properties_getAsLong(endpoint->properties, key, port); + celix_properties_unset(properties, key);//port should not set to mDNS TXT record, because it will be set to SRV record. see https://www.rfc-editor.org/rfc/rfc6763.html#section-6.3 + + if(snprintf(key, sizeof(key), "%s.ifname", token) >= sizeof(key)) { + celix_logHelper_error(announcer->logHelper, "Announcer: The length of imported config type %s is too long.", token); + return CELIX_ILLEGAL_ARGUMENT; } - port = celix_properties_getAsLong(endpoint->properties, importedConfigPortKey, DZC_PORT_DEFAULT); - ifName = celix_properties_get(endpoint->properties, importedConfigIfNameKey, NULL); + ifName = celix_properties_get(endpoint->properties, key, ifName); + celix_properties_unset(properties, key);//ifname should not set to mDNS TXT record, because service consumer will not use it. + + //We use the last word of config type as mDNS service subtype(https://www.rfc-editor.org/rfc/rfc6763.html#section-7.1). so we can browse the service by the last word of config type. + const char *svcSubType = strrchr(token, '.'); + if (svcSubType != NULL) { + svcSubType += 1;//skip '.' + } else { + svcSubType = token; + } + size_t subTypeLen = strlen(svcSubType); + if (subTypeLen ==0 || subTypeLen > 63) {//the subtype identifier is allowed to be up to 63 bytes, see https://www.rfc-editor.org/rfc/rfc6763.html#section-7.2 + celix_logHelper_error(announcer->logHelper, "Announcer: Invalid service sub type for %s.", token); + return CELIX_ILLEGAL_ARGUMENT; + } + int status = celix_stringHashMap_put(svcSubTypes, svcSubType, NULL); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put service sub type for %s. %d", token, status); + return status; + } + token = strtok_r(NULL, ",", &savePtr); } @@ -287,23 +327,24 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en } entry->port = port; - const char *serviceSubType = celix_properties_get(endpoint->properties, DZC_SERVICE_TYPE_KEY, NULL); - if (serviceSubType != NULL) { - int bytes = snprintf(entry->serviceType, sizeof(entry->serviceType), DZC_SERVICE_PRIMARY_TYPE",%s", serviceSubType); - if (bytes >= sizeof(entry->serviceType)) { - celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service type for %s.", serviceSubType); + char serviceType[DZC_MAX_SERVICE_TYPE_LEN] = {0}; + CELIX_BUILD_ASSERT(sizeof(serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); + strcpy(serviceType, DZC_SERVICE_PRIMARY_TYPE); + size_t offset = strlen(serviceType); + CELIX_STRING_HASH_MAP_ITERATE(svcSubTypes, iter) { + offset += snprintf(serviceType + offset, sizeof(serviceType) - offset, ",%s", iter.key); + if (offset >= sizeof(serviceType)) { + celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of imported configs for %s.", importedConfigs); return CELIX_ILLEGAL_ARGUMENT; } - } else { - CELIX_BUILD_ASSERT(sizeof(entry->serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); - strcpy(entry->serviceType, DZC_SERVICE_PRIMARY_TYPE); } - celix_autoptr(celix_properties_t) properties = entry->properties = celix_properties_copy(endpoint->properties); + entry->serviceType = celix_utils_strdup(serviceType); + if (entry->serviceType == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy service type."); + return CELIX_ENOMEM; + } - //Remove properties that remote service does not need - celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_INTERFACES);//TODO - celix_properties_unset(entry->properties, CELIX_RSA_NETWORK_PORT); - celix_properties_unset(entry->properties, DZC_SERVICE_TYPE_KEY); + entry->properties = properties; entry->serviceName = celix_properties_get(entry->properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL); if (entry->serviceName == NULL) { celix_logHelper_error(announcer->logHelper,"Announcer: Invalid service."); @@ -362,6 +403,7 @@ static void discoveryZeroconfAnnouncer_revokeEndpoints(discovery_zeroconf_announ DNSServiceRefDeallocate(entry->registerRef); } celix_properties_destroy(entry->properties); + free(entry->serviceType); free(entry); } return; @@ -405,9 +447,10 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno celix_properties_iterator_t propIter = celix_properties_begin(entry->properties); TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + (void)TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); char propSizeStr[16]= {0}; - sprintf(propSizeStr, "%zu", celix_properties_size(entry->properties) + 1); - (void)TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr);//TODO add txtver + sprintf(propSizeStr, "%zu", celix_properties_size(entry->properties) + 2/*size and version*/); + (void)TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); if (!discoveryZeroconfAnnouncer_copyPropertiesToTxtRecord(announcer, &propIter, &txtRecord, sizeof(txtBuf), splitTxtRecord)) { TXTRecordDeallocate(&txtRecord); continue; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h index d208e5a99..0a98ecb68 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_constants.h @@ -37,21 +37,6 @@ extern "C" { */ #define DZC_SERVICE_PRIMARY_TYPE "_celix-rpc._udp" -/** - * mDNS service subtype for celix.service, it can be null. - * About mDNS service subtype, see rfc6763 section 7.1 - * The subtype mechanism can be illustrated with some examples using the dns-sd command-line tool: - * If we register the following three services: - * % dns-sd -R service1 _celix-rpc._udp local 1001 - * % dns-sd -R service2 _celix-rpc._udp,subtype1 local 1002 - * % dns-sd -R service3 _celix-rpc._udp,subtype1,subtype2 local 1003 - * Now: - * % dns-sd -B _celix-rpc._udp # will find all three services - * % dns-sd -B _celix-rpc._udp,subtype1 # will find "service2" and "service3" - * % dns-sd -B _celix-rpc._udp,subtype2 # will find only "service3" - */ -#define DZC_SERVICE_TYPE_KEY "DZC_SERVICE_TYPE_KEY" - /** * The default port for mDNS service. * @@ -68,6 +53,13 @@ extern "C" { */ #define DZC_SERVICE_PROPERTIES_SIZE_KEY "DZC_SVC_PROPS_SIZE_KEY" +/** + * The version of mDNS txt record. + * @ref https://www.rfc-editor.org/rfc/rfc6763.html#section-6.7 + */ +#define DZC_TXT_RECORD_VERSION_KEY "txtvers" +#define DZC_CURRENT_TXT_RECORD_VERSION "1" + #ifdef __cplusplus } #endif diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 2a7e8ccf2..84ad2d2cb 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -18,6 +18,7 @@ */ #include "discovery_zeroconf_watcher.h" #include "discovery_zeroconf_constants.h" +#include "remote_service_admin.h" #include "endpoint_listener.h" #include "remote_constants.h" #include "celix_bundle_context.h" @@ -55,9 +56,9 @@ struct discovery_zeroconf_watcher { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; long epListenerTrkId; + long rsaTrkId; char fwUuid[64]; DNSServiceRef sharedRef; - DNSServiceRef browseRef; int eventFd; celix_thread_t watchEPThread; celix_string_hash_map_t *watchedServices;//key:instanceName+interfaceId, val:watched_service_entry_t* @@ -66,6 +67,7 @@ struct discovery_zeroconf_watcher { bool running; celix_string_hash_map_t *watchedEndpoints;//key:endpoint id, val:watched_endpoint_entry_t* celix_long_hash_map_t *epls;//key:service id, val:endpoint listener + celix_string_hash_map_t *serviceBrowsers;//key:service subtype(https://www.rfc-editor.org/rfc/rfc6763.html#section-7.1), val:service_browser_entry_t* }; typedef struct watched_endpoint_entry { @@ -82,6 +84,7 @@ typedef struct watched_service_entry { int ifIndex; char instanceName[64];//The instanceName must be 1-63 bytes char *hostname; + int port; bool resolved; int resolvedCnt; DNSServiceRef resolveRef; @@ -92,6 +95,12 @@ typedef struct watched_epl_entry { celix_filter_t *filter; }watched_epl_entry_t; +typedef struct service_browser_entry { + DNSServiceRef browseRef; + int refCnt; + int resolvedCnt; +}service_browser_entry_t; + typedef struct watched_host_entry { DNSServiceRef sdRef; char *hostname; @@ -102,9 +111,10 @@ typedef struct watched_host_entry { bool markDeleted; }watched_host_entry_t; -//TODO use subtypes to browse static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props); static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props); +static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props); +static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props); static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context); static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *instanceName, const char *regtype, const char *replyDomain, void *context); static void *discoveryZeroconfWatcher_watchEPThread(void *data); @@ -119,7 +129,6 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi watcher->logHelper = logHelper; watcher->ctx = ctx; watcher->sharedRef = NULL; - watcher->browseRef = NULL; watcher->eventFd = eventfd(0, 0); if (watcher->eventFd < 0) { celix_logHelper_fatal(logHelper, "Watcher: Failed to open event fd, %d.", errno); @@ -168,9 +177,23 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi return CELIX_BUNDLE_EXCEPTION; } + celix_service_tracking_options_t rsaOpts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; + rsaOpts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + rsaOpts.filter.filter = "(remote.configs.supported=*)"; + rsaOpts.callbackHandle = watcher; + rsaOpts.addWithProperties = discoveryZeroConfWatcher_addRSA; + rsaOpts.removeWithProperties = discoveryZeroConfWatcher_removeRSA; + watcher->rsaTrkId = celix_bundleContext_trackServicesWithOptionsAsync(ctx, &rsaOpts); + if (watcher->rsaTrkId < 0) { + celix_bundleContext_stopTracker(ctx, watcher->epListenerTrkId); + celix_logHelper_fatal(logHelper, "Watcher: Failed to register remote service admin service tracker."); + return CELIX_BUNDLE_EXCEPTION; + } + watcher->running = true; status = celixThread_create(&watcher->watchEPThread,NULL, discoveryZeroconfWatcher_watchEPThread, watcher); if (status != CELIX_SUCCESS) { + celix_bundleContext_stopTracker(ctx, watcher->rsaTrkId); celix_bundleContext_stopTracker(ctx, watcher->epListenerTrkId); return status; } @@ -192,8 +215,8 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { eventfd_t val = 1; eventfd_write(watcher->eventFd, val); celixThread_join(watcher->watchEPThread, NULL); - celix_bundleContext_stopTrackerAsync(watcher->ctx, watcher->epListenerTrkId, NULL, NULL); - celix_bundleContext_waitForAsyncStopTracker(watcher->ctx, watcher->epListenerTrkId); + celix_bundleContext_stopTracker(watcher->ctx, watcher->rsaTrkId); + celix_bundleContext_stopTracker(watcher->ctx, watcher->epListenerTrkId); celix_longHashMap_destroy(watcher->epls); assert(celix_stringHashMap_size(watcher->watchedServices) == 0); celix_stringHashMap_destroy(watcher->watchedServices); @@ -201,6 +224,10 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { celix_stringHashMap_destroy(watcher->watchedHosts); assert(celix_stringHashMap_size(watcher->watchedEndpoints) == 0); celix_stringHashMap_destroy(watcher->watchedEndpoints); + CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter) { + free(iter.value.ptrValue); + } + celix_stringHashMap_destroy(watcher->serviceBrowsers); celixThreadMutex_destroy(&watcher->mutex); close(watcher->eventFd); free(watcher); @@ -273,29 +300,110 @@ static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const ce return; } -static bool shouldResolveHostInfo(celix_properties_t *properties) { - const char *importedConfigs = celix_properties_get(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); - if (importedConfigs == NULL) { - return false; +static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props) { + assert(handle != NULL); + assert(svc != NULL); + assert(props != NULL); + discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; + const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); + if (configsSupported == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: No remote configs supported."); + return; } - celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); - if (importedConfigsCopy == NULL) { - return true; + celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); + if (configsSupportedCopy == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); + return; } - char *savePtr = NULL; - char *token = strtok_r(importedConfigsCopy, ",", &savePtr); + bool refreshBrowsers = false; + char *token = strtok(configsSupportedCopy, ","); while (token != NULL) { - char *configType = celix_utils_trimInPlace(token); - celix_autofree char *importedConfigPortKey = NULL; - if (asprintf(&importedConfigPortKey, "%s.port", configType) < 0) { - return true; + token = celix_utils_trimInPlace(token); + const char *svcSubType = strrchr(token, '.');//We use the last word of config type as mDNS service subtype + if (svcSubType != NULL) { + svcSubType += 1;//skip '.' + } else { + svcSubType = token; } - if (celix_properties_get(properties, importedConfigPortKey, NULL) != NULL) { - return true; + size_t subTypeLen = strlen(svcSubType); + if (subTypeLen ==0 || subTypeLen > 63) { + celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service type for %s.", token); + } else { + celixThreadMutex_lock(&watcher->mutex); + service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); + if (browserEntry == NULL) { + browserEntry = (service_browser_entry_t *)calloc(1, sizeof(*browserEntry)); + if (browserEntry != NULL) { + browserEntry->refCnt = 1; + browserEntry->resolvedCnt = 0; + browserEntry->browseRef = NULL; + if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) == CELIX_SUCCESS) { + refreshBrowsers = true; + } else { + free(browserEntry); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);//TODO check more function + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put browse entry."); + } + } else { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc browse entry."); + } + } else { + browserEntry->refCnt++; + } + celixThreadMutex_unlock(&watcher->mutex); } - token = strtok_r(NULL, ",", &savePtr); + token = strtok(NULL, ","); } - return false; + + if (refreshBrowsers) { + eventfd_t val = 1; + eventfd_write(watcher->eventFd, val); + } + + return; +} + +static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props) { + assert(handle != NULL); + assert(svc != NULL); + assert(props != NULL); + discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; + const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); + if (configsSupported == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: No remote configs supported."); + return; + } + + celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); + if (configsSupportedCopy == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); + return; + } + bool refreshBrowsers = false; + char *token = strtok(configsSupportedCopy, ","); + while (token != NULL) { + token = celix_utils_trimInPlace(token); + const char *svcSubType = strrchr(token, '.'); + if (svcSubType != NULL) { + svcSubType += 1;//skip '.' + } else { + svcSubType = token; + } + celixThreadMutex_lock(&watcher->mutex); + service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); + if ((browserEntry != NULL) && (--browserEntry->refCnt == 0)) { + refreshBrowsers = true; + } + celixThreadMutex_unlock(&watcher->mutex); + token = strtok(NULL, ","); + } + + if (refreshBrowsers) { + eventfd_t val = 1; + eventfd_write(watcher->eventFd, val); + } + + return; } static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { @@ -327,14 +435,18 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, svcEntry->endpointId = celix_properties_get(properties, OSGI_RSA_ENDPOINT_ID, NULL); long propSize = celix_properties_getAsLong(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0); - if (propSize == celix_properties_size(properties)) { - if (shouldResolveHostInfo(properties)) { + const char *version = celix_properties_get(properties, DZC_TXT_RECORD_VERSION_KEY, ""); + if (propSize == celix_properties_size(properties) && strcmp(DZC_CURRENT_TXT_RECORD_VERSION, version) == 0) { + //DZC_PORT_DEFAULT is used for the remote service that IPC is not network based(eg:shared memory). No need to resolve host information. + if (port != DZC_PORT_DEFAULT) { svcEntry->hostname = celix_utils_strdup(host); if (svcEntry->hostname == NULL) { return; } } + svcEntry->port = port; celix_properties_unset(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY);//Service endpoint do not need it + celix_properties_unset(properties, DZC_TXT_RECORD_VERSION_KEY);//Service endpoint do not need it svcEntry->resolved = true; } return; @@ -395,6 +507,39 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, return; } +static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + celixThreadMutex_lock(&watcher->mutex); + celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->serviceBrowsers); + while (!celix_stringHashMapIterator_isEnd(&iter)) { + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; + if (watcher->sharedRef != NULL && browserEntry->browseRef == NULL && browserEntry->refCnt > 0 && browserEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { + browserEntry->browseRef = watcher->sharedRef; + char serviceType[128] = {0};//primary type(15bytes) + subtype(63bytes) + (void)snprintf(serviceType, sizeof(serviceType), "%s,%s", DZC_SERVICE_PRIMARY_TYPE, iter.key); + DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, watcher); + if (dnsErr != kDNSServiceErr_NoError) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); + browserEntry->browseRef = NULL; + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + } + browserEntry->resolvedCnt ++; + } else if (browserEntry->refCnt == 0) { + if (browserEntry->browseRef) { + DNSServiceRefDeallocate(browserEntry->browseRef); + } + celix_stringHashMapIterator_remove(&iter); + free(browserEntry); + continue; + } + celix_stringHashMapIterator_next(&iter); + } + celixThreadMutex_unlock(&watcher->mutex); + + *pNextWorkIntervalTime = nextWorkIntervalTime; + return; +} + static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { @@ -641,34 +786,28 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero } char *savePtr = NULL; char *token = strtok_r(importedConfigsCopy, ",", &savePtr); - while (token != NULL && ipAddressesStr != NULL) { + while (token != NULL) { char *configType = celix_utils_trimInPlace(token); - celix_autofree char *importedConfigPortKey = NULL; - if(asprintf(&importedConfigPortKey, "%s.port", configType) < 0) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create imported config port key."); - return CELIX_ENOMEM; - } - celix_autofree char *importedConfigIpAddressListKey = NULL; - if(asprintf(&importedConfigIpAddressListKey, "%s.ipaddresses", configType) < 0) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create imported config ip address list key."); - return CELIX_ENOMEM; - } - //If the service.imported.configs contains the port property, then add the ipaddresses property - if (celix_properties_get(properties, importedConfigPortKey, NULL) != NULL) { - celix_autofree char *tmp = celix_utils_strdup(ipAddressesStr); - if (tmp == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); - return CELIX_ENOMEM; - } - status = celix_properties_setWithoutCopy(properties, importedConfigIpAddressListKey, tmp); - if (status != CELIX_SUCCESS) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); - return status; - } - epEntry->ipAddressesStr = tmp; - celix_steal_ptr(tmp); - celix_steal_ptr(importedConfigIpAddressListKey); + char key[128] = {0}; + if(snprintf(key, sizeof(key), "%s.port", configType) >= sizeof(key)) { + celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); + return CELIX_ILLEGAL_ARGUMENT; + } + status = celix_properties_setLong(properties, key, svcEntry->port); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config port."); + return status; + } + if(snprintf(key, sizeof(key), "%s.ipaddresses", configType) >= sizeof(key)) { + celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); + return CELIX_ILLEGAL_ARGUMENT; } + status = celix_properties_set(properties, key, ipAddressesStr); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); + return status; + } + epEntry->ipAddressesStr = celix_properties_get(properties, key, ""); } celix_steal_ptr(hostname); @@ -847,8 +986,16 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc if (watcher->sharedRef) { DNSServiceRefDeallocate(watcher->sharedRef); watcher->sharedRef = NULL; - watcher->browseRef = NULL;//no need free entry->browseRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. } + + celixThreadMutex_lock(&watcher->mutex); + CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter) { + service_browser_entry_t *browseEntry = (service_browser_entry_t *)iter.value.ptrValue; + browseEntry->browseRef = NULL;//no need free V->browseRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. + browseEntry->resolvedCnt = 0; + } + celixThreadMutex_unlock(&watcher->mutex); + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; //no need free svcEntry->resolveRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. @@ -901,15 +1048,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { } } - if (watcher->sharedRef != NULL && watcher->browseRef == NULL) { - watcher->browseRef = watcher->sharedRef; - dnsErr = DNSServiceBrowse(&watcher->browseRef, kDNSServiceFlagsShareConnection, 0, DZC_SERVICE_PRIMARY_TYPE, "local", OnServiceBrowseCallback, watcher); - if (dnsErr != kDNSServiceErr_NoError) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); - watcher->browseRef = NULL; - timeoutInS = MIN(DZC_MAX_RETRY_INTERVAL, timeoutInS);//retry after 5 seconds - } - } + discoveryZeroconfWatcher_browseServices(watcher, &timeoutInS); FD_ZERO(&readfds); FD_SET(watcher->eventFd, &readfds); 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 index dc9a02f47..e8c34e3ec 100644 --- 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 @@ -770,7 +770,6 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic if (admin->discoveryInterface != NULL) { celix_properties_set(endpointProperties, CELIX_RSA_NETWORK_INTERFACES, admin->discoveryInterface); } - celix_properties_set(endpointProperties, CELIX_RSA_NETWORK_PORT, admin->port); if (props != NULL) { CELIX_PROPERTIES_ITERATE(props, iter) { diff --git a/bundles/remote_services/rsa_spi/include/remote_constants.h b/bundles/remote_services/rsa_spi/include/remote_constants.h index cc9de6f11..cdcdf4fe7 100644 --- a/bundles/remote_services/rsa_spi/include/remote_constants.h +++ b/bundles/remote_services/rsa_spi/include/remote_constants.h @@ -45,10 +45,10 @@ static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location"; */ static const char * const CELIX_RSA_NETWORK_INTERFACES = "org.apache.celix.rsa.network.interfaces"; - /** - * Remote service admin property identifying the network port of the exported service. + * It identify which types of remote service configurations are supported by a distribution provider. + * @ref https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1708968 */ -#define CELIX_RSA_NETWORK_PORT "org.apache.celix.rsa.network.port" +#define OSGI_RSA_REMOTE_CONFIGS_SUPPORTED "remote.configs.supported" #endif /* REMOTE_CONSTANTS_H_ */ From dbc603d7a730a71e0fa79eab3e74eaa55ba98009 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 18 Dec 2023 21:19:08 +0800 Subject: [PATCH 11/29] Improve discovery_zeroconf and its unit test --- .../discovery_zeroconf/gtest/CMakeLists.txt | 6 + .../DiscoveryZeroconfAnnouncerTestSuite.cc | 118 ++- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 729 +++++++++++++++++- .../src/discovery_zeroconf_announcer.c | 209 +++-- .../src/discovery_zeroconf_watcher.c | 423 ++++++---- .../mdnsresponder/CMakeLists.txt | 2 +- .../mdnsresponder/include/mdnsresponder_ei.h | 2 + .../mdnsresponder/src/mdnsresponder_ei.cc | 16 + .../include/celix_string_hash_map_ei.h | 6 +- .../src/celix_string_hash_map_ei.cc | 7 + 10 files changed, 1237 insertions(+), 281 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt b/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt index fe911954c..204119303 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt +++ b/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt @@ -49,6 +49,7 @@ if (EI_TESTS) ) celix_deprecated_utils_headers(unit_test_discovery_zeroconf) + celix_deprecated_framework_headers(unit_test_discovery_zeroconf) target_link_libraries(unit_test_discovery_zeroconf PRIVATE rsa_discovery_zeroconf_cut @@ -58,6 +59,11 @@ if (EI_TESTS) Celix::threads_ei Celix::eventfd_ei Celix::bundle_ctx_ei + Celix::string_hash_map_ei + Celix::long_hash_map_ei + Celix::array_list_ei + Celix::properties_ei + Celix::utils_ei Celix::mdnsresponder_ei Celix::malloc_ei GTest::gtest diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index dfefa0182..ab40dec29 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -32,17 +32,22 @@ extern "C" { #include "eventfd_ei.h" #include "celix_threads_ei.h" #include "celix_bundle_context_ei.h" +#include "celix_string_hash_map_ei.h" +#include "celix_array_list_ei.h" +#include "celix_properties_ei.h" +#include "celix_utils_ei.h" #include "mdnsresponder_ei.h" #include "malloc_ei.h" #include #include #include -#include #include #include #include #include -#include +#include + +#define DZC_TEST_CONFIG_TYPE "celix.config_type.test" static int GetLoopBackIfIndex(void); @@ -77,6 +82,10 @@ class DiscoveryZeroconfAnnouncerTestSuite : public ::testing::Test { celix_ei_expect_DNSServiceProcessResult(nullptr, 0, 0); celix_ei_expect_TXTRecordSetValue(nullptr, 0, 0); celix_ei_expect_calloc(nullptr, 0, nullptr); + celix_ei_expect_celix_stringHashMap_create(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); } std::shared_ptr fw{}; @@ -134,6 +143,20 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed6) { EXPECT_EQ(status, CELIX_ENOMEM); } +TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed7) { + discovery_zeroconf_announcer_t *announcer{nullptr}; + celix_ei_expect_celix_stringHashMap_create((void*)&discoveryZeroconfAnnouncer_create, 0, nullptr); + auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); + EXPECT_EQ(status, CELIX_ENOMEM); +} + +TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed8) { + discovery_zeroconf_announcer_t *announcer{nullptr}; + celix_ei_expect_celix_arrayList_create((void*)&discoveryZeroconfAnnouncer_create, 0, nullptr); + auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); + EXPECT_EQ(status, CELIX_ENOMEM); +} + TEST_F(DiscoveryZeroconfAnnouncerTestSuite, ConnectDNSServiceOneTimeFailure) { discovery_zeroconf_announcer_t *announcer{nullptr}; celix_ei_expect_DNSServiceCreateConnection(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); @@ -181,9 +204,9 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); EXPECT_TRUE(celix_properties_getAsLong(prop, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0) > 0); - //The txt record should not include DZC_SERVICE_ANNOUNCED_IF_INDEX_KEY,DZC_SERVICE_TYPE_KEY - EXPECT_EQ(nullptr, celix_properties_get(prop, CELIX_RSA_NETWORK_INTERFACES, nullptr)); - //EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_SERVICE_TYPE_KEY, nullptr));TODO + //The txt record should not include ifname and port key + EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_TEST_CONFIG_TYPE".ifname", nullptr)); + EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_TEST_CONFIG_TYPE".port", nullptr)); DNSServiceRefDeallocate(dsRef); celix_properties_destroy(prop); } @@ -195,17 +218,17 @@ static void OnUseServiceCallback(void *handle, void *svc) { const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, "all"); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); } else if (t->ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -260,7 +283,7 @@ static void OnUseServiceCallbackForRegisterServiceFailure(void *handle, void *sv celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -298,17 +321,17 @@ static void OnUseServiceCallbackForNameConflict(void *handle, void *svc) { const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, "all"); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); } else if (t->ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -403,17 +426,17 @@ static void OnUseServiceWithJumboEndpointCallback(void *handle, void *svc) { const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, "all"); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); } else if (t->ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); for (int i = 0; i < 500; ++i) { char key[20]{}; sprintf(key,"custom_key%d", i); @@ -473,8 +496,7 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); - //celix_properties_set(properties, DZC_SERVICE_TYPE_KEY, "invalid_service_type_because_the_size_large_than_48");TODO + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.invalid_service_type_because_the_size_large_than_64_----------------"); endpoint_description_t *endpoint{}; status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -483,8 +505,32 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { status = epl->endpointAdded(epl->handle, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + //imported config too long + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_ifname-------------------------------------------------------------------------.subtype"); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + + //too many imported configs + char configTypes[256] = "config_type"; + auto offset = strlen(configTypes); + int i = 0; + while (offset < 256) { + offset += snprintf(configTypes + offset, 256 - offset, ",config_type-%d", ++i); + } + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, configTypes); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + + //lost imported config + celix_properties_unset(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + //lost service name - //celix_properties_unset(properties, DZC_SERVICE_TYPE_KEY);//TODO + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); celix_properties_unset(properties, CELIX_FRAMEWORK_SERVICE_NAME); status = epl->endpointAdded(epl->handle, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); @@ -507,25 +553,55 @@ static void OnUseServiceForAddEndpointENOMEM(void *handle, void *svc) { const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, "all"); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); } else if (t->ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, CELIX_RSA_NETWORK_INTERFACES, if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "dzc_test_config_type"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); + celix_ei_expect_celix_properties_copy(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr); + + celix_ei_expect_celix_stringHashMap_createWithOptions(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_stringHashMap_createWithOptions(nullptr, 0, nullptr); + + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); + + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); status = epl->endpointAdded(epl->handle, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); + + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 2); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); + epl->endpointRemoved(epl->handle, endpoint, nullptr); endpointDescription_destroy(endpoint); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 5778f78c6..879e9ebc9 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -18,11 +18,15 @@ */ #include "discovery_zeroconf_watcher.h" #include "discovery_zeroconf_constants.h" +#include "remote_service_admin.h" #include "endpoint_listener.h" -#include #include "remote_constants.h" #include "celix_threads_ei.h" #include "celix_bundle_context_ei.h" +#include "celix_string_hash_map_ei.h" +#include "celix_long_hash_map_ei.h" +#include "celix_properties_ei.h" +#include "celix_utils_ei.h" #include "mdnsresponder_ei.h" #include "malloc_ei.h" #include "celix_framework.h" @@ -31,44 +35,72 @@ #include "celix_properties.h" #include "celix_constants.h" #include "celix_errno.h" +#include "celix_log_service.h" +#include "celix_log_utils.h" +#include "celix_log_constants.h" +#include #include #include #include #include #include +#define DZC_TEST_CONFIG_TYPE "celix.config_type.test" +#define DZC_TEST_SERVICE_TYPE DZC_SERVICE_PRIMARY_TYPE",test" //use the last word of config type as service subtype +#define DZC_TEST_SERVICE_PORT 60001 + static const char *DZC_TEST_ENDPOINT_FW_UUID = "61EC83D5-A808-DA12-3615-B68376C35357"; -static sem_t syncSem; -static bool waitSyncSemTimeout(int s) { +static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *instanceName, const char *serviceType, const char *domain, void *data); +static DNSServiceRef RegisterTestService(const char *endpointId = "60f49d89-d105-430c-b12b-93fbb54b1d19", const char *serviceId = "100"); + +static const char *expectErrMsg = nullptr; +static sem_t msgSyncSem; +static void vlogDetails(void *handle, + celix_log_level_e level, + const char* file, + const char* function, + int line, + const char* format, + va_list formatArgs) { + (void)handle; + if (expectErrMsg != nullptr && strcmp(expectErrMsg, format) == 0) { + sem_post(&msgSyncSem); + } + celix_logUtils_vLogToStdoutDetails("DiscoveryZeroconf", level, file, function, line, format, formatArgs); +} + +static void ExpectMsgOutPut(const char *msg) { + expectErrMsg = msg; +} +static bool CheckMsgWithTimeOutInS(int secs) { struct timespec ts{}; clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += s; + ts.tv_sec += secs; errno = 0; - while ((sem_timedwait(&syncSem, &ts)) == -1 && errno == EINTR) + while ((sem_timedwait(&msgSyncSem, &ts)) == -1 && errno == EINTR) continue; return errno == ETIMEDOUT; } static celix_status_t discoveryZeroconfWatcherTest_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { - (void)handle; + auto logHelper = static_cast(handle); (void)matchedFilter; - EXPECT_STREQ("60f49d89-d105-430c-b12b-93fbb54b1d19", endpoint->id); EXPECT_STREQ("dzc_test_service", endpoint->serviceName); - EXPECT_EQ(100, endpoint->serviceId); - sem_post(&syncSem); + celix_logHelper_info(logHelper, "Endpoint added: %s.", endpoint->id); return CELIX_SUCCESS; } static celix_status_t discoveryZeroconfWatcherTest_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { - (void)handle; + auto logHelper = static_cast(handle); (void)endpoint; (void)matchedFilter; - + celix_logHelper_info(logHelper, "Endpoint removed: %s.", endpoint->id); return CELIX_SUCCESS; } + class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { public: static void SetUpTestCase() { @@ -83,15 +115,32 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { auto* props = celix_properties_create(); celix_properties_set(props, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, "true"); celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".dzc_watcher_test_cache"); + celix_properties_set(props, CELIX_LOGGING_DEFAULT_ACTIVE_LOG_LEVEL_CONFIG_NAME, "trace"); auto* fwPtr = celix_frameworkFactory_createFramework(props); auto* ctxPtr = celix_framework_getFrameworkContext(fwPtr); fw = std::shared_ptr{fwPtr, [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; ctx = std::shared_ptr{ctxPtr, [](auto*){/*nop*/}}; auto* logHelperPtr = celix_logHelper_create(ctxPtr,"DiscoveryZeroconf"); logHelper = std::shared_ptr{logHelperPtr, [](auto*l){ celix_logHelper_destroy(l);}}; + epListener.handle = logHelperPtr; eplId = celix_bundleContext_registerService(ctxPtr, &epListener, OSGI_ENDPOINT_LISTENER_SERVICE, nullptr); EXPECT_LE(0, eplId); - sem_init(&syncSem, 0, 0); + auto rsaSvcProps = celix_properties_create(); + celix_properties_set(rsaSvcProps, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, DZC_TEST_CONFIG_TYPE); + rsaSvcId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", OSGI_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); + EXPECT_LE(0, rsaSvcId); + logService.handle = nullptr; + logService.vlogDetails = vlogDetails; + celix_service_registration_options_t opts{}; + opts.svc = &logService; + opts.serviceName = CELIX_LOG_SERVICE_NAME; + opts.serviceVersion = CELIX_LOG_SERVICE_VERSION; + opts.properties = celix_properties_create(); + celix_properties_set(opts.properties, CELIX_LOG_SERVICE_PROPERTY_NAME, "DiscoveryZeroconf"); + lsId = celix_bundleContext_registerServiceWithOptions(ctxPtr, &opts); + EXPECT_LE(0, lsId); + + sem_init(&msgSyncSem, 0, 0); } ~DiscoveryZeroconfWatcherTestSuite() override { @@ -102,17 +151,149 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { celix_ei_expect_DNSServiceCreateConnection(nullptr, 0, 0); celix_ei_expect_DNSServiceBrowse(nullptr, 0, 0); celix_ei_expect_DNSServiceProcessResult(nullptr, 0, 0); + celix_ei_expect_DNSServiceResolve(nullptr, 0, 0, 0); + celix_ei_expect_DNSServiceGetAddrInfo(nullptr, 0, 0, 0); celix_ei_expect_calloc(nullptr, 0, nullptr); - - sem_destroy(&syncSem); + celix_ei_expect_celix_stringHashMap_create(nullptr, 0, nullptr); + celix_ei_expect_celix_stringHashMap_createWithOptions(nullptr, 0, nullptr); + celix_ei_expect_celix_longHashMap_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); + celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); + + sem_destroy(&msgSyncSem); + celix_bundleContext_unregisterService(ctx.get(), lsId); + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId); celix_bundleContext_unregisterService(ctx.get(), eplId); } + void TestRsaServiceAddAndRemove(void (*beforeAddRsaAction)(void), void (*afterAddRsaAction)(void), + void (*beforeRemoveRsaAction)(void) = nullptr, void (*afterRemoveRsaAction)(void) = nullptr, const char *remoteConfigsSupported = DZC_TEST_CONFIG_TYPE) { + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service id + rsaSvcId = -1; + discovery_zeroconf_watcher_t *watcher; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_waitForEvents(ctx.get()); + + beforeAddRsaAction(); + + auto rsaSvcProps = celix_properties_create(); + celix_properties_set(rsaSvcProps, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, remoteConfigsSupported); + auto rsaId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", OSGI_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); + EXPECT_LE(0, rsaId); + + afterAddRsaAction(); + + if (beforeRemoveRsaAction != nullptr) { + beforeRemoveRsaAction(); + } + + celix_bundleContext_unregisterService(ctx.get(), rsaId); + + if (afterRemoveRsaAction != nullptr) { + afterRemoveRsaAction(); + } + + discoveryZeroconfWatcher_destroy(watcher); + + } + + void TestAddEndpoint(void (*beforeAddEndpoint)(void), void (*afterAddEndpoint)(void)) { + discovery_zeroconf_watcher_t *watcher; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_waitForEvents(ctx.get()); + + beforeAddEndpoint(); + + auto dsRef = RegisterTestService(); + + afterAddEndpoint(); + + DNSServiceRefDeallocate(dsRef); + + discoveryZeroconfWatcher_destroy(watcher); + } + + void TestInvalidTxtRecord(void (*beforeAddTxt)(TXTRecordRef *txtRecord), void (*afterAddTxt)(void)) { + discovery_zeroconf_watcher_t *watcher; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_waitForEvents(ctx.get()); + + char txtBuf[1300] = {0}; + TXTRecordRef txtRecord; + TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + + beforeAddTxt(&txtRecord); + + char propSizeStr[16]= {0}; + sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); + TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + DNSServiceRef dsRef{}; + DNSServiceErrorType dnsErr; + dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", + DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), + TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), + OnDNSServiceRegisterCallback, nullptr); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + DNSServiceProcessResult(dsRef); + + afterAddTxt(); + + DNSServiceRefDeallocate(dsRef); + + discoveryZeroconfWatcher_destroy(watcher); + } + + void TestGetAddrInfo(void (*beforeRegServiceAction)(void), void (*afterRegServiceAction)(void), int interfaceIndex = kDNSServiceInterfaceIndexAny) { + discovery_zeroconf_watcher_t *watcher; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + char txtBuf[1300] = {0}; + TXTRecordRef txtRecord; + TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + char propSizeStr[16]= {0}; + sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); + TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + + beforeRegServiceAction(); + + DNSServiceRef dsRef{}; + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, interfaceIndex, + "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, + htons(DZC_TEST_SERVICE_PORT), + TXTRecordGetLength(&txtRecord), + TXTRecordGetBytesPtr(&txtRecord), + OnDNSServiceRegisterCallback, nullptr); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + DNSServiceProcessResult(dsRef); + TXTRecordDeallocate(&txtRecord); + + afterRegServiceAction(); + + DNSServiceRefDeallocate(dsRef); + sleep(2);//wait for service removed from mdnsd, avoid affect other test case + discoveryZeroconfWatcher_destroy(watcher); + } + std::shared_ptr fw{}; std::shared_ptr ctx{}; std::shared_ptr logHelper{}; endpoint_listener_t epListener{nullptr,discoveryZeroconfWatcherTest_endpointAdded, discoveryZeroconfWatcherTest_endpointRemoved}; + celix_log_service_t logService{}; long eplId{-1}; + long lsId{-1}; + long rsaSvcId{-1}; }; TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateAndDestroyWatcher) { @@ -170,6 +351,93 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed5) { EXPECT_EQ(CELIX_ENOMEM, status); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed6) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_stringHashMap_create((void*)&discoveryZeroconfWatcher_create, 0, nullptr); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed7) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_stringHashMap_createWithOptions((void*)&discoveryZeroconfWatcher_create, 0, nullptr); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed8) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_stringHashMap_create((void*)&discoveryZeroconfWatcher_create, 0, nullptr, 2); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed9) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_stringHashMap_create((void*)&discoveryZeroconfWatcher_create, 0, nullptr, 3); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed10) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_longHashMap_create((void*)&discoveryZeroconfWatcher_create, 0, nullptr); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed11) { + discovery_zeroconf_watcher_t *watcher; + celix_ei_expect_celix_bundleContext_trackServicesWithOptionsAsync((void*)&discoveryZeroconfWatcher_create, 0, -1, 2); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_BUNDLE_EXCEPTION, status); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, AddRsaServiceWithOutRemoteConfigsSupported) { + TestRsaServiceAddAndRemove([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to dup remote configs supported."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }, [](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to dup remote configs supported."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, AddRsaServiceWithInvalidRemoteConfigsSupported) { + TestRsaServiceAddAndRemove([](){ + ExpectMsgOutPut("Watcher: Invalid service type for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }, nullptr, nullptr, "celix.config_type_last_word_lager_than_63-----------------------------"); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForBrowserEntry) { + TestRsaServiceAddAndRemove([](){ + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to alloc service browser entry."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutBrowserEntryToCache) { + TestRsaServiceAddAndRemove([](){ + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to put service browser entry."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }); +} + static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *instanceName, const char *serviceType, const char *domain, void *data) { (void)sdRef;//unused (void)data;//unused @@ -181,53 +449,222 @@ static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags fl return; } -static DNSServiceRef RegisterTestService(void) { +static DNSServiceRef RegisterTestService(const char *endpointId, const char *serviceId) { char txtBuf[1300] = {0}; TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen(endpointId), endpointId); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen(serviceId), serviceId); TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen("dzc_test_config_type"), "dzc_test_config_type"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DNSServiceErrorType dnsErr; + int conflictCount = 0; + do { + conflictCount++; + char name[32]={0}; + snprintf(name, sizeof(name), "dzc_test_service_%d", conflictCount); + dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, name, + DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), + TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), + OnDNSServiceRegisterCallback, nullptr); + }while (dnsErr == kDNSServiceErr_NameConflict); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); return dsRef; } TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpoint) { + TestAddEndpoint([](){ + ExpectMsgOutPut("Endpoint added: %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, AddMultiEndpoint) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_waitForEvents(ctx.get()); - auto dsRef = RegisterTestService(); + ExpectMsgOutPut("Endpoint added: %s."); + + auto dsRef1 = RegisterTestService(); + auto dsRef2 = RegisterTestService("65d17a8c-f31b-478c-b13e-da743c96ab51", "101"); - auto timeOut = waitSyncSemTimeout(30); + //wait for endpoint1 added + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - DNSServiceRefDeallocate(dsRef); + //wait for endpoint2 added + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + ExpectMsgOutPut("Endpoint removed: %s."); + + DNSServiceRefDeallocate(dsRef1); + + //wait for endpoint1 added + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + DNSServiceRefDeallocate(dsRef2); + + //wait for endpoint2 added + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); discoveryZeroconfWatcher_destroy(watcher); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyEndpointProperties) { + TestAddEndpoint([](){ + celix_ei_expect_celix_properties_copy(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to copy endpoint properties."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForEndpointEntry) { + TestAddEndpoint([](){ + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); + ExpectMsgOutPut("Watcher: Failed to alloc endpoint entry."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyHostNameForEndpointEntry) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); + ExpectMsgOutPut("Watcher: Failed to create hostname for endpoint %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetHostIpAddressesWhenCreateEndpoint) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); + ExpectMsgOutPut("Watcher: Failed to create ip address list."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupImportedConfigsWhenCreateEndpoint) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 6); + ExpectMsgOutPut("Watcher: Failed to dup imported configs."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutEndpointToCache) { + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 5); + TestAddEndpoint([](){ + ExpectMsgOutPut("Watcher: Failed to add endpoint for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { + TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ + TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "-1"); + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + //No endpoint framework uuid + ExpectMsgOutPut("Watcher: Failed to create endpoint description."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { + TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ + TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + //NO imported configs + ExpectMsgOutPut("Watcher: No imported configs."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { + TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ + TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + const char *invalidImportedConfigs = "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"; + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); + + ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs2) { + TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ + TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + const char *invalidImportedConfigs = "celix.imported_config_too_long_for_ipaddresses--------------------------------------------------------------------.subtype"; + TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); + + ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateDNSServiceConnectionFailedOnce) { discovery_zeroconf_watcher_t *watcher; celix_ei_expect_DNSServiceCreateConnection(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); + ExpectMsgOutPut("Watcher: Failed to create connection for DNS service, %d."); celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); auto dsRef = RegisterTestService(); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); @@ -238,47 +675,178 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceBrowseFailedOnce) { discovery_zeroconf_watcher_t *watcher; celix_ei_expect_DNSServiceBrowse(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); + ExpectMsgOutPut("Watcher: Failed to browse DNS service, %d."); celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); auto dsRef = RegisterTestService(); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); discoveryZeroconfWatcher_destroy(watcher); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResultProcessFailed1) { +TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed1) { + discovery_zeroconf_watcher_t *watcher; + + celix_ei_expect_celix_stringHashMap_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); + ExpectMsgOutPut("Watcher: Failed to create updated service browsers cache."); + + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + auto dsRef = RegisterTestService(); + + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + DNSServiceRefDeallocate(dsRef); + discoveryZeroconfWatcher_destroy(watcher); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed2) { + discovery_zeroconf_watcher_t *watcher; + + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 2); + ExpectMsgOutPut("Watcher: Failed to put browse entry, %d."); + + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + auto dsRef = RegisterTestService(); + + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + DNSServiceRefDeallocate(dsRef); + discoveryZeroconfWatcher_destroy(watcher); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed3) { discovery_zeroconf_watcher_t *watcher; - celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_ServiceNotRunning, 2); + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + ExpectMsgOutPut("Endpoint added: %s."); + + auto dsRef = RegisterTestService(); + + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to put browse entry, %d."); + + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId); + rsaSvcId = -1; + + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + DNSServiceRefDeallocate(dsRef); + discoveryZeroconfWatcher_destroy(watcher); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForSvcEntry) { + TestAddEndpoint([](){ + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to alloc service entry."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCreateTxtRecordForSvcEntry) { + TestAddEndpoint([](){ + celix_ei_expect_celix_properties_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to create txt record for service entry."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutSvcEntryToCache) { + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 3); + TestAddEndpoint([](){ + ExpectMsgOutPut("Watcher: Failed to put service entry, %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, UnregisterRsaWhenBrowseServices) { + discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + ExpectMsgOutPut("Endpoint added: %s."); + auto dsRef = RegisterTestService(); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId); + rsaSvcId = -1; + DNSServiceRefDeallocate(dsRef); discoveryZeroconfWatcher_destroy(watcher); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResultProcessFailed1) { + discovery_zeroconf_watcher_t *watcher; + + auto dsRef = RegisterTestService(); + + celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_ServiceNotRunning); + ExpectMsgOutPut("Watcher: mDNS connection may be broken, %d."); + + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + discoveryZeroconfWatcher_destroy(watcher); + DNSServiceRefDeallocate(dsRef); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResultProcessFailed2) { discovery_zeroconf_watcher_t *watcher; - celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown, 2); + auto dsRef = RegisterTestService(); + + celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); + ExpectMsgOutPut("Watcher: Failed to process mDNS result, %d."); + + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); + + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + discoveryZeroconfWatcher_destroy(watcher); + DNSServiceRefDeallocate(dsRef); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResolveFailedOnce) { + discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + celix_ei_expect_DNSServiceResolve(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory); + ExpectMsgOutPut("Watcher: Failed to resolve %s on %d, %d."); auto dsRef = RegisterTestService(); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); @@ -294,26 +862,101 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); const char *fwUuid = celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); + TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid == nullptr ? 0 : strlen(fwUuid), fwUuid); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_self_fw_service"), "dzc_test_self_fw_service"); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen("dzc_test_config_type"), "dzc_test_config_type"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + ExpectMsgOutPut("Watcher: Ignore self endpoint for %s."); + DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_self_fw_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_self_fw_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + DNSServiceRefDeallocate(dsRef); discoveryZeroconfWatcher_destroy(watcher); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceGetAddrInfoFailedOnce) { + TestAddEndpoint([](){ + celix_ei_expect_DNSServiceGetAddrInfo(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory); + ExpectMsgOutPut("Watcher: Failed to get address info for %s on %d, %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForHostEntry) { + TestAddEndpoint([](){ + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + ExpectMsgOutPut("Watcher: Failed to alloc host entry for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForHostEntry) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + ExpectMsgOutPut("Watcher: Failed to create hostname for endpoint %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 4); + TestAddEndpoint([](){ + ExpectMsgOutPut("Watcher: Failed to add host entry for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, GetAddrInfo) { + TestGetAddrInfo([](){ + ExpectMsgOutPut("Endpoint added: %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutIpToHostEntry) { + TestGetAddrInfo([](){ + celix_ei_expect_celix_stringHashMap_putBool(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to add ip address(%s). %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutLoopBackIpToHostEntry) { + TestGetAddrInfo([](){ + celix_ei_expect_celix_stringHashMap_putBool(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to add localhost address. %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }, kDNSServiceInterfaceIndexLocalOnly); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); @@ -322,18 +965,21 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { char txtBuf[1300] = {0}; TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d18"), "60f49d89-d105-430c-b12b-93fbb54b1d18"); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen("dzc_test_config_type"), "dzc_test_config_type"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1 + 5); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + ExpectMsgOutPut("Endpoint added: %s."); + DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); TXTRecordDeallocate(&txtRecord); @@ -353,7 +999,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); TXTRecordDeallocate(&txtRecord); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); @@ -368,30 +1014,33 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { char txtBuf[1300] = {0}; TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen("dzc_test_config_type"), "dzc_test_config_type"); + TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); + ExpectMsgOutPut("Endpoint added: %s."); + DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_SERVICE_PRIMARY_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); - auto timeOut = waitSyncSemTimeout(30); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - endpoint_listener_t epListener{nullptr,discoveryZeroconfWatcherTest_endpointAdded, discoveryZeroconfWatcherTest_endpointRemoved}; + endpoint_listener_t epListener{logHelper.get(),discoveryZeroconfWatcherTest_endpointAdded, discoveryZeroconfWatcherTest_endpointRemoved}; long listenerId = celix_bundleContext_registerService(ctx.get(), &epListener, OSGI_ENDPOINT_LISTENER_SERVICE, nullptr); EXPECT_LE(0, listenerId); - timeOut = waitSyncSemTimeout(30); + timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); celix_bundleContext_unregisterService(ctx.get(), listenerId); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index a61e7f2e3..edfd98bcc 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -28,7 +28,6 @@ #include "celix_string_hash_map.h" #include "celix_array_list.h" #include "celix_log_helper.h" -#include "celix_types.h" #include "celix_errno.h" #include "celix_build_assert.h" #include "celix_stdlib_cleanup.h" @@ -83,11 +82,11 @@ typedef struct announce_endpoint_entry { int ifIndex; int port; const char *serviceName; - char *serviceType;//it is enough to cache the service type + char *serviceType; bool announced; }announce_endpoint_entry_t; - +static void endpointEntry_destroy(announce_endpoint_entry_t *entry); static void discoveryZeroconfAnnouncer_eventNotify(discovery_zeroconf_announcer_t *announcer); static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter); static celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter); @@ -121,9 +120,16 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce celix_autoptr(celix_thread_mutex_t) mutex = &announcer->mutex; celix_autoptr(celix_string_hash_map_t) endpoints = announcer->endpoints = celix_stringHashMap_create(); - assert(announcer->endpoints != NULL); + if (endpoints == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Announcer: Failed to create endpoints map."); + return CELIX_ENOMEM; + } celix_autoptr(celix_array_list_t) revokedEndpoints = announcer->revokedEndpoints = celix_arrayList_create(); - assert(announcer->revokedEndpoints != NULL); + if (revokedEndpoints == NULL) { + celix_logHelper_fatal(logHelper, "Announcer: Failed to create revoked endpoints list."); + return CELIX_ENOMEM; + } const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); if (fwUuid == NULL || strlen(fwUuid) >= sizeof(announcer->fwUuid)) { @@ -183,17 +189,13 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce int size = celix_arrayList_size(announcer->revokedEndpoints); for (int i = 0; i < size; ++i) { entry = (announce_endpoint_entry_t *)celix_arrayList_get(announcer->revokedEndpoints, i); - celix_properties_destroy(entry->properties); - free(entry->serviceType); - free(entry); + endpointEntry_destroy(entry); } celix_arrayList_destroy(announcer->revokedEndpoints); CELIX_STRING_HASH_MAP_ITERATE(announcer->endpoints,iter) { entry = (announce_endpoint_entry_t *) iter.value.ptrValue; - celix_properties_destroy(entry->properties); - free(entry->serviceType); - free(entry); + endpointEntry_destroy(entry); } celix_stringHashMap_destroy(announcer->endpoints); @@ -227,8 +229,94 @@ static bool isLoopBackNetInterface(const char *ifName) { return loopBack; } +static int discoveryZeroconfAnnouncer_setServiceSubTypeTo(discovery_zeroconf_announcer_t *announcer, const char *importedConfigType, celix_string_hash_map_t *svcSubTypes) { + //We use the last word of config type as mDNS service subtype(https://www.rfc-editor.org/rfc/rfc6763.html#section-7.1). so we can browse the service by the last word of config type. + const char *svcSubType = strrchr(importedConfigType, '.'); + if (svcSubType != NULL) { + svcSubType += 1;//skip '.' + } else { + svcSubType = importedConfigType; + } + size_t subTypeLen = strlen(svcSubType); + if (subTypeLen ==0 || subTypeLen > 63) {//the subtype identifier is allowed to be up to 63 bytes, see https://www.rfc-editor.org/rfc/rfc6763.html#section-7.2 + celix_logHelper_error(announcer->logHelper, "Announcer: Invalid service sub type for %s.", importedConfigType); + return CELIX_ILLEGAL_ARGUMENT; + } + int status = celix_stringHashMap_put(svcSubTypes, svcSubType, NULL); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put service sub type for %s. %d", importedConfigType, status); + return status; + } + return CELIX_SUCCESS; +} + +static int discoveryZeroconfAnnouncer_createEndpointEntry(discovery_zeroconf_announcer_t *announcer, const char *ifName, int port, const celix_string_hash_map_t *svcSubTypes, celix_properties_t *properties, announce_endpoint_entry_t **entryOut) { + celix_autoptr(celix_properties_t) propertiesPtr = properties; + celix_autofree announce_endpoint_entry_t *entry = (announce_endpoint_entry_t *)calloc(1, sizeof(*entry)); + if (entry == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to alloc endpoint entry."); + return CELIX_ENOMEM; + } + entry->registerRef = NULL; + entry->announced = false; + if (ifName != NULL) { + if (strcmp(ifName, "all") == 0) { + entry->ifIndex = kDNSServiceInterfaceIndexAny; + } else if (isLoopBackNetInterface(ifName)) { + // If it is a loopback interface,we will announce the service on the local only interface. + // Because the mDNSResponder will skip the loopback interface,if it found a normal interface. + entry->ifIndex = kDNSServiceInterfaceIndexLocalOnly; + } else { + entry->ifIndex = (int)if_nametoindex(ifName); + if (entry->ifIndex == 0) { + celix_logHelper_error(announcer->logHelper, "Announcer: Invalid network interface name %s.", ifName); + return CELIX_ILLEGAL_ARGUMENT; + } + } + } else { + entry->ifIndex = DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT; + } + entry->port = port; + + char serviceType[DZC_MAX_SERVICE_TYPE_LEN] = {0}; + CELIX_BUILD_ASSERT(sizeof(serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); + strcpy(serviceType, DZC_SERVICE_PRIMARY_TYPE); + size_t offset = strlen(serviceType); + CELIX_STRING_HASH_MAP_ITERATE(svcSubTypes, iter) { + offset += snprintf(serviceType + offset, sizeof(serviceType) - offset, ",%s", iter.key); + if (offset >= sizeof(serviceType)) { + celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of imported configs for %s.", serviceType); + return CELIX_ILLEGAL_ARGUMENT; + } + } + celix_autofree char *serviceTypePtr = entry->serviceType = celix_utils_strdup(serviceType); + if (serviceTypePtr == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy service type."); + return CELIX_ENOMEM; + } + entry->serviceName = celix_properties_get(propertiesPtr, CELIX_FRAMEWORK_SERVICE_NAME, NULL); + if (entry->serviceName == NULL) { + celix_logHelper_error(announcer->logHelper,"Announcer: Invalid service."); + return CELIX_ILLEGAL_ARGUMENT; + } + entry->properties = celix_steal_ptr(propertiesPtr); + celix_steal_ptr(serviceTypePtr); + *entryOut = celix_steal_ptr(entry); + return CELIX_SUCCESS; +} + +static void endpointEntry_destroy(announce_endpoint_entry_t *entry) { + celix_properties_destroy(entry->properties); + free(entry->serviceType); + free(entry); + return; +} +CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(announce_endpoint_entry_t, endpointEntry_destroy) + static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { (void)matchedFilter;//unused + int status = CELIX_SUCCESS; discovery_zeroconf_announcer_t *announcer = (discovery_zeroconf_announcer_t *)handle; assert(announcer != NULL); if (endpointDescription_isInvalid(endpoint)) { @@ -246,6 +334,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en celix_autoptr(celix_properties_t) properties = celix_properties_copy(endpoint->properties); if (properties == NULL) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy endpoint properties."); return CELIX_ENOMEM; } @@ -253,13 +342,17 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en opts.storeKeysWeakly = true; celix_autoptr(celix_string_hash_map_t) svcSubTypes = celix_stringHashMap_createWithOptions(&opts); if (svcSubTypes == NULL) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create svc sub types map."); return CELIX_ENOMEM; } - + celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); + if (importedConfigsCopy == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to dup imported configs."); + return CELIX_ENOMEM; + } const char *ifName = NULL; int port = DZC_PORT_DEFAULT; - celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); char *savePtr = NULL; char *token = strtok_r(importedConfigsCopy, ",", &savePtr); while (token != NULL) { @@ -270,7 +363,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en return CELIX_ILLEGAL_ARGUMENT; } //We only need to get one imported config port/ifname property, because all imported configs listed in this property must be synonymous(see https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1710847). - port = celix_properties_getAsLong(endpoint->properties, key, port); + port = (int)celix_properties_getAsLong(endpoint->properties, key, port); celix_properties_unset(properties, key);//port should not set to mDNS TXT record, because it will be set to SRV record. see https://www.rfc-editor.org/rfc/rfc6763.html#section-6.3 if(snprintf(key, sizeof(key), "%s.ifname", token) >= sizeof(key)) { @@ -280,81 +373,32 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en ifName = celix_properties_get(endpoint->properties, key, ifName); celix_properties_unset(properties, key);//ifname should not set to mDNS TXT record, because service consumer will not use it. - //We use the last word of config type as mDNS service subtype(https://www.rfc-editor.org/rfc/rfc6763.html#section-7.1). so we can browse the service by the last word of config type. - const char *svcSubType = strrchr(token, '.'); - if (svcSubType != NULL) { - svcSubType += 1;//skip '.' - } else { - svcSubType = token; - } - size_t subTypeLen = strlen(svcSubType); - if (subTypeLen ==0 || subTypeLen > 63) {//the subtype identifier is allowed to be up to 63 bytes, see https://www.rfc-editor.org/rfc/rfc6763.html#section-7.2 - celix_logHelper_error(announcer->logHelper, "Announcer: Invalid service sub type for %s.", token); - return CELIX_ILLEGAL_ARGUMENT; - } - int status = celix_stringHashMap_put(svcSubTypes, svcSubType, NULL); + status = discoveryZeroconfAnnouncer_setServiceSubTypeTo(announcer, token, svcSubTypes); if (status != CELIX_SUCCESS) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put service sub type for %s. %d", token, status); return status; } token = strtok_r(NULL, ",", &savePtr); } - celix_autofree announce_endpoint_entry_t *entry = (announce_endpoint_entry_t *)calloc(1, sizeof(*entry)); - if (entry == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to alloc endpoint entry."); - return CELIX_ENOMEM; - } - entry->registerRef = NULL; - entry->announced = false; - if (ifName != NULL) { - if (strcmp(ifName, "all") == 0) { - entry->ifIndex = kDNSServiceInterfaceIndexAny; - } else if (isLoopBackNetInterface(ifName)) { - // If it is a loopback interface,we will announce the service on the local only interface. - // Because the mDNSResponder will skip the loopback interface,if it found a normal interface. - entry->ifIndex = kDNSServiceInterfaceIndexLocalOnly; - } else { - entry->ifIndex = if_nametoindex(ifName); - if (entry->ifIndex == 0) { - celix_logHelper_error(announcer->logHelper, "Announcer: Invalid network interface name %s.", ifName); - return CELIX_ILLEGAL_ARGUMENT; - } - } - } else { - entry->ifIndex = DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT; + celix_autoptr(announce_endpoint_entry_t) entry = NULL; + status = discoveryZeroconfAnnouncer_createEndpointEntry(announcer, ifName, port, svcSubTypes, celix_steal_ptr(properties), &entry); + if (status != CELIX_SUCCESS) { + return status; } - entry->port = port; - char serviceType[DZC_MAX_SERVICE_TYPE_LEN] = {0}; - CELIX_BUILD_ASSERT(sizeof(serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); - strcpy(serviceType, DZC_SERVICE_PRIMARY_TYPE); - size_t offset = strlen(serviceType); - CELIX_STRING_HASH_MAP_ITERATE(svcSubTypes, iter) { - offset += snprintf(serviceType + offset, sizeof(serviceType) - offset, ",%s", iter.key); - if (offset >= sizeof(serviceType)) { - celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of imported configs for %s.", importedConfigs); - return CELIX_ILLEGAL_ARGUMENT; - } - } - entry->serviceType = celix_utils_strdup(serviceType); - if (entry->serviceType == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy service type."); - return CELIX_ENOMEM; + celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&announcer->mutex); + status = celix_stringHashMap_put(announcer->endpoints, endpoint->id, entry); + if (status == CELIX_SUCCESS) { + celix_steal_ptr(entry); + } else { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put endpoint entry for %s.", endpoint->id); + return status; } - entry->properties = properties; - entry->serviceName = celix_properties_get(entry->properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL); - if (entry->serviceName == NULL) { - celix_logHelper_error(announcer->logHelper,"Announcer: Invalid service."); - return CELIX_ILLEGAL_ARGUMENT; - } - celixThreadMutex_lock(&announcer->mutex); - celix_stringHashMap_put(announcer->endpoints, endpoint->id, celix_steal_ptr(entry)); - celixThreadMutex_unlock(&announcer->mutex); discoveryZeroconfAnnouncer_eventNotify(announcer); - celix_steal_ptr(properties); + return CELIX_SUCCESS; } @@ -402,9 +446,7 @@ static void discoveryZeroconfAnnouncer_revokeEndpoints(discovery_zeroconf_announ if (entry->registerRef != NULL) { DNSServiceRefDeallocate(entry->registerRef); } - celix_properties_destroy(entry->properties); - free(entry->serviceType); - free(entry); + endpointEntry_destroy(entry); } return; } @@ -520,13 +562,13 @@ static void discoveryZeroconfAnnouncer_handleMDNSEvent(discovery_zeroconf_announ celixThreadMutex_lock(&announcer->mutex); CELIX_STRING_HASH_MAP_ITERATE(announcer->endpoints, iter) { entry = (announce_endpoint_entry_t *) iter.value.ptrValue; - entry->registerRef = NULL;//no need free entry->registerRef, 'DNSServiceRefDeallocate(announcer->sharedRef)' has do it. + entry->registerRef = NULL;//no need free entry->registerRef, 'DNSServiceRefDeallocate(announcer->sharedRef)' has done it. entry->announced = false; } int size = celix_arrayList_size(announcer->revokedEndpoints); for (int i = 0; i < size; ++i) { entry = celix_arrayList_get(announcer->revokedEndpoints, i); - entry->registerRef = NULL;//no need free entry->registerRef, 'DNSServiceRefDeallocate(announcer->sharedRef)' has do it. + entry->registerRef = NULL;//no need free entry->registerRef, 'DNSServiceRefDeallocate(announcer->sharedRef)' has done it. } celixThreadMutex_unlock(&announcer->mutex); } else if (dnsErr != kDNSServiceErr_NoError) { @@ -608,7 +650,8 @@ static void *discoveryZeroconfAnnouncer_refreshEndpointThread(void *data) { discoveryZeroconfAnnouncer_handleMDNSEvent(announcer); } } else if (result == -1 && errno != EINTR) { - celix_logHelper_error(announcer->logHelper, "Announcer: Error Selecting event, %d.", errno); + celix_logHelper_error(announcer->logHelper, "Announcer: Error Selecting event, %d.", errno); + sleep(1);//avoid busy loop } } if (announcer->sharedRef) { diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 84ad2d2cb..a4515f587 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -46,7 +46,7 @@ #include #include -#define DZC_EP_JITTER_INTERVAL 3//The jitter interval for endpoint.Avoid updating endpoint description on all network interfaces when only one network interface is updated.The endpoint description will be removed when the service is removed for 3 seconds. +#define DZC_EP_JITTER_INTERVAL 5//The jitter interval for endpoint.Avoid updating endpoint description on all network interfaces when only one network interface is updated.The endpoint description will be removed when the service is removed for 5 seconds. #define DZC_MAX_RESOLVED_CNT 10 //Max resolved count for each service when resolve service failed #define DZC_MAX_RETRY_INTERVAL 5 //Max retry interval when resolve service failed @@ -79,6 +79,7 @@ typedef struct watched_endpoint_entry { }watched_endpoint_entry_t; typedef struct watched_service_entry { + celix_log_helper_t *logHelper; celix_properties_t *txtRecord; const char *endpointId; int ifIndex; @@ -88,6 +89,7 @@ typedef struct watched_service_entry { bool resolved; int resolvedCnt; DNSServiceRef resolveRef; + bool reResolve; }watched_service_entry_t; typedef struct watched_epl_entry { @@ -99,10 +101,12 @@ typedef struct service_browser_entry { DNSServiceRef browseRef; int refCnt; int resolvedCnt; + bool toBeDeleted; }service_browser_entry_t; typedef struct watched_host_entry { DNSServiceRef sdRef; + celix_log_helper_t *logHelper; char *hostname; int ifIndex; celix_string_hash_map_t *ipAddresses;//key:ip address, val:true(ipv4)/false(ipv6) @@ -149,21 +153,41 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi return status; } celix_autoptr(celix_thread_mutex_t) mutex = &watcher->mutex; + celix_autoptr(celix_string_hash_map_t) serviceBrowsers = watcher->serviceBrowsers = celix_stringHashMap_create(); + if (serviceBrowsers == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Watcher: Failed to create service browsers map."); + return CELIX_ENOMEM; + } celix_string_hash_map_create_options_t epOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; epOpts.storeKeysWeakly = true; celix_autoptr(celix_string_hash_map_t) watchedEndpoints = watcher->watchedEndpoints = celix_stringHashMap_createWithOptions(&epOpts); - assert(watcher->watchedEndpoints); - watcher->watchedHosts = celix_stringHashMap_create(); - assert(watcher->watchedHosts != NULL); - celix_string_hash_map_create_options_t svcOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; + if (watchedEndpoints == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Watcher: Failed to create endpoints map."); + return CELIX_ENOMEM; + } + celix_autoptr(celix_string_hash_map_t) watchedHosts = watcher->watchedHosts = celix_stringHashMap_create(); + if (watchedHosts == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Watcher: Failed to create hosts map."); + return CELIX_ENOMEM; + } celix_autoptr(celix_string_hash_map_t) watchedServices = - watcher->watchedServices = celix_stringHashMap_createWithOptions(&svcOpts); - assert(watcher->watchedServices != NULL); - + watcher->watchedServices = celix_stringHashMap_create(); + if (watchedServices == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Watcher: Failed to create services map."); + return CELIX_ENOMEM; + } celix_autoptr(celix_long_hash_map_t) epls = watcher->epls = celix_longHashMap_create(); - assert(watcher->epls != NULL); + if (epls == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_fatal(logHelper, "Watcher: Failed to create endpoint listener map."); + return CELIX_ENOMEM; + } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; opts.filter.serviceName = OSGI_ENDPOINT_LISTENER_SERVICE; @@ -201,7 +225,9 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi celix_steal_ptr(epls); celix_steal_ptr(watchedServices); + celix_steal_ptr(watchedHosts); celix_steal_ptr(watchedEndpoints); + celix_steal_ptr(serviceBrowsers); celix_steal_ptr(mutex); celix_steal_fd(&eventFd); *watcherOut = celix_steal_ptr(watcher); @@ -306,10 +332,6 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix assert(props != NULL); discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); - if (configsSupported == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: No remote configs supported."); - return; - } celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); @@ -326,7 +348,7 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix svcSubType = token; } size_t subTypeLen = strlen(svcSubType); - if (subTypeLen ==0 || subTypeLen > 63) { + if (subTypeLen > 63) { celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service type for %s.", token); } else { celixThreadMutex_lock(&watcher->mutex); @@ -337,15 +359,16 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix browserEntry->refCnt = 1; browserEntry->resolvedCnt = 0; browserEntry->browseRef = NULL; + browserEntry->toBeDeleted = false; if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) == CELIX_SUCCESS) { refreshBrowsers = true; } else { free(browserEntry); - celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);//TODO check more function - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put browse entry."); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service browser entry."); } } else { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc browse entry."); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service browser entry."); } } else { browserEntry->refCnt++; @@ -369,11 +392,6 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce assert(props != NULL); discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); - if (configsSupported == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: No remote configs supported."); - return; - } - celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); @@ -412,11 +430,12 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, (void)interfaceIndex;//unused (void)port;//unused (void)fullname;//unused + watched_service_entry_t *svcEntry = (watched_service_entry_t *)context; + assert(svcEntry != NULL); if (errorCode != kDNSServiceErr_NoError || strlen(host) > DZC_MAX_HOSTNAME_LEN) { + celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to resolve service, or hostname invalid, %d.", errorCode); return; } - watched_service_entry_t *svcEntry = (watched_service_entry_t *)context; - assert(svcEntry != NULL); celix_properties_t *properties = svcEntry->txtRecord; int cnt = TXTRecordGetCount(txtLen, txtRecord); for (int i = 0; i < cnt; ++i) { @@ -426,25 +445,34 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint8_t valLen = 0; DNSServiceErrorType err = TXTRecordGetItemAtIndex(txtLen, txtRecord, i, sizeof(key), key, &valLen, &valPtr); if (err != kDNSServiceErr_NoError) { + celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to get txt record item(%s), %d.", key, err); return; } assert(valLen <= UINT8_MAX); memcpy(val, valPtr, valLen); - celix_properties_set(properties, key, val); + int status = celix_properties_set(properties, key, val); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(svcEntry->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to set txt record item(%s), %d.", key, status); + svcEntry->reResolve = (status == CELIX_ENOMEM) ? true : svcEntry->reResolve; + return; + } } svcEntry->endpointId = celix_properties_get(properties, OSGI_RSA_ENDPOINT_ID, NULL); long propSize = celix_properties_getAsLong(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0); const char *version = celix_properties_get(properties, DZC_TXT_RECORD_VERSION_KEY, ""); if (propSize == celix_properties_size(properties) && strcmp(DZC_CURRENT_TXT_RECORD_VERSION, version) == 0) { - //DZC_PORT_DEFAULT is used for the remote service that IPC is not network based(eg:shared memory). No need to resolve host information. - if (port != DZC_PORT_DEFAULT) { + svcEntry->port = ntohs(port); + //DZC_PORT_DEFAULT is used for the remote service that IPC is not network based(e.g.:shared memory). No need to resolve host information. + if (svcEntry->port != DZC_PORT_DEFAULT) { svcEntry->hostname = celix_utils_strdup(host); if (svcEntry->hostname == NULL) { + celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to dup hostname."); + svcEntry->reResolve = true; return; } } - svcEntry->port = port; celix_properties_unset(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY);//Service endpoint do not need it celix_properties_unset(properties, DZC_TXT_RECORD_VERSION_KEY);//Service endpoint do not need it svcEntry->resolved = true; @@ -475,23 +503,37 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, (void)snprintf(key, sizeof(key), "%s%d", instanceName, (int)interfaceIndex); if (flags & kDNSServiceFlagsAdd) { if (celix_stringHashMap_hasKey(watcher->watchedServices, key)) { - celix_logHelper_info(watcher->logHelper,"Watcher: %s already on interface %d.", instanceName, interfaceIndex); + celix_logHelper_debug(watcher->logHelper,"Watcher: %s already on interface %d.", instanceName, interfaceIndex); return; } svcEntry = (watched_service_entry_t *)calloc(1, sizeof(*svcEntry)); if (svcEntry == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed service entry."); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service entry."); return; } svcEntry->resolveRef = NULL; svcEntry->txtRecord = celix_properties_create(); + if (svcEntry->txtRecord == NULL) { + free(svcEntry); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create txt record for service entry."); + return; + } svcEntry->endpointId = NULL; svcEntry->resolved = false; strcpy(svcEntry->instanceName, instanceName); svcEntry->hostname = NULL; svcEntry->ifIndex = (int)interfaceIndex; svcEntry->resolvedCnt = 0; - celix_stringHashMap_put(watcher->watchedServices, key, svcEntry); + svcEntry->reResolve = false; + svcEntry->logHelper = watcher->logHelper; + int status = celix_stringHashMap_put(watcher->watchedServices, key, svcEntry); + if (status != CELIX_SUCCESS) { + celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service entry, %d.", status); + } } else { svcEntry = (watched_service_entry_t *)celix_stringHashMap_get(watcher->watchedServices, key); if (svcEntry) { @@ -507,34 +549,74 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, return; } -static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { +static void discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(discovery_zeroconf_watcher_t *watcher, celix_string_hash_map_t *updatedServiceBrowsers, unsigned int *pNextWorkIntervalTime) { + int status = CELIX_SUCCESS; unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + celixThreadMutex_lock(&watcher->mutex); + celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->serviceBrowsers); while (!celix_stringHashMapIterator_isEnd(&iter)) { service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; if (watcher->sharedRef != NULL && browserEntry->browseRef == NULL && browserEntry->refCnt > 0 && browserEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { - browserEntry->browseRef = watcher->sharedRef; - char serviceType[128] = {0};//primary type(15bytes) + subtype(63bytes) - (void)snprintf(serviceType, sizeof(serviceType), "%s,%s", DZC_SERVICE_PRIMARY_TYPE, iter.key); - DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, watcher); - if (dnsErr != kDNSServiceErr_NoError) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); - browserEntry->browseRef = NULL; + status = celix_stringHashMap_put(updatedServiceBrowsers, iter.key, browserEntry); + if (status != CELIX_SUCCESS) { nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put browse entry, %d.", status); } - browserEntry->resolvedCnt ++; - } else if (browserEntry->refCnt == 0) { + } else if (browserEntry->refCnt <= 0) { + status = celix_stringHashMap_put(updatedServiceBrowsers, iter.key, browserEntry); + if (status == CELIX_SUCCESS) { + celix_stringHashMapIterator_remove(&iter); + browserEntry->toBeDeleted = true; + continue; + } else { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put browse entry, %d.", status); + } + } + celix_stringHashMapIterator_next(&iter); + } + + celixThreadMutex_unlock(&watcher->mutex); + + //release to be deleted service browsers + celix_string_hash_map_iterator_t iter2 = celix_stringHashMap_begin(updatedServiceBrowsers); + while (!celix_stringHashMapIterator_isEnd(&iter2)) { + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter2.value.ptrValue; + if (browserEntry->toBeDeleted) { + celix_stringHashMapIterator_remove(&iter2); if (browserEntry->browseRef) { DNSServiceRefDeallocate(browserEntry->browseRef); } - celix_stringHashMapIterator_remove(&iter); free(browserEntry); - continue; + } else { + celix_stringHashMapIterator_next(&iter2); } - celix_stringHashMapIterator_next(&iter); } - celixThreadMutex_unlock(&watcher->mutex); + + *pNextWorkIntervalTime = nextWorkIntervalTime; + return; +} + +static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t *watcher, celix_string_hash_map_t *updatedServiceBrowsers, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + + CELIX_STRING_HASH_MAP_ITERATE(updatedServiceBrowsers, iter) { + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; + browserEntry->browseRef = watcher->sharedRef; + char serviceType[128] = {0};//primary type(15bytes) + subtype(63bytes) + (void)snprintf(serviceType, sizeof(serviceType), "%s,%s", DZC_SERVICE_PRIMARY_TYPE, iter.key); + DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, watcher); + if (dnsErr != kDNSServiceErr_NoError) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); + browserEntry->browseRef = NULL; + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + } + browserEntry->resolvedCnt ++; + } *pNextWorkIntervalTime = nextWorkIntervalTime; return; @@ -554,6 +636,16 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ } svcEntry->resolvedCnt ++; } + + if (svcEntry->reResolve) {//release resolveRef and retry resolve service after 5 seconds + svcEntry->reResolve = false; + if (svcEntry->resolveRef) { + DNSServiceRefDeallocate(svcEntry->resolveRef); + svcEntry->resolveRef = NULL; + } + svcEntry->resolvedCnt = 0; + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry resolve after 5 seconds + } } *pNextWorkIntervalTime = nextWorkIntervalTime; return; @@ -564,19 +656,25 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ (void)sdRef;//unused (void)ttl;//unused (void)hostname;//unused + int status = CELIX_SUCCESS; watched_host_entry_t *hostEntry = (watched_host_entry_t *)context; assert(hostEntry != NULL); if (errorCode == kDNSServiceErr_NoSuchRecord) { //If localonly interface cannot found record, then add localhost address.Because the mDNSResponder will skip the loopback interface,if it found a normal interface. if (ifIndex == kDNSServiceInterfaceIndexLocalOnly) { if (celix_stringHashMap_size(hostEntry->ipAddresses) == 0) { - celix_stringHashMap_putBool(hostEntry->ipAddresses, "127.0.0.1", true); + status = celix_stringHashMap_putBool(hostEntry->ipAddresses, "127.0.0.1", true); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(hostEntry->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(hostEntry->logHelper, "Watcher: Failed to add localhost address. %d.", status); + return; + } } hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); } return; } - if (errorCode != kDNSServiceErr_NoError || address != NULL || (address->sa_family != AF_INET && address->sa_family != AF_INET6)) { + if (errorCode != kDNSServiceErr_NoError || address == NULL || (address->sa_family != AF_INET && address->sa_family != AF_INET6)) { return; } @@ -588,12 +686,16 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ } if (flags & kDNSServiceFlagsAdd) { - celix_stringHashMap_putBool(hostEntry->ipAddresses, ip, address->sa_family == AF_INET); + status = celix_stringHashMap_putBool(hostEntry->ipAddresses, ip, address->sa_family == AF_INET); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(hostEntry->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(hostEntry->logHelper, "Watcher: Failed to add ip address(%s). %d.", ip, status); + } } else { celix_stringHashMap_remove(hostEntry->ipAddresses, ip); } - if (!(flags & kDNSServiceFlagsMoreComing) && celix_stringHashMap_size(hostEntry->ipAddresses) > 0) { + if (!(flags & kDNSServiceFlagsMoreComing)) { hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); hostEntry->activeStartTime.tv_sec += 2;//If the host information does not change within 2 seconds, we will use the host information to create endpoint description. } else { @@ -610,7 +712,7 @@ static watched_host_entry_t *discoveryZeroconfWatcher_getHostEntry(discovery_zer return (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); } -static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { +static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; //mark deleted hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { @@ -618,7 +720,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher hostEntry->markDeleted = true; } - //add new hosts + //add or mark hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; if (svcEntry->hostname != NULL) { @@ -629,20 +731,24 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher } else { hostEntry = (watched_host_entry_t *)calloc(1, sizeof(*hostEntry)); if (hostEntry == NULL) { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc host entry for %s.", svcEntry->instanceName); continue; } celix_autoptr(celix_string_hash_map_t) ipAddresses = hostEntry->ipAddresses = celix_stringHashMap_create(); if (ipAddresses == NULL) { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc ip address list for %s.", svcEntry->instanceName); continue; } celix_autofree char *hostname = hostEntry->hostname = celix_utils_strdup(svcEntry->hostname); if (hostname == NULL) { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create hostname for endpoint %s.", svcEntry->instanceName); continue; } hostEntry->sdRef = NULL; + hostEntry->logHelper = watcher->logHelper; hostEntry->activeStartTime.tv_sec = INT_MAX; hostEntry->ifIndex = svcEntry->ifIndex; hostEntry->resolvedCnt = 0; @@ -650,6 +756,8 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex); if (celix_stringHashMap_put(watcher->watchedHosts, key, hostEntry) != CELIX_SUCCESS) { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); celix_logHelper_error(watcher->logHelper, "Watcher: Failed to add host entry for %s.", svcEntry->instanceName); continue; } @@ -659,6 +767,14 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher } } } + *pNextWorkIntervalTime = nextWorkIntervalTime; + return; +} + +static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + + discoveryZeroconfWatcher_addHosts(watcher, &nextWorkIntervalTime); //delete hosts celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedHosts); @@ -682,7 +798,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; if (watcher->sharedRef && hostEntry->sdRef == NULL && hostEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { hostEntry->sdRef = watcher->sharedRef; - DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); + DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection | kDNSServiceFlagsReturnIntermediates, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); if (dnsErr != kDNSServiceErr_NoError) { hostEntry->sdRef = NULL; celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get address info for %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, dnsErr); @@ -690,18 +806,13 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher } hostEntry->resolvedCnt ++; } - double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); - if (hostEntry->activeStartTime.tv_sec != INT_MAX && elapsed < 0) { - unsigned int tmp = abs((int)elapsed); - nextWorkIntervalTime = MIN(nextWorkIntervalTime, tmp); - } } *pNextWorkIntervalTime = nextWorkIntervalTime; return; } -static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { +static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex, unsigned int *pNextWorkIntervalTime) { if (hostname == NULL) {//if no need to resolve host info, then return true return true; } @@ -709,15 +820,52 @@ static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t if (hostEntry == NULL) { return false; } - if (celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime) > 0) { + if (celix_stringHashMap_size(hostEntry->ipAddresses) == 0) { + return false; + } + double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); + if (elapsed >= 0) { return true; + } else if (hostEntry->activeStartTime.tv_sec != INT_MAX) { + unsigned int tmp = abs((int)elapsed); + *pNextWorkIntervalTime = MIN(*pNextWorkIntervalTime, tmp); } + return false; } +static int discoveryZeroConfWatcher_getHostIpAddresses(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex, char **ipAddressesStrOut) { + celix_autofree char *ipAddressesStr = NULL; + watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, hostname, ifIndex); + if (hostEntry != NULL) { + CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { + const char *ip = iter.key; + char *tmp= NULL; + if (ipAddressesStr == NULL) { + tmp = celix_utils_strdup(ip); + } else { + asprintf(&tmp, "%s,%s", ipAddressesStr, ip); + } + if (tmp == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); + return CELIX_ENOMEM; + } + free(ipAddressesStr); + ipAddressesStr = tmp; + } + } + if (ipAddressesStr == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get ip address list."); + return CELIX_ILLEGAL_STATE; + } + *ipAddressesStrOut = celix_steal_ptr(ipAddressesStr); + return CELIX_SUCCESS; +} + static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zeroconf_watcher_t *watcher, watched_service_entry_t *svcEntry, watched_endpoint_entry_t **epOut) { celix_autoptr(celix_properties_t) properties = celix_properties_copy(svcEntry->txtRecord); if (properties == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to copy endpoint properties."); return CELIX_ENOMEM; } celix_autoptr(endpoint_description_t) ep = NULL; @@ -730,7 +878,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_autofree watched_endpoint_entry_t *epEntry = (watched_endpoint_entry_t *)calloc(1, sizeof(*epEntry)); if (epEntry == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher:Failed to alloc endpoint entry."); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc endpoint entry."); return CELIX_ENOMEM; } epEntry->endpoint = ep; @@ -739,7 +887,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero epEntry->ipAddressesStr = NULL; epEntry->hostname = NULL; - if (svcEntry->hostname == NULL) {//if no need to resolve host info, then return + if (svcEntry->hostname == NULL) {//if no need to resolve host info, then return CELIX_SUCCESS celix_steal_ptr(ep); *epOut = celix_steal_ptr(epEntry); return CELIX_SUCCESS; @@ -751,37 +899,20 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero return CELIX_ENOMEM; } - //fill ip address list property celix_autofree char *ipAddressesStr = NULL; - watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, svcEntry->hostname, svcEntry->ifIndex); - if (hostEntry != NULL) { - CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { - const char *ip = iter.key; - char *tmp= NULL; - if (ipAddressesStr == NULL) { - tmp = celix_utils_strdup(ip); - } else { - asprintf(&tmp, "%s,%s", ipAddressesStr, ip); - } - if (tmp == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); - return CELIX_ENOMEM; - } - free(ipAddressesStr); - ipAddressesStr = tmp; - } - } - if (ipAddressesStr == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get ip address list."); - return CELIX_ILLEGAL_STATE; + status = discoveryZeroConfWatcher_getHostIpAddresses(watcher, hostname, svcEntry->ifIndex, &ipAddressesStr); + if (status != CELIX_SUCCESS) { + return status; } - const char *importedConfigs = celix_properties_get(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importedConfigs = celix_properties_get(ep->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); if (importedConfigs == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: No imported configs."); return CELIX_ILLEGAL_ARGUMENT; } celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); if (importedConfigsCopy == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup imported configs."); return CELIX_ENOMEM; } char *savePtr = NULL; @@ -793,7 +924,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); return CELIX_ILLEGAL_ARGUMENT; } - status = celix_properties_setLong(properties, key, svcEntry->port); + status = celix_properties_setLong(ep->properties, key, svcEntry->port); if (status != CELIX_SUCCESS) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config port."); return status; @@ -802,12 +933,14 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); return CELIX_ILLEGAL_ARGUMENT; } - status = celix_properties_set(properties, key, ipAddressesStr); + status = celix_properties_set(ep->properties, key, ipAddressesStr); if (status != CELIX_SUCCESS) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); return status; } - epEntry->ipAddressesStr = celix_properties_get(properties, key, ""); + epEntry->ipAddressesStr = celix_properties_get(ep->properties, key, ""); + + token = strtok_r(NULL, ",", &savePtr); } celix_steal_ptr(hostname); @@ -840,6 +973,29 @@ static void discoveryZeroConfWatcher_informEPLs(discovery_zeroconf_watcher_t *wa return; } +static void discoveryZeroconfWatcher_filterSameFrameWorkServices(discovery_zeroconf_watcher_t *watcher) { + celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedServices); + while (!celix_stringHashMapIterator_isEnd(&iter)) { + watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; + if (svcEntry->resolved) { + const char *epFwUuid = celix_properties_get(svcEntry->txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); + if (epFwUuid != NULL && strcmp(epFwUuid, watcher->fwUuid) == 0) { + celix_logHelper_debug(watcher->logHelper, "Watcher: Ignore self endpoint for %s.", celix_properties_get(svcEntry->txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, "unknown")); + celix_stringHashMapIterator_remove(&iter); + if (svcEntry->resolveRef) { + DNSServiceRefDeallocate(svcEntry->resolveRef); + } + celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry->hostname); + free(svcEntry); + continue; + } + } + celix_stringHashMapIterator_next(&iter); + } + return; +} + static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_zeroconf_watcher_t *watcher, watched_endpoint_entry_t *endpointEntry) { if (endpointEntry->hostname == NULL) { return false; @@ -852,22 +1008,25 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z return false; } if (endpointEntry->ipAddressesStr != NULL) { - celix_autofree char *ipAddresses = celix_utils_strdup(endpointEntry->ipAddressesStr); - if (ipAddresses != NULL) { - char *savePtr = NULL; - char *token = strtok_r(ipAddresses, ",", &savePtr); - int ipCnt = 0; - while (token != NULL) { - ipCnt ++; - char *ip = celix_utils_trimInPlace(token); + const char *p = endpointEntry->ipAddressesStr; + const char *end = p + strlen(p); + char ip[INET6_ADDRSTRLEN] = {0}; + int i = 0; + int ipCnt = 0; + while (p <= end && i < INET6_ADDRSTRLEN){ + ip[i++] = *p; + if (*p == ',' || *p == '\0') { + ip[i] = '\0'; if (!celix_stringHashMap_hasKey(hostEntry->ipAddresses, ip)) { return true; } - token = strtok_r(NULL, ",", &savePtr); - } - if (ipCnt != celix_stringHashMap_size(hostEntry->ipAddresses)) { - return true; + i = 0; + ipCnt ++; } + p++; + } + if (ipCnt != celix_stringHashMap_size(hostEntry->ipAddresses)) { + return true; } } return false; @@ -878,28 +1037,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher watched_service_entry_t *svcEntry = NULL; unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; - //remove self endpoints - celix_string_hash_map_iterator_t svcIter = celix_stringHashMap_begin(watcher->watchedServices); - while (!celix_stringHashMapIterator_isEnd(&svcIter)) { - svcEntry = (watched_service_entry_t *)svcIter.value.ptrValue; - if (svcEntry->resolved) { - const char *epFwUuid = celix_properties_get(svcEntry->txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); - if (epFwUuid != NULL && strcmp(epFwUuid, watcher->fwUuid) == 0) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Ignore self endpoint for %s.", celix_properties_get(svcEntry->txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, "unknown")); - celix_stringHashMapIterator_remove(&svcIter); - if (svcEntry->resolveRef) { - DNSServiceRefDeallocate(svcEntry->resolveRef); - } - celix_properties_destroy(svcEntry->txtRecord); - free(svcEntry->hostname); - free(svcEntry); - continue; - } - } - celix_stringHashMapIterator_next(&svcIter); - } - - celixThreadMutex_lock(&watcher->mutex); + celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&watcher->mutex); //remove the endpoint which ip address list changed, and mark expired time of the endpoint. celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); @@ -907,7 +1045,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry)) { celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); - celix_stringHashMap_remove(watcher->watchedEndpoints, epEntry->endpoint->id); + celix_stringHashMapIterator_remove(&epIter); discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); endpointEntry_destroy(epEntry); } else { @@ -922,23 +1060,30 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher //add new endpoint CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { svcEntry = (watched_service_entry_t *)iter.value.ptrValue; - if (svcEntry->endpointId != NULL && svcEntry->resolved && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex)) { + if (svcEntry->endpointId != NULL && svcEntry->resolved) { epEntry = (watched_endpoint_entry_t *)celix_stringHashMap_get(watcher->watchedEndpoints, svcEntry->endpointId); - if (epEntry == NULL) { + if (epEntry == NULL && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex, &nextWorkIntervalTime)) { celix_status_t status = discoveryZeroConfWatcher_createEndpointEntryForService(watcher, svcEntry, &epEntry); - if (status != CELIX_SUCCESS && status != CELIX_ENOMEM) { + if (status != CELIX_SUCCESS) { // If properties invalid,endpointDescription_create will return error. - // Avoid endpointDescription_create again, set svcEntry->resolved false. - svcEntry->resolved = false; + // Avoid create endpointDescription again, set svcEntry->resolved false. + if (status != CELIX_ENOMEM) { + svcEntry->resolved = false; + } else { + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds + } continue; } celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); if (celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry) == CELIX_SUCCESS) { discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, true); } else { + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to add endpoint for %s.", epEntry->endpoint->serviceName); endpointEntry_destroy(epEntry); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds } - } else { + } else if (epEntry != NULL) { epEntry->expiredTime.tv_sec = INT_MAX; epEntry->expiredTime.tv_nsec = 0; } @@ -964,8 +1109,6 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher } } - celixThreadMutex_unlock(&watcher->mutex); - *pNextWorkIntervalTime = nextWorkIntervalTime; return; } @@ -1039,17 +1182,25 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { struct timeval *timeout = NULL; unsigned int timeoutInS = UINT_MAX; bool running = watcher->running; + + celix_autoptr(celix_string_hash_map_t) updatedBrowsers = celix_stringHashMap_create(); + if (updatedBrowsers == NULL) { + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create updated service browsers cache."); + return NULL; + } + while (running) { if (watcher->sharedRef == NULL) { dnsErr = DNSServiceCreateConnection(&watcher->sharedRef); if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create connection for DNS service, %d.", dnsErr); timeoutInS = MIN(DZC_MAX_RETRY_INTERVAL, timeoutInS);//retry after 5 seconds + } else { + timeoutInS = 0;//need to browse service immediately when connection created } } - discoveryZeroconfWatcher_browseServices(watcher, &timeoutInS); - FD_ZERO(&readfds); FD_SET(watcher->eventFd, &readfds); maxFd = watcher->eventFd; @@ -1074,7 +1225,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { if (result > 0) { if (FD_ISSET(watcher->eventFd, &readfds)) { eventfd_read(watcher->eventFd, &val); - //do nothing, the thread will be exited + //the thread will be exited or browse service } if (dsFd >= 0 && FD_ISSET(dsFd, &readfds)) { @@ -1086,7 +1237,13 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { } timeoutInS = UINT_MAX; + discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(watcher, updatedBrowsers, &timeoutInS); + if (celix_stringHashMap_size(updatedBrowsers) > 0) { + discoveryZeroconfWatcher_browseServices(watcher, updatedBrowsers, &timeoutInS); + celix_stringHashMap_clear(updatedBrowsers); + } discoveryZeroconfWatcher_resolveServices(watcher, &timeoutInS); + discoveryZeroconfWatcher_filterSameFrameWorkServices(watcher); discoveryZeroconfWatcher_refreshHostsInfo(watcher, &timeoutInS); discoveryZeroconfWatcher_refreshEndpoints(watcher, &timeoutInS); diff --git a/libs/error_injector/mdnsresponder/CMakeLists.txt b/libs/error_injector/mdnsresponder/CMakeLists.txt index 4360e5cae..91777945c 100644 --- a/libs/error_injector/mdnsresponder/CMakeLists.txt +++ b/libs/error_injector/mdnsresponder/CMakeLists.txt @@ -22,5 +22,5 @@ find_package(DNSSD) target_include_directories(mdnsresponder_ei PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) target_link_libraries(mdnsresponder_ei PUBLIC Celix::error_injector DNSSD::DNSSD) -target_link_options(mdnsresponder_ei INTERFACE LINKER:--wrap,DNSServiceCreateConnection LINKER:--wrap,DNSServiceProcessResult LINKER:--wrap,DNSServiceRegister LINKER:--wrap,TXTRecordSetValue LINKER:--wrap,DNSServiceBrowse) +target_link_options(mdnsresponder_ei INTERFACE LINKER:--wrap,DNSServiceCreateConnection LINKER:--wrap,DNSServiceProcessResult LINKER:--wrap,DNSServiceRegister LINKER:--wrap,TXTRecordSetValue LINKER:--wrap,DNSServiceBrowse LINKER:--wrap,DNSServiceResolve LINKER:--wrap,DNSServiceGetAddrInfo) add_library(Celix::mdnsresponder_ei ALIAS mdnsresponder_ei) diff --git a/libs/error_injector/mdnsresponder/include/mdnsresponder_ei.h b/libs/error_injector/mdnsresponder/include/mdnsresponder_ei.h index 30a542519..e072fde55 100644 --- a/libs/error_injector/mdnsresponder/include/mdnsresponder_ei.h +++ b/libs/error_injector/mdnsresponder/include/mdnsresponder_ei.h @@ -30,6 +30,8 @@ CELIX_EI_DECLARE(DNSServiceProcessResult, DNSServiceErrorType); CELIX_EI_DECLARE(DNSServiceRegister, DNSServiceErrorType); CELIX_EI_DECLARE(TXTRecordSetValue, DNSServiceErrorType); CELIX_EI_DECLARE(DNSServiceBrowse, DNSServiceErrorType); +CELIX_EI_DECLARE(DNSServiceResolve, DNSServiceErrorType); +CELIX_EI_DECLARE(DNSServiceGetAddrInfo, DNSServiceErrorType); #ifdef __cplusplus } diff --git a/libs/error_injector/mdnsresponder/src/mdnsresponder_ei.cc b/libs/error_injector/mdnsresponder/src/mdnsresponder_ei.cc index abdda5c5f..d542edca2 100644 --- a/libs/error_injector/mdnsresponder/src/mdnsresponder_ei.cc +++ b/libs/error_injector/mdnsresponder/src/mdnsresponder_ei.cc @@ -55,4 +55,20 @@ DNSServiceErrorType __wrap_DNSServiceBrowse(DNSServiceRef *__sdRef, DNSServiceFl CELIX_EI_IMPL(DNSServiceBrowse); return __real_DNSServiceBrowse(__sdRef, __flags, __interfaceIndex, __regtype, __domain, __callBack, __context); } + +DNSServiceErrorType __real_DNSServiceResolve(DNSServiceRef *sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char *name,const char *regtype,const char *domain,DNSServiceResolveReply callBack,void *context); +CELIX_EI_DEFINE(DNSServiceResolve, DNSServiceErrorType) +DNSServiceErrorType __wrap_DNSServiceResolve(DNSServiceRef *sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,const char *name,const char *regtype,const char *domain,DNSServiceResolveReply callBack,void *context) { + CELIX_EI_IMPL(DNSServiceResolve); + return __real_DNSServiceResolve(sdRef, flags, interfaceIndex, name, regtype, domain, callBack, context); +} + +DNSServiceErrorType __real_DNSServiceGetAddrInfo(DNSServiceRef *sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceProtocol protocol,const char *hostname,DNSServiceGetAddrInfoReply callBack,void *context); +CELIX_EI_DEFINE(DNSServiceGetAddrInfo, DNSServiceErrorType) +DNSServiceErrorType __wrap_DNSServiceGetAddrInfo(DNSServiceRef *sdRef,DNSServiceFlags flags,uint32_t interfaceIndex,DNSServiceProtocol protocol,const char *hostname,DNSServiceGetAddrInfoReply callBack,void *context) { + CELIX_EI_IMPL(DNSServiceGetAddrInfo); + return __real_DNSServiceGetAddrInfo(sdRef, flags, interfaceIndex, protocol, hostname, callBack, context); +} + + } \ No newline at end of file diff --git a/libs/utils/error_injector/celix_string_hash_map/include/celix_string_hash_map_ei.h b/libs/utils/error_injector/celix_string_hash_map/include/celix_string_hash_map_ei.h index ca45ff5bd..e0b3280b7 100644 --- a/libs/utils/error_injector/celix_string_hash_map/include/celix_string_hash_map_ei.h +++ b/libs/utils/error_injector/celix_string_hash_map/include/celix_string_hash_map_ei.h @@ -17,8 +17,8 @@ * under the License. */ -#ifndef CELIX_CELIX_LONG_HASH_MAP_EI_H -#define CELIX_CELIX_LONG_HASH_MAP_EI_H +#ifndef CELIX_CELIX_STRING_HASH_MAP_EI_H +#define CELIX_CELIX_STRING_HASH_MAP_EI_H #ifdef __cplusplus extern "C" { #endif @@ -41,4 +41,4 @@ CELIX_EI_DECLARE(celix_stringHashMap_putBool, celix_status_t); } #endif -#endif //CELIX_CELIX_LONG_HASH_MAP_EI_H +#endif //CELIX_CELIX_STRING_HASH_MAP_EI_H diff --git a/libs/utils/error_injector/celix_string_hash_map/src/celix_string_hash_map_ei.cc b/libs/utils/error_injector/celix_string_hash_map/src/celix_string_hash_map_ei.cc index b63417feb..3647dabc1 100644 --- a/libs/utils/error_injector/celix_string_hash_map/src/celix_string_hash_map_ei.cc +++ b/libs/utils/error_injector/celix_string_hash_map/src/celix_string_hash_map_ei.cc @@ -55,4 +55,11 @@ celix_status_t __wrap_celix_stringHashMap_putDouble(celix_string_hash_map_t* map return __real_celix_stringHashMap_putDouble(map, key, value); } +celix_status_t __real_celix_stringHashMap_putBool(celix_string_hash_map_t* map, long key, bool value); +CELIX_EI_DEFINE(celix_stringHashMap_putBool, celix_status_t) +celix_status_t __wrap_celix_stringHashMap_putBool(celix_string_hash_map_t* map, long key, bool value) { + CELIX_EI_IMPL(celix_stringHashMap_putBool); + return __real_celix_stringHashMap_putBool(map, key, value); +} + } \ No newline at end of file From f6cfb5ec7ae994f9449d91b532a3801cf4005030 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Wed, 20 Dec 2023 10:03:09 +0800 Subject: [PATCH 12/29] Refresh remote service endpoint when RSA is removed --- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 18 +- .../src/discovery_zeroconf_watcher.c | 204 ++++++++++++------ 2 files changed, 155 insertions(+), 67 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 879e9ebc9..8f14d7790 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -169,7 +169,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { void TestRsaServiceAddAndRemove(void (*beforeAddRsaAction)(void), void (*afterAddRsaAction)(void), void (*beforeRemoveRsaAction)(void) = nullptr, void (*afterRemoveRsaAction)(void) = nullptr, const char *remoteConfigsSupported = DZC_TEST_CONFIG_TYPE) { - celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service id + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service rsaSvcId = -1; discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); @@ -428,6 +428,20 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForBrowserEntry) { }); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCreateServiceMapForBrowserEntry) { + celix_ei_expect_DNSServiceCreateConnection(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); + ExpectMsgOutPut("Watcher: Failed to create connection for DNS service, %d.");//it is used for sync work thread + TestRsaServiceAddAndRemove([](){ + auto timeOut = CheckMsgWithTimeOutInS(1);//wait for work thread run + EXPECT_FALSE(timeOut); + celix_ei_expect_celix_stringHashMap_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + ExpectMsgOutPut("Watcher: Failed to create watched services map."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(1); + EXPECT_FALSE(timeOut); + }); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutBrowserEntryToCache) { TestRsaServiceAddAndRemove([](){ celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); @@ -690,6 +704,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceBrowseFailedOnce) { } TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed1) { + celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service + rsaSvcId = -1; discovery_zeroconf_watcher_t *watcher; celix_ei_expect_celix_stringHashMap_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index a4515f587..f26e4477f 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -52,6 +52,8 @@ #define DZC_MAX_HOSTNAME_LEN 255 //The fully qualified domain name of the host, eg: "MyComputer.local". RFC 1034 specifies that this name is limited to 255 bytes. +#define DZC_MAX_SERVICE_INSTANCE_NAME_LEN 64 //The instanceName must be 1-63 bytes, + 1 for '\0' + struct discovery_zeroconf_watcher { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; @@ -61,8 +63,8 @@ struct discovery_zeroconf_watcher { DNSServiceRef sharedRef; int eventFd; celix_thread_t watchEPThread; - celix_string_hash_map_t *watchedServices;//key:instanceName+interfaceId, val:watched_service_entry_t* - celix_string_hash_map_t *watchedHosts;//key:hostname+interfaceId, val:watched_host_entry_t* + celix_string_hash_map_t *watchedServices;//key:instanceName+interfaceIndex, val:watched_service_entry_t* + celix_string_hash_map_t *watchedHosts;//key:hostname+interfaceIndex, val:watched_host_entry_t* celix_thread_mutex_t mutex;//projects below bool running; celix_string_hash_map_t *watchedEndpoints;//key:endpoint id, val:watched_endpoint_entry_t* @@ -83,13 +85,14 @@ typedef struct watched_service_entry { celix_properties_t *txtRecord; const char *endpointId; int ifIndex; - char instanceName[64];//The instanceName must be 1-63 bytes + char instanceName[DZC_MAX_SERVICE_INSTANCE_NAME_LEN]; char *hostname; int port; bool resolved; int resolvedCnt; DNSServiceRef resolveRef; bool reResolve; + bool markDeleted; }watched_service_entry_t; typedef struct watched_epl_entry { @@ -99,9 +102,11 @@ typedef struct watched_epl_entry { typedef struct service_browser_entry { DNSServiceRef browseRef; + celix_log_helper_t *logHelper; + celix_string_hash_map_t *watchedServices;//key:instanceName+'/'+interfaceIndex, val:interfaceIndex int refCnt; int resolvedCnt; - bool toBeDeleted; + bool markDeleted; }service_browser_entry_t; typedef struct watched_host_entry { @@ -251,7 +256,9 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { assert(celix_stringHashMap_size(watcher->watchedEndpoints) == 0); celix_stringHashMap_destroy(watcher->watchedEndpoints); CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter) { - free(iter.value.ptrValue); + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; + celix_stringHashMap_destroy(browserEntry->watchedServices); + free(browserEntry); } celix_stringHashMap_destroy(watcher->serviceBrowsers); celixThreadMutex_destroy(&watcher->mutex); @@ -356,16 +363,25 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix if (browserEntry == NULL) { browserEntry = (service_browser_entry_t *)calloc(1, sizeof(*browserEntry)); if (browserEntry != NULL) { - browserEntry->refCnt = 1; - browserEntry->resolvedCnt = 0; - browserEntry->browseRef = NULL; - browserEntry->toBeDeleted = false; - if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) == CELIX_SUCCESS) { - refreshBrowsers = true; + browserEntry->watchedServices = celix_stringHashMap_create(); + if (browserEntry->watchedServices != NULL) { + browserEntry->refCnt = 1; + browserEntry->resolvedCnt = 0; + browserEntry->browseRef = NULL; + browserEntry->logHelper = watcher->logHelper; + browserEntry->markDeleted = false; + if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) == CELIX_SUCCESS) { + refreshBrowsers = true; + } else { + celix_stringHashMap_destroy(browserEntry->watchedServices); + free(browserEntry); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service browser entry."); + } } else { free(browserEntry); celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service browser entry."); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create watched services map."); } } else { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service browser entry."); @@ -410,7 +426,13 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce celixThreadMutex_lock(&watcher->mutex); service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); if ((browserEntry != NULL) && (--browserEntry->refCnt == 0)) { + if (browserEntry->browseRef == NULL) {//if browser is not browsing, remove it directly, otherwise, let the watchEPThread remove it + celix_stringHashMap_remove(watcher->serviceBrowsers, svcSubType); + celix_stringHashMap_destroy(browserEntry->watchedServices); + free(browserEntry); + } else { refreshBrowsers = true; + } } celixThreadMutex_unlock(&watcher->mutex); token = strtok(NULL, ","); @@ -484,67 +506,30 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, (void)sdRef;//unused (void)regtype;//unused (void)replyDomain;//unused - discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)context; - assert(watcher != NULL); + service_browser_entry_t *browser = (service_browser_entry_t *)context; + assert(browser != NULL); if (errorCode != kDNSServiceErr_NoError) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse service, %d.", errorCode); + celix_logHelper_error(browser->logHelper, "Watcher: Failed to browse service, %d.", errorCode); return; } - watched_service_entry_t *svcEntry = NULL; - if (instanceName == NULL || strlen(instanceName) >= sizeof(svcEntry->instanceName)) { - celix_logHelper_error(watcher->logHelper, "Watcher: service name err."); + if (instanceName == NULL || strlen(instanceName) >= DZC_MAX_SERVICE_INSTANCE_NAME_LEN) { + celix_logHelper_error(browser->logHelper, "Watcher: service name err."); return; } - celix_logHelper_info(watcher->logHelper, "Watcher: %s %s on interface %d.", (flags & kDNSServiceFlagsAdd) ? "Add" : "Remove", instanceName, interfaceIndex); + celix_logHelper_info(browser->logHelper, "Watcher: %s %s on interface %d.", (flags & kDNSServiceFlagsAdd) ? "Add" : "Remove", instanceName, interfaceIndex); char key[128]={0}; - (void)snprintf(key, sizeof(key), "%s%d", instanceName, (int)interfaceIndex); + (void)snprintf(key, sizeof(key), "%s/%d", instanceName, (int)interfaceIndex); if (flags & kDNSServiceFlagsAdd) { - if (celix_stringHashMap_hasKey(watcher->watchedServices, key)) { - celix_logHelper_debug(watcher->logHelper,"Watcher: %s already on interface %d.", instanceName, interfaceIndex); - return; - } - svcEntry = (watched_service_entry_t *)calloc(1, sizeof(*svcEntry)); - if (svcEntry == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service entry."); - return; - } - svcEntry->resolveRef = NULL; - svcEntry->txtRecord = celix_properties_create(); - if (svcEntry->txtRecord == NULL) { - free(svcEntry); - celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create txt record for service entry."); - return; - } - svcEntry->endpointId = NULL; - svcEntry->resolved = false; - strcpy(svcEntry->instanceName, instanceName); - svcEntry->hostname = NULL; - svcEntry->ifIndex = (int)interfaceIndex; - svcEntry->resolvedCnt = 0; - svcEntry->reResolve = false; - svcEntry->logHelper = watcher->logHelper; - int status = celix_stringHashMap_put(watcher->watchedServices, key, svcEntry); + int status = celix_stringHashMap_putLong(browser->watchedServices, key, interfaceIndex); if (status != CELIX_SUCCESS) { - celix_properties_destroy(svcEntry->txtRecord); - free(svcEntry); - celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service entry, %d.", status); + celix_logHelper_logTssErrors(browser->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(browser->logHelper, "Watcher: Failed to cache service instance name, %d.", status); } } else { - svcEntry = (watched_service_entry_t *)celix_stringHashMap_get(watcher->watchedServices, key); - if (svcEntry) { - celix_stringHashMap_remove(watcher->watchedServices, key); - if (svcEntry->resolveRef) { - DNSServiceRefDeallocate(svcEntry->resolveRef); - } - celix_properties_destroy(svcEntry->txtRecord); - free(svcEntry->hostname); - free(svcEntry); - } + celix_stringHashMap_remove(browser->watchedServices, key); } return; } @@ -554,7 +539,6 @@ static void discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(discovery_zeroco unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; celixThreadMutex_lock(&watcher->mutex); - celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->serviceBrowsers); while (!celix_stringHashMapIterator_isEnd(&iter)) { service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; @@ -569,7 +553,7 @@ static void discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(discovery_zeroco status = celix_stringHashMap_put(updatedServiceBrowsers, iter.key, browserEntry); if (status == CELIX_SUCCESS) { celix_stringHashMapIterator_remove(&iter); - browserEntry->toBeDeleted = true; + browserEntry->markDeleted = true; continue; } else { nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds @@ -579,18 +563,18 @@ static void discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(discovery_zeroco } celix_stringHashMapIterator_next(&iter); } - celixThreadMutex_unlock(&watcher->mutex); //release to be deleted service browsers celix_string_hash_map_iterator_t iter2 = celix_stringHashMap_begin(updatedServiceBrowsers); while (!celix_stringHashMapIterator_isEnd(&iter2)) { service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter2.value.ptrValue; - if (browserEntry->toBeDeleted) { + if (browserEntry->markDeleted) { celix_stringHashMapIterator_remove(&iter2); if (browserEntry->browseRef) { DNSServiceRefDeallocate(browserEntry->browseRef); } + celix_stringHashMap_destroy(browserEntry->watchedServices); free(browserEntry); } else { celix_stringHashMapIterator_next(&iter2); @@ -609,7 +593,7 @@ static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t browserEntry->browseRef = watcher->sharedRef; char serviceType[128] = {0};//primary type(15bytes) + subtype(63bytes) (void)snprintf(serviceType, sizeof(serviceType), "%s,%s", DZC_SERVICE_PRIMARY_TYPE, iter.key); - DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, watcher); + DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, browserEntry); if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); browserEntry->browseRef = NULL; @@ -624,6 +608,7 @@ static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; if (watcher->sharedRef && svcEntry->resolveRef == NULL && svcEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { @@ -651,6 +636,92 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ return; } +static void discoveryZeroconfWatcher_refreshWatchedServices(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + + //mark deleted status for all watched services + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { + watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; + svcEntry->markDeleted = true; + } + + celixThreadMutex_lock(&watcher->mutex); + CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter) { + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter.value.ptrValue; + CELIX_STRING_HASH_MAP_ITERATE(browserEntry->watchedServices, iter2) { + const char *key = iter2.key; + int interfaceIndex = (int)iter2.value.longValue; + celix_autofree watched_service_entry_t *svcEntry = (watched_service_entry_t *)celix_stringHashMap_get(watcher->watchedServices, key); + if (svcEntry != NULL) { + svcEntry->markDeleted = false; + celix_steal_ptr(svcEntry); + continue; + } + char *instanceNameEnd = strrchr(key, '/'); + if (instanceNameEnd == NULL || instanceNameEnd-key >= DZC_MAX_SERVICE_INSTANCE_NAME_LEN) { + celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service instance key, %s.", key); + continue; + } + svcEntry = (watched_service_entry_t *)calloc(1, sizeof(*svcEntry)); + if (svcEntry == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service entry."); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + continue; + } + svcEntry->resolveRef = NULL; + svcEntry->txtRecord = celix_properties_create(); + if (svcEntry->txtRecord == NULL) { + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create txt record for service entry."); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + continue; + } + svcEntry->endpointId = NULL; + svcEntry->resolved = false; + strncpy(svcEntry->instanceName, key, instanceNameEnd-key); + svcEntry->instanceName[instanceNameEnd-key] = '\0'; + svcEntry->hostname = NULL; + svcEntry->ifIndex = interfaceIndex; + svcEntry->resolvedCnt = 0; + svcEntry->reResolve = false; + svcEntry->markDeleted = false; + svcEntry->logHelper = watcher->logHelper; + int status = celix_stringHashMap_put(watcher->watchedServices, key, svcEntry); + if (status != CELIX_SUCCESS) { + celix_properties_destroy(svcEntry->txtRecord); + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service entry, %d.", status); + nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry browse after 5 seconds + continue; + } + celix_steal_ptr(svcEntry); + } + } + celixThreadMutex_unlock(&watcher->mutex); + + //remove to be deleted services + celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedServices); + while (!celix_stringHashMapIterator_isEnd(&iter)) { + watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; + if (svcEntry->markDeleted) { + celix_stringHashMapIterator_remove(&iter); + if (svcEntry->resolveRef) { + DNSServiceRefDeallocate(svcEntry->resolveRef); + } + celix_properties_destroy(svcEntry->txtRecord); + free(svcEntry->hostname); + free(svcEntry); + } else { + celix_stringHashMapIterator_next(&iter); + } + } + + discoveryZeroconfWatcher_resolveServices(watcher, &nextWorkIntervalTime); + + *pNextWorkIntervalTime = nextWorkIntervalTime; + return; +} + static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context) { (void)sdRef;//unused @@ -1136,6 +1207,7 @@ static void discoveryZeroconfWatcher_closeMDNSConnection(discovery_zeroconf_watc service_browser_entry_t *browseEntry = (service_browser_entry_t *)iter.value.ptrValue; browseEntry->browseRef = NULL;//no need free V->browseRef, 'DNSServiceRefDeallocate(watcher->sharedRef)' has done it. browseEntry->resolvedCnt = 0; + celix_stringHashMap_clear(browseEntry->watchedServices); } celixThreadMutex_unlock(&watcher->mutex); @@ -1242,7 +1314,7 @@ static void *discoveryZeroconfWatcher_watchEPThread(void *data) { discoveryZeroconfWatcher_browseServices(watcher, updatedBrowsers, &timeoutInS); celix_stringHashMap_clear(updatedBrowsers); } - discoveryZeroconfWatcher_resolveServices(watcher, &timeoutInS); + discoveryZeroconfWatcher_refreshWatchedServices(watcher, &timeoutInS); discoveryZeroconfWatcher_filterSameFrameWorkServices(watcher); discoveryZeroconfWatcher_refreshHostsInfo(watcher, &timeoutInS); discoveryZeroconfWatcher_refreshEndpoints(watcher, &timeoutInS); From 9266360ab5f5f92418d22245be89f8d66897bb2e Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Wed, 20 Dec 2023 10:39:53 +0800 Subject: [PATCH 13/29] Add remote.configs.supported property for RSA service,and add celix.remote.admin.shm.rpc_type property for RSA_SHM configuration type --- .../gtest/src/RsaShmActivatorUnitTestSuite.cc | 29 +++++++++++- .../RsaShmExportRegistrationUnitTestSuite.cc | 46 ++++--------------- .../gtest/src/RsaShmImplUnitTestSuite.cc | 8 ++-- .../RsaShmImportRegistrationUnitTestSuite.cc | 43 ++++------------- .../rsa_shm/src/rsa_shm_activator.c | 12 ++++- .../rsa_shm/src/rsa_shm_constants.h | 24 ++++++---- .../rsa_shm/src/rsa_shm_export_registration.c | 29 +++--------- .../rsa_shm/src/rsa_shm_impl.c | 46 ++----------------- .../rsa_shm/src/rsa_shm_import_registration.c | 29 +++--------- .../celix_properties/CMakeLists.txt | 1 + .../include/celix_properties_ei.h | 1 + .../src/celix_properties_ei.cc | 7 +++ 12 files changed, 103 insertions(+), 172 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc index ac2528376..4ae275c6e 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc @@ -21,8 +21,9 @@ #include "remote_service_admin.h" #include "celix_api.h" #include "celix_log_helper_ei.h" -#include "malloc_ei.h" +#include "celix_properties_ei.h" #include "celix_bundle_context_ei.h" +#include "malloc_ei.h" #include class RsaShmActivatorUnitTestSuite : public ::testing::Test { @@ -41,6 +42,8 @@ class RsaShmActivatorUnitTestSuite : public ::testing::Test { celix_ei_expect_celix_logHelper_create(nullptr, 0, nullptr); celix_ei_expect_calloc(nullptr, 0, nullptr); celix_ei_expect_celix_bundleContext_registerServiceAsync(nullptr, 0, 0); + celix_ei_expect_celix_properties_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_set(nullptr, 0, 0); } @@ -90,6 +93,30 @@ TEST_F(RsaShmActivatorUnitTestSuite, RsaShmActivatorStartWithCreatingRsaError) { EXPECT_EQ(status, CELIX_SUCCESS); } +TEST_F(RsaShmActivatorUnitTestSuite, RsaShmActivatorStartWithCreatingServicePropertiesError) { + void *userData = nullptr; + auto status = celix_bundleActivator_create(ctx.get(), &userData); + EXPECT_EQ(status, CELIX_SUCCESS); + celix_ei_expect_celix_properties_create((void*)&celix_bundleActivator_start, 1, nullptr); + status = celix_bundleActivator_start(userData, ctx.get()); + EXPECT_EQ(status, CELIX_ENOMEM); + + status = celix_bundleActivator_destroy(userData, ctx.get()); + EXPECT_EQ(status, CELIX_SUCCESS); +} + +TEST_F(RsaShmActivatorUnitTestSuite, RsaShmActivatorStartWithSettingServicePropertiesError) { + void *userData = nullptr; + auto status = celix_bundleActivator_create(ctx.get(), &userData); + EXPECT_EQ(status, CELIX_SUCCESS); + celix_ei_expect_celix_properties_set((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM); + status = celix_bundleActivator_start(userData, ctx.get()); + EXPECT_EQ(status, CELIX_ENOMEM); + + status = celix_bundleActivator_destroy(userData, ctx.get()); + EXPECT_EQ(status, CELIX_SUCCESS); +} + TEST_F(RsaShmActivatorUnitTestSuite, RsaShmActivatorStartWithRegisteringRsaServiceError) { void *userData = nullptr; auto status = celix_bundleActivator_create(ctx.get(), &userData); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc index a85691905..8992bda43 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc @@ -36,6 +36,8 @@ #include #include +#define RSA_RPC_TYPE_FOR_TEST "celix.remote.admin.rpc_type.test" + static celix_status_t expect_RpcFacCreateEndpoint_ret = CELIX_SUCCESS; static celix_status_t RpcFacCreateEndpoint(void *handle, const endpoint_description_t *endpoint, long *requestHandlerSvcId) { (void)endpoint; //unused @@ -91,7 +93,8 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE"," RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); calcSvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); EXPECT_GE(calcSvcId, 0); @@ -103,7 +106,7 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { rpcFactory.destroyEndpoint = RpcFacDestroyEndpoint; celix_properties_t *rpcFacProps = celix_properties_create(); - celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, RSA_RPC_FACTORY_NAME, rpcFacProps); EXPECT_GE(rpcFactorySvcId, 1); @@ -128,7 +131,8 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE"," RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); celix_properties_setLong(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, calcSvcId); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); @@ -204,39 +208,7 @@ TEST_F(RsaShmExportRegUnitTestSuite, CreateExportRegistrationWithOutRpcType) { endpoint_description_t *endpoint = CreateEndpointDescription(); service_reference_pt reference = GetServiceReference(); - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); - - export_registration_t *exportRegistration = nullptr; - auto status = exportRegistration_create(ctx.get(), logHelper.get(), reference, endpoint, &exportRegistration); - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - bundleContext_ungetServiceReference(ctx.get(), reference); - endpointDescription_destroy(endpoint); -} - -TEST_F(RsaShmExportRegUnitTestSuite, CreateExportRegistrationWithOverlongRpcTypeString) { - endpoint_description_t *endpoint = CreateEndpointDescription(); - service_reference_pt reference = GetServiceReference(); - - char overlongRpcType[128] = RSA_RPC_TYPE_PREFIX; - for (int i = strlen(RSA_RPC_TYPE_PREFIX); i < 127; ++i) { - overlongRpcType[i] = 'a'; - } - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, overlongRpcType); - - export_registration_t *exportRegistration = nullptr; - auto status = exportRegistration_create(ctx.get(), logHelper.get(), reference, endpoint, &exportRegistration); - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - bundleContext_ungetServiceReference(ctx.get(), reference); - endpointDescription_destroy(endpoint); -} - -TEST_F(RsaShmExportRegUnitTestSuite, CreateExportRegistrationWithOutConfigType) { - endpoint_description_t *endpoint = CreateEndpointDescription(); - service_reference_pt reference = GetServiceReference(); - - celix_properties_unset(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + celix_properties_unset(endpoint->properties, RSA_SHM_RPC_TYPE_KEY); export_registration_t *exportRegistration = nullptr; auto status = exportRegistration_create(ctx.get(), logHelper.get(), reference, endpoint, &exportRegistration); @@ -329,7 +301,7 @@ TEST_F(RsaShmExportRegUnitTestSuite, RegisterMoreThanOneRpcFactory) { //register another rpc factory celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", RSA_RPC_FACTORY_NAME, props); EXPECT_GE(svcId, 1); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc index 0b41f6e59..fd92e6d36 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc @@ -83,7 +83,8 @@ class RsaShmUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE "," RSA_SHM_RPC_TYPE_DEFAULT); + celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); calcSvcId = celix_bundleContext_registerService(ctx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); }; @@ -96,7 +97,8 @@ class RsaShmUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE "," RSA_SHM_RPC_TYPE_DEFAULT); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "1234"); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); @@ -615,7 +617,7 @@ TEST_F(RsaShmUnitTestSuite, EndpointLostRpcType) { endpoint_description_t *endpoint = CreateEndpointDescription(); EXPECT_NE(nullptr, endpoint); - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_unset(endpoint->properties, RSA_SHM_RPC_TYPE_KEY); status = rsaShm_importService(admin, endpoint, ®s); EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc index 93d8a7440..10e83d352 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc @@ -33,6 +33,8 @@ #include "celix_errno.h" #include +#define RSA_RPC_TYPE_FOR_TEST "celix.remote.admin.rpc_type.test" + static celix_status_t expect_RpcFacCreateProxy_ret = CELIX_SUCCESS; static celix_status_t RpcFacCreateProxy(void *handle, const endpoint_description_t *endpointDesc, long requestSenderSvcId, long *proxySvcId) { (void)endpointDesc;//unused @@ -51,7 +53,8 @@ static celix_status_t RpcFacCreateProxy(void *handle, const endpoint_description celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE"," RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); auto calcSvcId = celix_bundleContext_registerServiceAsync(ctx, &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); EXPECT_GE(calcSvcId, 0); *proxySvcId = calcSvcId; @@ -85,7 +88,7 @@ class RsaShmImportRegUnitTestSuite : public ::testing::Test { rpcFactory.destroyEndpoint = nullptr; celix_properties_t *rpcFacProps = celix_properties_create(); - celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, RSA_RPC_FACTORY_NAME, rpcFacProps); EXPECT_GE(rpcFactorySvcId, 1); @@ -107,7 +110,8 @@ class RsaShmImportRegUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE"," RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); celix_properties_setLong(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, 100);//Set a dummy service id celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); @@ -187,41 +191,12 @@ TEST_F(RsaShmImportRegUnitTestSuite, FailedToCloneEndpointDescription) { endpointDescription_destroy(endpoint); } -TEST_F(RsaShmImportRegUnitTestSuite, CreateImportRegistrationWithInvalidRpcType) { - auto* endpoint = CreateEndpointDescription(); - - import_registration_t *importRegistration = nullptr; - long reqSenderSvcId = 123;//set dummy service id - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "invalid"); - auto status = importRegistration_create(ctx.get(), logHelper.get(), endpoint, reqSenderSvcId, &importRegistration); - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - endpointDescription_destroy(endpoint); -} - TEST_F(RsaShmImportRegUnitTestSuite, CreateImportRegistrationWithoutRpcType) { auto* endpoint = CreateEndpointDescription(); import_registration_t *importRegistration = nullptr; long reqSenderSvcId = 123;//set dummy service id - celix_properties_unset(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); - auto status = importRegistration_create(ctx.get(), logHelper.get(), endpoint, reqSenderSvcId, &importRegistration); - EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); - - endpointDescription_destroy(endpoint); -} - -TEST_F(RsaShmImportRegUnitTestSuite, CreateImportRegistrationWithOverlongRpcTypeString) { - endpoint_description_t *endpoint = CreateEndpointDescription(); - - char overlongRpcType[128] = RSA_RPC_TYPE_PREFIX; - for (int i = strlen(RSA_RPC_TYPE_PREFIX); i < 127; ++i) { - overlongRpcType[i] = 'a'; - } - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, overlongRpcType); - - import_registration_t *importRegistration = nullptr; - long reqSenderSvcId = 123;//set dummy service id + celix_properties_unset(endpoint->properties, RSA_SHM_RPC_TYPE_KEY); auto status = importRegistration_create(ctx.get(), logHelper.get(), endpoint, reqSenderSvcId, &importRegistration); EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, status); @@ -255,7 +230,7 @@ TEST_F(RsaShmImportRegUnitTestSuite, RegisterMoreThanOneRpcFactory) { //register another rpc factory celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_PREFIX"mock"); + celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", RSA_RPC_FACTORY_NAME, props); EXPECT_GE(svcId, 1); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c index c3029ff93..3d9f0f258 100755 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c @@ -19,6 +19,8 @@ #include "rsa_shm_export_registration.h" #include "rsa_shm_import_registration.h" #include "rsa_shm_impl.h" +#include "rsa_shm_constants.h" +#include "remote_constants.h" #include "remote_service_admin.h" #include "celix_log_helper.h" #include "celix_api.h" @@ -47,7 +49,15 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t *activator, celix_bundl if (status != CELIX_SUCCESS) { return status; } + celix_autoptr(celix_properties_t) props = celix_properties_create(); + if (props == NULL) { + return CELIX_ENOMEM; + } + status = celix_properties_set(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_SHM_CONFIGURATION_TYPE); + if (status != CELIX_SUCCESS) { + return status; + } activator->adminService.admin = (void*)admin; activator->adminService.exportService = (void*)rsaShm_exportService; @@ -70,7 +80,7 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t *activator, celix_bundl activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference; activator->adminSvcId = celix_bundleContext_registerServiceAsync(context, &activator->adminService, - OSGI_RSA_REMOTE_SERVICE_ADMIN, NULL); + OSGI_RSA_REMOTE_SERVICE_ADMIN, celix_steal_ptr(props)); if (activator->adminSvcId < 0) { return CELIX_BUNDLE_EXCEPTION; } diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h index 11b5a5523..c46e4647b 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h @@ -24,17 +24,25 @@ extern "C" { #endif - -#define RSA_SHM_CONFIGURATION_TYPE "celix.remote.admin.shm" - -#define RSA_SHM_SERVER_NAME_KEY "rsaShmServerName" +/** + * @brief RSA Configuration type for shared memory + */ +#define RSA_SHM_CONFIGURATION_TYPE "celix.remote.admin.shm" +/** + * @brief The unix domain socket server name, which is used to create an abstract socket. The abstract socket is used to transfer shared memory address information. + */ +#define RSA_SHM_SERVER_NAME_KEY "celix.remote.admin.shm.server_name" +/** + * @brief The serializer type of RSA_SHM_CONFIGURATION_TYPE. The value should associated with RSA_RPC_TYPE_KEY of rsa_rpc_factory_t. + */ +#define RSA_SHM_RPC_TYPE_KEY "celix.remote.admin.shm.rpc_type" /** * @brief A property of RsaShm bundle that indicates the shared memory pool size. - * Its value should be greater than 8192 + * Its value should be greater than 8192, because the memory pool ctrl block(control_t) size is 6536 bytes. * */ -#define RSA_SHM_MEMORY_POOL_SIZE_KEY "rsaShmPoolSize" +#define RSA_SHM_MEMORY_POOL_SIZE_KEY "RSA_SHM_POOL_SIZE" /** * @brief Shared memory pool default size * @@ -45,7 +53,7 @@ extern "C" { * @brief A property of RsaShm bundle that indicates the timeout of remote service invocation. * */ -#define RSA_SHM_MSG_TIMEOUT_KEY "rsaShmMsgTimeout" +#define RSA_SHM_MSG_TIMEOUT_KEY "RSA_SHM_MSG_TIMEOUT" /** * @brief The default timeout of remote service invocation. * @@ -57,7 +65,7 @@ extern "C" { * If there are more concurrent invocations than its value, service invocation will fail. * */ -#define RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY "rsaShmCctIvNum" +#define RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY "RSA_SHM_MAX_CONCURRENT_INVOCATIONS_NUM" /** * @brief The default value of the maximum concurrent invocations, If property RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY does not exist, the default value is used diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c index f44bfaef0..805f602ed 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c @@ -18,6 +18,7 @@ */ #include "rsa_shm_export_registration.h" +#include "rsa_shm_constants.h" #include "rsa_request_handler_service.h" #include "rsa_rpc_factory.h" #include "endpoint_description.h" @@ -108,34 +109,16 @@ celix_status_t exportRegistration_create(celix_bundle_context_t *context, } export->reqHandlerSvcEntry = reqHandlerSvcEntry; - const char *serviceImportedConfigs = celix_properties_get(endpointDesc->properties, - OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); - if (serviceImportedConfigs == NULL) { - celix_logHelper_error(logHelper,"RSA export reg: service.imported.configs property is not exist."); - return CELIX_ILLEGAL_ARGUMENT; - } - char *rsaRpcType = NULL; - celix_autofree char *icCopy = strdup(serviceImportedConfigs); - const char delimiter[2] = ","; - char *token, *savePtr; - token = strtok_r(icCopy, delimiter, &savePtr); - while (token != NULL) { - rsaRpcType = celix_utils_trimInPlace(token); - if (strncmp(rsaRpcType, RSA_RPC_TYPE_PREFIX, sizeof(RSA_RPC_TYPE_PREFIX) - 1) == 0) { - break; - } - rsaRpcType = NULL; - token = strtok_r(NULL, delimiter, &savePtr); - } - if (rsaRpcType == NULL) { - celix_logHelper_error(logHelper,"RSA export reg: %s property is not exist.", RSA_RPC_TYPE_KEY); + const char *rsaShmRpcType = celix_properties_get(endpointDesc->properties, RSA_SHM_RPC_TYPE_KEY, NULL); + if (rsaShmRpcType == NULL) { + celix_logHelper_error(logHelper,"RSA export reg: %s property is not exist.", RSA_SHM_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } char filter[128] = {0}; - int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaRpcType); + int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaShmRpcType); if (bytes >= sizeof(filter)) { - celix_logHelper_error(logHelper,"RSA export reg: The value(%s) of %s is too long.", rsaRpcType, RSA_RPC_TYPE_KEY); + celix_logHelper_error(logHelper,"RSA export reg: The value(%s) of %s is too long.", rsaShmRpcType, RSA_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c index c93ac4955..2e0c760a1 100755 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c @@ -453,34 +453,6 @@ celix_status_t rsaShm_removeExportedService(rsa_shm_t *admin, export_registratio return status; } -static char *rsaShm_getRpcTypeWithDefault(rsa_shm_t *admin CELIX_UNUSED, const char *serviceExportedConfigs, const char *defaultVal) { - char *rpcType = NULL; - if (serviceExportedConfigs != NULL) { - celix_autofree char *ecCopy = celix_utils_strdup(serviceExportedConfigs); - if (ecCopy == NULL) { - return NULL; - } - const char delimiter[2] = ","; - char *token, *savePtr; - - token = strtok_r(ecCopy, delimiter, &savePtr); - while (token != NULL) { - celix_autofree char *tokenTrim = celix_utils_trim(token); - if (tokenTrim != NULL && strncmp(tokenTrim, RSA_RPC_TYPE_PREFIX, sizeof(RSA_RPC_TYPE_PREFIX) - 1) == 0) { - rpcType = celix_steal_ptr(tokenTrim); - break;//TODO Multiple RPC type values may be supported in the future. - } - token = strtok_r(NULL, delimiter, &savePtr); - } - } - //if rpc type is not exist, then set a default value. - if (rpcType == NULL && defaultVal != NULL) { - rpcType = celix_utils_strdup(defaultVal); - } - - return rpcType; -} - static celix_status_t rsaShm_createEndpointDescription(rsa_shm_t *admin, celix_properties_t *exportedProperties, char *interface, endpoint_description_t **description) { celix_status_t status = CELIX_SUCCESS; @@ -512,21 +484,11 @@ static celix_status_t rsaShm_createEndpointDescription(rsa_shm_t *admin, celix_properties_setLong(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId); celix_properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid); celix_properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true"); - - celix_autofree char *rpcType = rsaShm_getRpcTypeWithDefault(admin, celix_properties_get(exportedProperties,OSGI_RSA_SERVICE_EXPORTED_CONFIGS, NULL), - RSA_SHM_RPC_TYPE_DEFAULT); - if (rpcType == NULL) { - celix_logHelper_error(admin->logHelper, "Failed to get rpc type"); - return CELIX_ENOMEM; - } - - char *importedConfigs = NULL; - int bytes = asprintf(&importedConfigs, "%s,%s",RSA_SHM_CONFIGURATION_TYPE, rpcType); - if (bytes < 0) { - celix_logHelper_error(admin->logHelper, "Failed to create imported configs"); - return CELIX_ENOMEM; + celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CONFIGURATION_TYPE); + //If the rpc type of RSA_SHM_CONFIGURATION_TYPE is not set, then set a default value. + if (celix_properties_get(endpointProperties, RSA_SHM_RPC_TYPE_KEY, NULL) == NULL) { + celix_properties_set(endpointProperties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); } - celix_properties_setWithoutCopy(endpointProperties, strdup(OSGI_RSA_SERVICE_IMPORTED_CONFIGS), importedConfigs); celix_properties_set(endpointProperties, (char *) RSA_SHM_SERVER_NAME_KEY, admin->shmServerName); status = endpointDescription_create(endpointProperties, description); if (status != CELIX_SUCCESS) { diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c index 0238b7e20..f0f4bdef4 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c @@ -18,6 +18,7 @@ */ #include "rsa_shm_import_registration.h" +#include "rsa_shm_constants.h" #include "rsa_rpc_factory.h" #include "remote_constants.h" #include "celix_log_helper.h" @@ -63,34 +64,16 @@ celix_status_t importRegistration_create(celix_bundle_context_t *context, import->rpcFac = NULL; import->proxySvcId = -1; - const char *serviceImportedConfigs = celix_properties_get(endpointDesc->properties, - OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); - if (serviceImportedConfigs == NULL) { - celix_logHelper_error(logHelper,"RSA import reg: service.imported.configs property is not exist."); - return CELIX_ILLEGAL_ARGUMENT; - } - char *rsaRpcType = NULL; - celix_autofree char *icCopy = strdup(serviceImportedConfigs); - const char delimiter[2] = ","; - char *token, *savePtr; - token = strtok_r(icCopy, delimiter, &savePtr); - while (token != NULL) { - rsaRpcType = celix_utils_trimInPlace(token); - if (strncmp(rsaRpcType, RSA_RPC_TYPE_PREFIX, sizeof(RSA_RPC_TYPE_PREFIX) - 1) == 0) { - break; - } - rsaRpcType = NULL; - token = strtok_r(NULL, delimiter, &savePtr); - } - if (rsaRpcType == NULL) { - celix_logHelper_error(logHelper,"RSA import reg: %s property is not exist.", RSA_RPC_TYPE_KEY); + const char *rsaShmRpcType = celix_properties_get(endpointDesc->properties, RSA_SHM_RPC_TYPE_KEY, NULL); + if (rsaShmRpcType == NULL) { + celix_logHelper_error(logHelper,"RSA import reg: %s property is not exist.", RSA_SHM_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } char filter[128] = {0}; - int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaRpcType); + int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaShmRpcType); if (bytes >= sizeof(filter)) { - celix_logHelper_error(logHelper,"RSA import reg: The value(%s) of %s is too long.", rsaRpcType, RSA_RPC_TYPE_KEY); + celix_logHelper_error(logHelper,"RSA import reg: The value(%s) of %s is too long.", rsaShmRpcType, RSA_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; diff --git a/libs/utils/error_injector/celix_properties/CMakeLists.txt b/libs/utils/error_injector/celix_properties/CMakeLists.txt index 2ddcf2fd0..60ae24b09 100644 --- a/libs/utils/error_injector/celix_properties/CMakeLists.txt +++ b/libs/utils/error_injector/celix_properties/CMakeLists.txt @@ -23,5 +23,6 @@ target_link_libraries(properties_ei PUBLIC Celix::error_injector Celix::utils) target_link_options(properties_ei INTERFACE LINKER:--wrap,celix_properties_create LINKER:--wrap,celix_properties_copy + LINKER:--wrap,celix_properties_set ) add_library(Celix::properties_ei ALIAS properties_ei) diff --git a/libs/utils/error_injector/celix_properties/include/celix_properties_ei.h b/libs/utils/error_injector/celix_properties/include/celix_properties_ei.h index fd4d1730e..cd94c140a 100644 --- a/libs/utils/error_injector/celix_properties/include/celix_properties_ei.h +++ b/libs/utils/error_injector/celix_properties/include/celix_properties_ei.h @@ -28,6 +28,7 @@ extern "C" { CELIX_EI_DECLARE(celix_properties_create, celix_properties_t*); CELIX_EI_DECLARE(celix_properties_copy, celix_properties_t*); +CELIX_EI_DECLARE(celix_properties_set, celix_status_t); #ifdef __cplusplus } diff --git a/libs/utils/error_injector/celix_properties/src/celix_properties_ei.cc b/libs/utils/error_injector/celix_properties/src/celix_properties_ei.cc index eea81d814..40b06000f 100644 --- a/libs/utils/error_injector/celix_properties/src/celix_properties_ei.cc +++ b/libs/utils/error_injector/celix_properties/src/celix_properties_ei.cc @@ -34,4 +34,11 @@ celix_properties_t *__wrap_celix_properties_copy(const celix_properties_t *prope return __real_celix_properties_copy(properties); } +celix_status_t __real_celix_properties_set(celix_properties_t *properties, const char *key, const char *value); +CELIX_EI_DEFINE(celix_properties_set, celix_status_t) +celix_status_t __wrap_celix_properties_set(celix_properties_t *properties, const char *key, const char *value) { + CELIX_EI_IMPL(celix_properties_set); + return __real_celix_properties_set(properties, key, value); +} + } \ No newline at end of file From 3b06116716dd3c3d25e6a91da49177808d48823e Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 25 Dec 2023 11:17:31 +0800 Subject: [PATCH 14/29] fix bugs for discovery_zeroconf --- .../DiscoveryZeroconfAnnouncerTestSuite.cc | 12 ++ .../src/DiscoveryZeroconfWatcherTestSuite.cc | 57 ++----- .../src/discovery_zeroconf_announcer.c | 34 +++- .../src/discovery_zeroconf_watcher.c | 146 ++++++++---------- 4 files changed, 118 insertions(+), 131 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index ab40dec29..344d9850f 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -157,6 +157,13 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed8) { EXPECT_EQ(status, CELIX_ENOMEM); } +TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed9) { + discovery_zeroconf_announcer_t *announcer{nullptr}; + celix_ei_expect_celix_stringHashMap_create((void*)&discoveryZeroconfAnnouncer_create, 0, nullptr, 2); + auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); + EXPECT_EQ(status, CELIX_ENOMEM); +} + TEST_F(DiscoveryZeroconfAnnouncerTestSuite, ConnectDNSServiceOneTimeFailure) { discovery_zeroconf_announcer_t *announcer{nullptr}; celix_ei_expect_DNSServiceCreateConnection(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); @@ -602,6 +609,11 @@ static void OnUseServiceForAddEndpointENOMEM(void *handle, void *svc) { EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); + celix_ei_expect_celix_stringHashMap_putLong(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + status = epl->endpointAdded(epl->handle, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ENOMEM); + celix_ei_expect_celix_stringHashMap_putLong(nullptr, 0, 0); + epl->endpointRemoved(epl->handle, endpoint, nullptr); endpointDescription_destroy(endpoint); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 8f14d7790..9179918d5 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -247,42 +247,19 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { discoveryZeroconfWatcher_destroy(watcher); } - void TestGetAddrInfo(void (*beforeRegServiceAction)(void), void (*afterRegServiceAction)(void), int interfaceIndex = kDNSServiceInterfaceIndexAny) { + void TestGetAddrInfo(void (*beforeRegServiceAction)(void), void (*afterRegServiceAction)(void)) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - char txtBuf[1300] = {0}; - TXTRecordRef txtRecord; - TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); - TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); - TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); - char propSizeStr[16]= {0}; - sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); - TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); - beforeRegServiceAction(); - DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, interfaceIndex, - "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, - htons(DZC_TEST_SERVICE_PORT), - TXTRecordGetLength(&txtRecord), - TXTRecordGetBytesPtr(&txtRecord), - OnDNSServiceRegisterCallback, nullptr); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - DNSServiceProcessResult(dsRef); - TXTRecordDeallocate(&txtRecord); + DNSServiceRef dsRef = RegisterTestService(); afterRegServiceAction(); DNSServiceRefDeallocate(dsRef); - sleep(2);//wait for service removed from mdnsd, avoid affect other test case + discoveryZeroconfWatcher_destroy(watcher); } @@ -480,16 +457,14 @@ static DNSServiceRef RegisterTestService(const char *endpointId, const char *ser DNSServiceRef dsRef{}; DNSServiceErrorType dnsErr; - int conflictCount = 0; - do { - conflictCount++; - char name[32]={0}; - snprintf(name, sizeof(name), "dzc_test_service_%d", conflictCount); - dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, name, - DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), - TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), - OnDNSServiceRegisterCallback, nullptr); - }while (dnsErr == kDNSServiceErr_NameConflict); + static int conflictCount = 0; + conflictCount++;//avoid conflict + char name[32]={0}; + snprintf(name, sizeof(name), "dzc_test_service_%d", conflictCount); + dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, name, + DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), + TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), + OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); return dsRef; @@ -963,16 +938,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutIpToHostEntry) { }); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutLoopBackIpToHostEntry) { - TestGetAddrInfo([](){ - celix_ei_expect_celix_stringHashMap_putBool(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); - ExpectMsgOutPut("Watcher: Failed to add localhost address. %d."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexLocalOnly); -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index edfd98bcc..961c37a0b 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -74,6 +74,7 @@ struct discovery_zeroconf_announcer { bool running; celix_string_hash_map_t *endpoints;//key:endpoint id, val:announce_endpoint_entry_t* celix_array_list_t *revokedEndpoints; + celix_string_hash_map_t *conflictCntMap;//key:service name, val:conflictCnt. Use to resolve conflict service name in same host.Because the mDNSResponder does not automatically resolve service name conflicts in the same host. }; typedef struct announce_endpoint_entry { @@ -131,6 +132,12 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce return CELIX_ENOMEM; } + celix_autoptr(celix_string_hash_map_t) conflictCntMap = announcer->conflictCntMap = celix_stringHashMap_create(); + if (conflictCntMap == NULL) { + celix_logHelper_fatal(logHelper, "Announcer: Failed to create conflict count map."); + return CELIX_ENOMEM; + } + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); if (fwUuid == NULL || strlen(fwUuid) >= sizeof(announcer->fwUuid)) { celix_logHelper_fatal(logHelper, "Announcer: Failed to get framework uuid."); @@ -168,6 +175,7 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce celixThread_setName(&announcer->refreshEPThread, "DiscAnnouncer"); epListenerSvcReg.svcId = -1; + celix_steal_ptr(conflictCntMap); celix_steal_ptr(revokedEndpoints); celix_steal_ptr(endpoints); celix_steal_ptr(mutex); @@ -185,6 +193,7 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce celix_bundleContext_unregisterServiceAsync(announcer->ctx, announcer->epListenerSvcId, NULL, NULL); celix_bundleContext_waitForAsyncUnregistration(announcer->ctx, announcer->epListenerSvcId); + celix_stringHashMap_destroy(announcer->conflictCntMap); announce_endpoint_entry_t *entry = NULL; int size = celix_arrayList_size(announcer->revokedEndpoints); for (int i = 0; i < size; ++i) { @@ -388,10 +397,18 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en } celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&announcer->mutex); + long conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); + status = celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, conflictCnt + 1); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put conflict count for %s.", entry->serviceName); + return status; + } status = celix_stringHashMap_put(announcer->endpoints, endpoint->id, entry); if (status == CELIX_SUCCESS) { celix_steal_ptr(entry); } else { + celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, conflictCnt); celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put endpoint entry for %s.", endpoint->id); return status; @@ -498,18 +515,21 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno continue; } + celixThreadMutex_lock(&announcer->mutex); + long conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); + celixThreadMutex_unlock(&announcer->mutex); DNSServiceErrorType dnsErr; char instanceName[64] = {0}; bool registered = false; - int conflictCnt = 1; + int resolvedConflictCnt = 0; DNSServiceRef dsRef; do { dsRef = announcer->sharedRef;//DNSServiceRegister will set a new value for dsRef int bytes = 0; - if (conflictCnt == 1) { + if (conflictCnt <= 1) { bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld", entry->serviceName, (long)announcer->pid); } else { - bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld(%d)", entry->serviceName, (long)announcer->pid, conflictCnt); + bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld(%ld)", entry->serviceName, (long)announcer->pid, conflictCnt); } if (bytes >= sizeof(instanceName)) { celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service name for %s.", entry->serviceName); @@ -522,8 +542,14 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno } else { celix_logHelper_error(announcer->logHelper, "Announcer: Failed to announce service, %s. %d", instanceName, dnsErr); } + if (dnsErr == kDNSServiceErr_NameConflict) { + celixThreadMutex_lock(&announcer->mutex); + conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); + celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, ++conflictCnt); + celixThreadMutex_unlock(&announcer->mutex); + } //LocalOnly service may be return kDNSServiceErr_NameConflict, but mDNS daemon will resolve the instance name conflicts for non-LocalOnly service - } while (dnsErr == kDNSServiceErr_NameConflict && conflictCnt++ < DZC_MAX_CONFLICT_CNT); + } while (dnsErr == kDNSServiceErr_NameConflict && resolvedConflictCnt++ < DZC_MAX_CONFLICT_CNT); TXTRecordDeallocate(&txtRecord); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index f26e4477f..1365ab69d 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -115,7 +115,7 @@ typedef struct watched_host_entry { char *hostname; int ifIndex; celix_string_hash_map_t *ipAddresses;//key:ip address, val:true(ipv4)/false(ipv6) - struct timespec activeStartTime; + bool resolved; int resolvedCnt; bool markDeleted; }watched_host_entry_t; @@ -354,43 +354,44 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix } else { svcSubType = token; } - size_t subTypeLen = strlen(svcSubType); - if (subTypeLen > 63) { - celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service type for %s.", token); - } else { - celixThreadMutex_lock(&watcher->mutex); - service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); - if (browserEntry == NULL) { - browserEntry = (service_browser_entry_t *)calloc(1, sizeof(*browserEntry)); - if (browserEntry != NULL) { - browserEntry->watchedServices = celix_stringHashMap_create(); - if (browserEntry->watchedServices != NULL) { - browserEntry->refCnt = 1; - browserEntry->resolvedCnt = 0; - browserEntry->browseRef = NULL; - browserEntry->logHelper = watcher->logHelper; - browserEntry->markDeleted = false; - if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) == CELIX_SUCCESS) { - refreshBrowsers = true; - } else { - celix_stringHashMap_destroy(browserEntry->watchedServices); - free(browserEntry); - celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service browser entry."); - } - } else { - free(browserEntry); - celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create watched services map."); - } - } else { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service browser entry."); - } - } else { + do { + size_t subTypeLen = strlen(svcSubType); + if (subTypeLen > 63) { + celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service type for %s.", token); + break; + } + celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&watcher->mutex); + celix_autofree service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); + if (browserEntry != NULL) { browserEntry->refCnt++; + celix_steal_ptr(browserEntry); + break; } - celixThreadMutex_unlock(&watcher->mutex); - } + browserEntry = (service_browser_entry_t *)calloc(1, sizeof(*browserEntry)); + if (browserEntry == NULL) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc service browser entry."); + break; + } + celix_autoptr(celix_string_hash_map_t) watchedServices = browserEntry->watchedServices = celix_stringHashMap_create(); + if (watchedServices == NULL) { + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create watched services map."); + break; + } + browserEntry->refCnt = 1; + browserEntry->resolvedCnt = 0; + browserEntry->browseRef = NULL; + browserEntry->logHelper = watcher->logHelper; + browserEntry->markDeleted = false; + if (celix_stringHashMap_put(watcher->serviceBrowsers, svcSubType, browserEntry) != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to put service browser entry."); + break; + } + celix_steal_ptr(watchedServices); + celix_steal_ptr(browserEntry); + refreshBrowsers = true; + } while (0); token = strtok(NULL, ","); } @@ -428,7 +429,7 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce if ((browserEntry != NULL) && (--browserEntry->refCnt == 0)) { if (browserEntry->browseRef == NULL) {//if browser is not browsing, remove it directly, otherwise, let the watchEPThread remove it celix_stringHashMap_remove(watcher->serviceBrowsers, svcSubType); - celix_stringHashMap_destroy(browserEntry->watchedServices); + celix_stringHashMap_destroy(browserEntry->watchedServices);//TODO fix bug free(browserEntry); } else { refreshBrowsers = true; @@ -458,6 +459,9 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to resolve service, or hostname invalid, %d.", errorCode); return; } + if (interfaceIndex != svcEntry->ifIndex) { + return; + } celix_properties_t *properties = svcEntry->txtRecord; int cnt = TXTRecordGetCount(txtLen, txtRecord); for (int i = 0; i < cnt; ++i) { @@ -486,8 +490,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, const char *version = celix_properties_get(properties, DZC_TXT_RECORD_VERSION_KEY, ""); if (propSize == celix_properties_size(properties) && strcmp(DZC_CURRENT_TXT_RECORD_VERSION, version) == 0) { svcEntry->port = ntohs(port); - //DZC_PORT_DEFAULT is used for the remote service that IPC is not network based(e.g.:shared memory). No need to resolve host information. - if (svcEntry->port != DZC_PORT_DEFAULT) { + if (svcEntry->ifIndex != kDNSServiceInterfaceIndexLocalOnly || svcEntry->port != DZC_PORT_DEFAULT) {//if it is not network service, no need to resolve ip address svcEntry->hostname = celix_utils_strdup(host); if (svcEntry->hostname == NULL) { celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to dup hostname."); @@ -495,6 +498,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, return; } } + celix_properties_unset(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY);//Service endpoint do not need it celix_properties_unset(properties, DZC_TXT_RECORD_VERSION_KEY);//Service endpoint do not need it svcEntry->resolved = true; @@ -730,22 +734,11 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ int status = CELIX_SUCCESS; watched_host_entry_t *hostEntry = (watched_host_entry_t *)context; assert(hostEntry != NULL); - if (errorCode == kDNSServiceErr_NoSuchRecord) { - //If localonly interface cannot found record, then add localhost address.Because the mDNSResponder will skip the loopback interface,if it found a normal interface. - if (ifIndex == kDNSServiceInterfaceIndexLocalOnly) { - if (celix_stringHashMap_size(hostEntry->ipAddresses) == 0) { - status = celix_stringHashMap_putBool(hostEntry->ipAddresses, "127.0.0.1", true); - if (status != CELIX_SUCCESS) { - celix_logHelper_logTssErrors(hostEntry->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(hostEntry->logHelper, "Watcher: Failed to add localhost address. %d.", status); - return; - } - } - hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); - } + if (errorCode != kDNSServiceErr_NoError || address == NULL || (address->sa_family != AF_INET && address->sa_family != AF_INET6)) { + celix_logHelper_error(hostEntry->logHelper, "Watcher: Failed to resolve host %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, errorCode); return; } - if (errorCode != kDNSServiceErr_NoError || address == NULL || (address->sa_family != AF_INET && address->sa_family != AF_INET6)) { + if (ifIndex != hostEntry->ifIndex) { return; } @@ -766,13 +759,7 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ celix_stringHashMap_remove(hostEntry->ipAddresses, ip); } - if (!(flags & kDNSServiceFlagsMoreComing)) { - hostEntry->activeStartTime = celix_gettime(CLOCK_MONOTONIC); - hostEntry->activeStartTime.tv_sec += 2;//If the host information does not change within 2 seconds, we will use the host information to create endpoint description. - } else { - hostEntry->activeStartTime.tv_sec = INT_MAX; - hostEntry->activeStartTime.tv_nsec = 0; - } + hostEntry->resolved = !(flags & kDNSServiceFlagsMoreComing); return; } @@ -794,7 +781,7 @@ static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watc //add or mark hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue; - if (svcEntry->hostname != NULL) { + if (svcEntry->hostname != NULL && svcEntry->ifIndex != kDNSServiceInterfaceIndexLocalOnly) { celix_autofree watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, svcEntry->hostname, svcEntry->ifIndex); if (hostEntry != NULL) { hostEntry->markDeleted = false; @@ -820,7 +807,7 @@ static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watc } hostEntry->sdRef = NULL; hostEntry->logHelper = watcher->logHelper; - hostEntry->activeStartTime.tv_sec = INT_MAX; + hostEntry->resolved = false; hostEntry->ifIndex = svcEntry->ifIndex; hostEntry->resolvedCnt = 0; hostEntry->markDeleted = false; @@ -869,7 +856,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; if (watcher->sharedRef && hostEntry->sdRef == NULL && hostEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { hostEntry->sdRef = watcher->sharedRef; - DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection | kDNSServiceFlagsReturnIntermediates, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); + DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); if (dnsErr != kDNSServiceErr_NoError) { hostEntry->sdRef = NULL; celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get address info for %s on %d, %d.", hostEntry->hostname, hostEntry->ifIndex, dnsErr); @@ -883,8 +870,8 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher return; } -static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex, unsigned int *pNextWorkIntervalTime) { - if (hostname == NULL) {//if no need to resolve host info, then return true +static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex) { + if (hostname == NULL || ifIndex == kDNSServiceInterfaceIndexLocalOnly) {//if no need to resolve host info, then return true return true; } watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, hostname, ifIndex); @@ -894,19 +881,16 @@ static bool discoveryZeroConfWatcher_isHostResolved(discovery_zeroconf_watcher_t if (celix_stringHashMap_size(hostEntry->ipAddresses) == 0) { return false; } - double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime); - if (elapsed >= 0) { - return true; - } else if (hostEntry->activeStartTime.tv_sec != INT_MAX) { - unsigned int tmp = abs((int)elapsed); - *pNextWorkIntervalTime = MIN(*pNextWorkIntervalTime, tmp); - } - return false; + return hostEntry->resolved; } static int discoveryZeroConfWatcher_getHostIpAddresses(discovery_zeroconf_watcher_t *watcher, const char *hostname, int ifIndex, char **ipAddressesStrOut) { celix_autofree char *ipAddressesStr = NULL; + if (ifIndex == kDNSServiceInterfaceIndexLocalOnly) { + *ipAddressesStrOut = celix_utils_strdup("127.0.0.1,::1"); + return (*ipAddressesStrOut != NULL) ? CELIX_SUCCESS : CELIX_ENOMEM; + } watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, hostname, ifIndex); if (hostEntry != NULL) { CELIX_STRING_HASH_MAP_ITERATE(hostEntry->ipAddresses, iter) { @@ -1073,9 +1057,9 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z } watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, endpointEntry->hostname, endpointEntry->ifIndex); if (hostEntry == NULL) { - return true; + return false; } - if (celix_elapsedtime(CLOCK_MONOTONIC, hostEntry->activeStartTime) < 0) { + if (!hostEntry->resolved) { return false; } if (endpointEntry->ipAddressesStr != NULL) { @@ -1115,7 +1099,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher while (!celix_stringHashMapIterator_isEnd(&epIter)) { epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry)) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); + celix_logHelper_debug(watcher->logHelper, "Watcher: Remove ip changed endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); celix_stringHashMapIterator_remove(&epIter); discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); endpointEntry_destroy(epEntry); @@ -1133,7 +1117,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher svcEntry = (watched_service_entry_t *)iter.value.ptrValue; if (svcEntry->endpointId != NULL && svcEntry->resolved) { epEntry = (watched_endpoint_entry_t *)celix_stringHashMap_get(watcher->watchedEndpoints, svcEntry->endpointId); - if (epEntry == NULL && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex, &nextWorkIntervalTime)) { + if (epEntry == NULL && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex)) { celix_status_t status = discoveryZeroConfWatcher_createEndpointEntryForService(watcher, svcEntry, &epEntry); if (status != CELIX_SUCCESS) { // If properties invalid,endpointDescription_create will return error. @@ -1145,7 +1129,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher } continue; } - celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); + celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); if (celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry) == CELIX_SUCCESS) { discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, true); } else { @@ -1165,15 +1149,15 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); while (!celix_stringHashMapIterator_isEnd(&epIter)) { epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; - double elapsed = celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime); + int elapsed = (int)celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime); if (elapsed >= 0) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %s.", epEntry->endpoint->serviceName, epEntry->endpoint->frameworkUUID); + celix_logHelper_debug(watcher->logHelper, "Watcher: Remove expired endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); celix_stringHashMapIterator_remove(&epIter); discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); endpointEntry_destroy(epEntry); } else { if (epEntry->expiredTime.tv_sec != INT_MAX) { - unsigned int tmp = abs((int)elapsed); + unsigned int tmp = abs(elapsed); nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; } celix_stringHashMapIterator_next(&epIter); From ddcd91b92d9597597a600816e5ef19e0cb1a8e86 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 25 Dec 2023 12:13:42 +0800 Subject: [PATCH 15/29] Add zeroconf configuration type for rsa_dfi --- .../gtest/src/rsa_tests.cc | 54 ++++++++ .../src/remote_service_admin_activator.c | 14 +- .../src/remote_service_admin_dfi.c | 122 +++++++++++++++--- .../src/remote_service_admin_dfi_constants.h | 9 ++ 4 files changed, 178 insertions(+), 21 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc index 966a4c4dd..b905f0119 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc @@ -118,6 +118,7 @@ extern "C" { celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8888/service/42/org.apache.celix.Example"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.Example"); int rc = endpointDescription_create(props, &endpoint); @@ -154,6 +155,55 @@ extern "C" { ASSERT_TRUE(called); } + static void testImportServiceCallbackForZeroconfConfigType(void *handle CELIX_UNUSED, void *svc) { + thread_local bool init = true; + thread_local endpoint_description_t *endpoint = nullptr; + if (init) { + auto *rsa = static_cast(svc); + celix_properties_t *props = celix_properties_create(); + celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.remote.admin.dfi.zeroconf.http"); + celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.port", "8888"); + celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.ipaddresses", "127.0.0.1"); + celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.path", "/service/42/org.apache.celix.Example"); + celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.Example"); + + int rc = endpointDescription_create(props, &endpoint); + ASSERT_EQ(CELIX_SUCCESS, rc); + + import_registration_t* reg = nullptr; + rc = rsa->importService(rsa->admin, endpoint, ®); + ASSERT_EQ(CELIX_SUCCESS, rc); + ASSERT_TRUE(reg != nullptr); + + init = false; + } else { + int rc = endpointDescription_destroy(endpoint); + ASSERT_EQ(CELIX_SUCCESS, rc); + } + } + + static void testImportServiceForZeroconfConfigType(void) { + celix_service_use_options_t opts{}; + opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.use = testImportServiceCallbackForZeroconfConfigType; + opts.waitTimeoutInSeconds = 0.25; + + //first call -> init + bool called = celix_bundleContext_useServiceWithOptions(context, &opts); + ASSERT_TRUE(called); + + celix_framework_waitForEmptyEventQueue(celix_bundleContext_getFramework(context)); + long svcId = celix_bundleContext_findService(context, "org.apache.celix.Example"); + EXPECT_GE(svcId, 0); + + //second call -> deinit + called = celix_bundleContext_useServiceWithOptions(context, &opts); + ASSERT_TRUE(called); + } + static void testBundles(void) { array_list_pt bundles = NULL; @@ -204,6 +254,10 @@ TEST_F(RsaDfiTests, ImportService) { testImportService(); } +TEST_F(RsaDfiTests, ImportServiceForZeroconfConfigType) { + testImportServiceForZeroconfConfigType(); +} + TEST_F(RsaDfiTests, TestBundles) { testBundles(); } diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c index 0b470da72..3d0e78aa3 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c @@ -22,6 +22,8 @@ #include "remote_service_admin_dfi.h" #include "export_registration_dfi.h" #include "import_registration_dfi.h" +#include "remote_service_admin_dfi_constants.h" +#include "remote_constants.h" typedef struct celix_remote_service_admin_activator { remote_service_admin_t *admin; @@ -32,7 +34,14 @@ typedef struct celix_remote_service_admin_activator { static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* activator, celix_bundle_context_t* ctx) { celix_status_t status = CELIX_SUCCESS; activator->svcIdRsa = -1; - + celix_autoptr(celix_properties_t) props = celix_properties_create(); + if (props == NULL) { + return CELIX_ENOMEM; + } + status = celix_properties_set(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); + if (status != CELIX_SUCCESS) { + return status; + } status = remoteServiceAdmin_create(ctx, &activator->admin); if (status == CELIX_SUCCESS) { activator->adminService.admin = activator->admin; @@ -56,7 +65,8 @@ static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* ac activator->adminService.importRegistration_getException = importRegistration_getException; activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference; - activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, OSGI_RSA_REMOTE_SERVICE_ADMIN, NULL); + activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, OSGI_RSA_REMOTE_SERVICE_ADMIN, + celix_steal_ptr(props)); } return status; 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 index e8c34e3ec..103a3ea81 100644 --- 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 @@ -46,6 +46,8 @@ #include "remote_service_admin_dfi_constants.h" #include "celix_bundle_context.h" +#include "celix_string_hash_map.h" +#include "celix_stdlib_cleanup.h" // defines how often the webserver is restarted (with an increased port number) #define MAX_NUMBER_OF_RESTARTS 5 @@ -202,16 +204,6 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote const char *interface = celix_bundleContext_getProperty(context, RSA_INTERFACE_KEY, NULL); (*admin)->curlShareEnabled = celix_bundleContext_getPropertyAsBool(context, RSA_DFI_USE_CURL_SHARE_HANDLE, RSA_DFI_USE_CURL_SHARE_HANDLE_DEFAULT); - const char *networkInterfaces = celix_bundleContext_getProperty(context, CELIX_RSA_NETWORK_INTERFACES, NULL); - char *interfacesCopy = NULL; - if (networkInterfaces != NULL) { - interfacesCopy = celix_utils_strdup(networkInterfaces); - const char delimiter[2] = ","; - char *savePtr; - //TODO Supports multiple network interfaces - interface = strtok_r(interfacesCopy, delimiter, &savePtr); - } - char *discoveryInterface = NULL; char *detectedIp = NULL; if ((interface != NULL) && (remoteServiceAdmin_getIpAddress((char*)interface, &detectedIp) != CELIX_SUCCESS)) { @@ -224,10 +216,6 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote discoveryInterface = remoteServiceAdmin_getIFNameForIP(ip); } - if (interfacesCopy != NULL) { - free(interfacesCopy); - } - if (ip != NULL) { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_DEBUG, "RSA: Using %s for service annunciation", ip); (*admin)->ip = strdup(ip); @@ -765,11 +753,13 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic celix_properties_set(endpointProperties, OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId); celix_properties_set(endpointProperties, OSGI_RSA_ENDPOINT_ID, endpoint_uuid); celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) RSA_DFI_CONFIGURATION_TYPE); + celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); celix_properties_set(endpointProperties, RSA_DFI_ENDPOINT_URL, url); if (admin->discoveryInterface != NULL) { - celix_properties_set(endpointProperties, CELIX_RSA_NETWORK_INTERFACES, admin->discoveryInterface); + celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IFNAME, admin->discoveryInterface); } + celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, admin->port); + celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, buf); if (props != NULL) { CELIX_PROPERTIES_ITERATE(props, iter) { @@ -870,6 +860,43 @@ celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_t *a return status; } +static bool checkConfigurationType(endpoint_description_t *endpoint, const char *configType) { + bool result = true; + if (strncmp(configType, RSA_DFI_CONFIGURATION_TYPE, 1024) == 0) { + const char *url = celix_properties_get(endpoint->properties, RSA_DFI_ENDPOINT_URL, NULL); + if (url == NULL) { + result = false; + } + } else if (strncmp(configType, CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE, 1024) == 0) { + const char *ip = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES, NULL);//the property is set by the discovery_zeroconf + const char *port = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, NULL); + const char *path = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, NULL); + if (ip == NULL || port == NULL || path == NULL) { + return false; + } + celix_autofree char *ipCopy = celix_utils_strdup(ip); + if (ipCopy == NULL) { + return false; + } + char *savePtr = NULL; + char *token = strtok_r(ipCopy, ",", &savePtr); + result = (token != NULL); + while (token != NULL) { + struct sockaddr_in sa; + struct sockaddr_in6 sa6; + if (inet_pton(AF_INET, token, &sa.sin_addr) != 1 && inet_pton(AF_INET6, token, &sa6.sin6_addr) != 1) { + result = false; + break; + } + token = strtok_r(NULL, ",", &savePtr); + } + } else { + result = false; + } + + return result; +} + celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, endpoint_description_t *endpointDescription, import_registration_t **out) { celix_status_t status = CELIX_SUCCESS; @@ -883,7 +910,7 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, e token = strtok_r(ecCopy, delimiter, &savePtr); while (token != NULL) { - if (strncmp(celix_utils_trimInPlace(token), RSA_DFI_CONFIGURATION_TYPE, 1024) == 0) { + if (checkConfigurationType(endpointDescription, celix_utils_trimInPlace(token))) { importService = true; break; } @@ -954,6 +981,42 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_t * static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply, int* replyStatus) { remote_service_admin_t * rsa = handle; + celix_autoptr(celix_string_hash_map_t) ipAddressMap = NULL; + celix_autofree char *ipStrListCopy = NULL; + const char *ipaddresses = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES, NULL); + if (ipaddresses != NULL) { + celix_string_hash_map_create_options_t opts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; + opts.storeKeysWeakly = true; + ipAddressMap = celix_stringHashMap_createWithOptions(&opts); + if (ipAddressMap == NULL) { + celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(rsa->loghelper, "Error creating ip address map"); + return CELIX_ENOMEM; + } + ipStrListCopy = celix_utils_strdup(ipaddresses); + if (ipStrListCopy == NULL) { + return CELIX_ENOMEM; + } + char *savePtr = NULL; + char *token = strtok_r(ipStrListCopy, ",", &savePtr); + while (token != NULL) { + char *ip = celix_utils_trimInPlace(token); + struct sockaddr_in sa; + if (inet_pton(AF_INET, ip, &(sa.sin_addr)) == 1) { + if (celix_stringHashMap_putBool(ipAddressMap, ip, true) != CELIX_SUCCESS) {//IPV4 + celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_WARNING); + celix_logHelper_warning(rsa->loghelper, "Error putting ip address in map"); + } + } else { + if (celix_stringHashMap_putBool(ipAddressMap, ip, false) != CELIX_SUCCESS) {//IPV6 + celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_WARNING); + celix_logHelper_warning(rsa->loghelper, "Error putting ip address in map"); + } + } + token = strtok_r(NULL, ",", &savePtr); + } + } + struct celix_post_data post; post.readptr = request; post.size = strlen(request); @@ -990,6 +1053,8 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description curl = curl_easy_init(); if(!curl) { + fclose(get.stream); + free(get.buf); status = CELIX_ILLEGAL_STATE; } else { struct curl_slist *metadataHeader = NULL; @@ -1006,7 +1071,6 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description 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); @@ -1016,7 +1080,27 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description if (rsa->curlShareEnabled) { curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare); } - res = curl_easy_perform(curl); + if (ipAddressMap == NULL || celix_stringHashMap_size(ipAddressMap) == 0) {//no zeroconf addresses found, use org.amdatu.remote.admin.http.url + curl_easy_setopt(curl, CURLOPT_URL, url); + res = curl_easy_perform(curl); + } else { + const char *port = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, ""); + const char *path = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, ""); + CELIX_STRING_HASH_MAP_ITERATE(ipAddressMap, iter) { + const char *ip = iter.key; + bool ipv4 = iter.value.boolValue; + if (ipv4) { + snprintf(url, sizeof(url), "http://%s:%s%s", ip, port, path); + } else { + snprintf(url, sizeof(url), "http://[%s]:%s%s", ip, port, path); + } + curl_easy_setopt(curl, CURLOPT_URL, url); + res = curl_easy_perform(curl); + if (res != CURLE_COULDNT_CONNECT) {//TODO cache the ip address and use it for the next call + break; + } + } + } fputc('\0', get.stream); fclose(get.stream); diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h index e10a6d662..6cc92529f 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h @@ -36,6 +36,15 @@ #define RSA_DFI_CONFIGURATION_TYPE "org.amdatu.remote.admin.http" #define RSA_DFI_ENDPOINT_URL "org.amdatu.remote.admin.http.url" +/** + * @brief RSA Configuration type for zeroconf http, it is synonymous(https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1698916) with RSA_DFI_CONFIGURATION_TYPE, they refer to the same endpoint. + */ +#define CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE "celix.remote.admin.dfi.zeroconf.http" +#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IFNAME "celix.remote.admin.dfi.zeroconf.http.ifname" +#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT "celix.remote.admin.dfi.zeroconf.http.port" +#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES "celix.remote.admin.dfi.zeroconf.http.ipaddresses" +#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH "celix.remote.admin.dfi.zeroconf.http.path" + /** * @brief Remote Service Admin DFI environment property (named "RSA_DFI_USE_CURL_SHARE_HANDLE") which specified * whether the RSA DFI should use curl's share handle. From ea552e56db45fe48d8d8891df1cf7f586fe4d4d4 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 25 Dec 2023 12:13:59 +0800 Subject: [PATCH 16/29] Add zeroconf configuration type for rsa_dfi --- .../remote_services/rsa_spi/include/remote_constants.h | 9 --------- .../remote_services/rsa_spi/include/rsa_rpc_factory.h | 6 ------ 2 files changed, 15 deletions(-) diff --git a/bundles/remote_services/rsa_spi/include/remote_constants.h b/bundles/remote_services/rsa_spi/include/remote_constants.h index cdcdf4fe7..1532d274a 100644 --- a/bundles/remote_services/rsa_spi/include/remote_constants.h +++ b/bundles/remote_services/rsa_spi/include/remote_constants.h @@ -36,15 +36,6 @@ static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported. static const char * const OSGI_RSA_SERVICE_EXPORTED_CONFIGS = "service.exported.configs"; static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location"; -/** - * Remote service admin property identifying the network interfaces that announce service. - * The property value is network interfaces name, it Can be a comma separated list of CIDR notation,eg:"eth0,en0". - * Default value is "", and the loopback interface will be used. Its exported service will be discovered - * only by other local clients on the same machine. - * If want to bound service to all network interfaces, we can set the property value to "all". - */ -static const char * const CELIX_RSA_NETWORK_INTERFACES = "org.apache.celix.rsa.network.interfaces"; - /** * It identify which types of remote service configurations are supported by a distribution provider. * @ref https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1708968 diff --git a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h index 8c9027237..875b77b24 100644 --- a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h +++ b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h @@ -33,12 +33,6 @@ extern "C" { */ #define RSA_RPC_TYPE_KEY "celix.remote.admin.rpc_type" -/** - * @brief The prefix for RPC type value, and the RPC type value belongs to `service.exported.configs`. - * A whole RPC type value as follows: celix.remote.admin.rpc_type.json,celix.remote.admin.rpc_type.avpr. - */ -#define RSA_RPC_TYPE_PREFIX "celix.remote.admin.rpc_type." - #define RSA_RPC_FACTORY_NAME "rsa_rpc_factory" #define RSA_RPC_FACTORY_VERSION "1.0.0" #define RSA_RPC_FACTORY_USE_RANGE "[1.0.0,2.0.0)" From eedf073b504604cc46293715f76c626b6b0db0f8 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 25 Dec 2023 21:17:43 +0800 Subject: [PATCH 17/29] Rename the configurations name of rsa_shm --- .../rsa_shm/src/rsa_shm_constants.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h index c46e4647b..a7c47a0f2 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_constants.h @@ -33,16 +33,16 @@ extern "C" { */ #define RSA_SHM_SERVER_NAME_KEY "celix.remote.admin.shm.server_name" /** - * @brief The serializer type of RSA_SHM_CONFIGURATION_TYPE. The value should associated with RSA_RPC_TYPE_KEY of rsa_rpc_factory_t. + * @brief The serializer type of RSA_SHM_CONFIGURATION_TYPE. The value should be associated with RSA_RPC_TYPE_KEY of rsa_rpc_factory_t. */ #define RSA_SHM_RPC_TYPE_KEY "celix.remote.admin.shm.rpc_type" /** * @brief A property of RsaShm bundle that indicates the shared memory pool size. - * Its value should be greater than 8192, because the memory pool ctrl block(control_t) size is 6536 bytes. + * Its value should be greater than or equal to 8192, because the memory pool ctrl block(control_t) size is 6536 bytes. * */ -#define RSA_SHM_MEMORY_POOL_SIZE_KEY "RSA_SHM_POOL_SIZE" +#define RSA_SHM_MEMORY_POOL_SIZE_KEY "CELIX_RSA_SHM_POOL_SIZE" /** * @brief Shared memory pool default size * @@ -53,7 +53,7 @@ extern "C" { * @brief A property of RsaShm bundle that indicates the timeout of remote service invocation. * */ -#define RSA_SHM_MSG_TIMEOUT_KEY "RSA_SHM_MSG_TIMEOUT" +#define RSA_SHM_MSG_TIMEOUT_KEY "CELIX_RSA_SHM_MSG_TIMEOUT" /** * @brief The default timeout of remote service invocation. * @@ -65,7 +65,7 @@ extern "C" { * If there are more concurrent invocations than its value, service invocation will fail. * */ -#define RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY "RSA_SHM_MAX_CONCURRENT_INVOCATIONS_NUM" +#define RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY "CELIX_RSA_SHM_MAX_CONCURRENT_INVOCATIONS_NUM" /** * @brief The default value of the maximum concurrent invocations, If property RSA_SHM_MAX_CONCURRENT_INVOCATIONS_KEY does not exist, the default value is used From 11c8fdc5a5539b83b486b4ee2b5115f642903dd1 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 25 Dec 2023 21:43:29 +0800 Subject: [PATCH 18/29] Rename remote service bundles --- bundles/remote_services/discovery_configured/CMakeLists.txt | 1 + bundles/remote_services/discovery_etcd/CMakeLists.txt | 1 + bundles/remote_services/discovery_zeroconf/CMakeLists.txt | 1 + bundles/remote_services/remote_service_admin_dfi/CMakeLists.txt | 1 + .../remote_service_admin_shm_v2/rsa_shm/CMakeLists.txt | 1 + bundles/remote_services/rsa_rpc_json/CMakeLists.txt | 1 + bundles/remote_services/topology_manager/CMakeLists.txt | 1 + 7 files changed, 7 insertions(+) diff --git a/bundles/remote_services/discovery_configured/CMakeLists.txt b/bundles/remote_services/discovery_configured/CMakeLists.txt index 176cb680b..0c72e64ad 100644 --- a/bundles/remote_services/discovery_configured/CMakeLists.txt +++ b/bundles/remote_services/discovery_configured/CMakeLists.txt @@ -21,6 +21,7 @@ if (RSA_DISCOVERY_CONFIGURED) VERSION 0.9.0 SYMBOLIC_NAME "apache_celix_rsa_discovery" NAME "Apache Celix RSA Configured Discovery" + FILENAME celix_rsa_discovery_configured SOURCES src/discovery_impl.c ) diff --git a/bundles/remote_services/discovery_etcd/CMakeLists.txt b/bundles/remote_services/discovery_etcd/CMakeLists.txt index 67de75131..35346ca07 100644 --- a/bundles/remote_services/discovery_etcd/CMakeLists.txt +++ b/bundles/remote_services/discovery_etcd/CMakeLists.txt @@ -22,6 +22,7 @@ if (RSA_DISCOVERY_ETCD) SYMBOLIC_NAME "apache_celix_rsa_discovery_etcd" NAME "Apache Celix RSA Discovery ETCD" GROUP "Celix/RSA" + FILENAME celix_rsa_discovery_etcd SOURCES src/discovery_impl.c src/etcd_watcher.c diff --git a/bundles/remote_services/discovery_zeroconf/CMakeLists.txt b/bundles/remote_services/discovery_zeroconf/CMakeLists.txt index bf1fa6c20..4d7e0b4d1 100644 --- a/bundles/remote_services/discovery_zeroconf/CMakeLists.txt +++ b/bundles/remote_services/discovery_zeroconf/CMakeLists.txt @@ -40,6 +40,7 @@ if (RSA_DISCOVERY_ZEROCONF) VERSION "2.0.0" NAME "Apache Celix Multicast zeroconf service discovery" GROUP "Celix/RSA" + FILENAME celix_rsa_discovery_zeroconf SOURCES ${RSA_DISCOVERY_ZEROCONF_SRC} ) diff --git a/bundles/remote_services/remote_service_admin_dfi/CMakeLists.txt b/bundles/remote_services/remote_service_admin_dfi/CMakeLists.txt index 27dee5838..c2d5f0965 100644 --- a/bundles/remote_services/remote_service_admin_dfi/CMakeLists.txt +++ b/bundles/remote_services/remote_service_admin_dfi/CMakeLists.txt @@ -27,6 +27,7 @@ if (RSA_REMOTE_SERVICE_ADMIN_DFI) SYMBOLIC_NAME "apache_celix_remote_service_admin_dfi" NAME "Apache Celix Remote Service Admin Dynamic Function Interface (DFI)" GROUP "Celix/RSA" + FILENAME celix_rsa_dfi SOURCES src/remote_service_admin_dfi.c src/remote_service_admin_activator.c diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/CMakeLists.txt b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/CMakeLists.txt index b7189afcd..48370496c 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/CMakeLists.txt +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/CMakeLists.txt @@ -41,6 +41,7 @@ add_celix_bundle(rsa_shm SYMBOLIC_NAME "apache_celix_remote_service_admin_shm_v2" NAME "Apache Celix Remote Service Admin SHM V2" GROUP "Celix/RSA" + FILENAME celix_rsa_shm SOURCES ${RSA_SHM_SRC} ) diff --git a/bundles/remote_services/rsa_rpc_json/CMakeLists.txt b/bundles/remote_services/rsa_rpc_json/CMakeLists.txt index 779b7e864..0733be48e 100644 --- a/bundles/remote_services/rsa_rpc_json/CMakeLists.txt +++ b/bundles/remote_services/rsa_rpc_json/CMakeLists.txt @@ -44,6 +44,7 @@ if (RSA_JSON_RPC) SYMBOLIC_NAME "apache_celix_rsa_json_rpc" NAME "Apache Celix Remote Service Admin JSON RPC" GROUP "Celix/RSA" + FILENAME celix_rsa_json_rpc SOURCES ${RSA_JSON_RPC_SRC} ) diff --git a/bundles/remote_services/topology_manager/CMakeLists.txt b/bundles/remote_services/topology_manager/CMakeLists.txt index 1ed7420be..ea6ccf702 100644 --- a/bundles/remote_services/topology_manager/CMakeLists.txt +++ b/bundles/remote_services/topology_manager/CMakeLists.txt @@ -24,6 +24,7 @@ add_celix_bundle(rsa_topology_manager SYMBOLIC_NAME "apache_celix_rs_topology_manager" GROUP "Celix/RSA" NAME "Apache Celix RS Topology Manager" + FILENAME celix_rsa_topology_manager ) target_include_directories(rsa_topology_manager PRIVATE src) target_include_directories(rsa_topology_manager PRIVATE include) From 8100c7f91bd5d34ac89d6e15f8266fb1b157a817 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Thu, 28 Dec 2023 19:33:39 +0800 Subject: [PATCH 19/29] Fix bugs for discovery_zeroconf --- .../discovery_zeroconf/gtest/CMakeLists.txt | 3 + .../DiscoveryZeroconfActivatorTestSuite.cc | 112 ++++++++ .../DiscoveryZeroconfAnnouncerTestSuite.cc | 246 +++++++---------- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 251 +++++++++++++----- .../src/discovery_zeroconf_activator.c | 95 ++++++- .../src/discovery_zeroconf_announcer.c | 158 +++++------ .../src/discovery_zeroconf_announcer.h | 6 +- .../src/discovery_zeroconf_watcher.c | 169 +++++------- .../src/discovery_zeroconf_watcher.h | 8 + libs/framework/error_injector/CMakeLists.txt | 3 +- .../celix_bundle_ctx/CMakeLists.txt | 1 + .../include/celix_bundle_context_ei.h | 2 + .../src/celix_bundle_context_ei.cc | 7 + .../celix_dm_component/CMakeLists.txt | 28 ++ .../include/celix_dm_component_ei.h | 36 +++ .../src/celix_dm_component_ei.cc | 38 +++ libs/framework/include/celix_dm_component.h | 3 + 17 files changed, 747 insertions(+), 419 deletions(-) create mode 100644 libs/framework/error_injector/celix_dm_component/CMakeLists.txt create mode 100644 libs/framework/error_injector/celix_dm_component/include/celix_dm_component_ei.h create mode 100644 libs/framework/error_injector/celix_dm_component/src/celix_dm_component_ei.cc diff --git a/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt b/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt index 204119303..6581e573e 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt +++ b/bundles/remote_services/discovery_zeroconf/gtest/CMakeLists.txt @@ -64,6 +64,9 @@ if (EI_TESTS) Celix::array_list_ei Celix::properties_ei Celix::utils_ei + Celix::dm_component_ei + Celix::bundle_ctx_ei + Celix::log_helper_ei Celix::mdnsresponder_ei Celix::malloc_ei GTest::gtest diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc index 2dbb1bfc0..02d86c6bf 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc @@ -19,6 +19,10 @@ #include "discovery_zeroconf_announcer.h" #include "discovery_zeroconf_watcher.h" +#include "celix_dm_component_ei.h" +#include "celix_bundle_context_ei.h" +#include "celix_properties_ei.h" +#include "celix_log_helper_ei.h" #include "eventfd_ei.h" #include "celix_framework.h" #include "celix_framework_factory.h" @@ -41,6 +45,12 @@ class DiscoveryZeroconfActivatorTestSuite : public ::testing::Test { ~DiscoveryZeroconfActivatorTestSuite() override { celix_ei_expect_eventfd(nullptr, 0, 0); + celix_ei_expect_celix_bundleContext_getProperty(nullptr, 0, nullptr); + celix_ei_expect_celix_bundleContext_getDependencyManager(nullptr, 0, nullptr); + celix_ei_expect_celix_dmComponent_create(nullptr, 0, nullptr); + celix_ei_expect_celix_dmServiceDependency_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_create(nullptr, 0, nullptr); + celix_ei_expect_celix_logHelper_create(nullptr, 0, nullptr); } std::shared_ptr fw{}; @@ -84,6 +94,108 @@ TEST_F(DiscoveryZeroconfActivatorTestSuite, DiscoveryZeroconfWatcherCreateFailed status = celix_bundleActivator_start(act, ctx.get()); EXPECT_EQ(CELIX_ENOMEM, status); + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, GetFrameworkUuidFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_bundleContext_getProperty(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_BUNDLE_EXCEPTION, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateLogHelperFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_logHelper_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateAnnouncerDmComponentFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_dmComponent_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateAnnouncerEndpointListenerPropertiesFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_properties_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateWatcherDmComponentFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_dmComponent_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateEndpointListenerDependencyFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_dmServiceDependency_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateRsaDependencyFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_dmServiceDependency_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, GetDependencyManagerFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_ei_expect_celix_bundleContext_getDependencyManager(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); status = celix_bundleActivator_destroy(act, ctx.get()); EXPECT_EQ(CELIX_SUCCESS, status); } \ No newline at end of file diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index 344d9850f..79f4549e5 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -23,7 +23,6 @@ extern "C" { #include "endpoint_description.h" } -#include "endpoint_listener.h" #include "celix_log_helper.h" #include "celix_bundle_context.h" #include "celix_framework_factory.h" @@ -115,20 +114,6 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed2) { EXPECT_EQ(status, EINVAL); } -TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed3) { - discovery_zeroconf_announcer_t *announcer{nullptr}; - celix_ei_expect_celix_bundleContext_getProperty((void*)&discoveryZeroconfAnnouncer_create, 0, nullptr); - auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); - EXPECT_EQ(status, CELIX_BUNDLE_EXCEPTION); -} - -TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed4) { - discovery_zeroconf_announcer_t *announcer{nullptr}; - celix_ei_expect_celix_bundleContext_registerServiceWithOptionsAsync((void*)&discoveryZeroconfAnnouncer_create, 0, -1); - auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); - EXPECT_EQ(status, CELIX_BUNDLE_EXCEPTION); -} - TEST_F(DiscoveryZeroconfAnnouncerTestSuite, CreateAnnouncerFailed5) { discovery_zeroconf_announcer_t *announcer{nullptr}; celix_ei_expect_celixThread_create((void*)&discoveryZeroconfAnnouncer_create, 0, CELIX_ENOMEM); @@ -202,9 +187,9 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *instanceName, const char *regtype, const char *replyDomain, void *context) { EXPECT_NE(nullptr, sdRef); - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)context; + (void)context; EXPECT_EQ(errorCode, kDNSServiceErr_NoError); - if ((flags & kDNSServiceFlagsAdd) && (strstr(instanceName, "dzc_test_service") != nullptr) && (int)interfaceIndex == t->ifIndex) { + if ((flags & kDNSServiceFlagsAdd) && (strstr(instanceName, "dzc_test_service") != nullptr)) { DNSServiceRef dsRef{}; celix_properties_t *prop = celix_properties_create(); DNSServiceErrorType dnsErr = DNSServiceResolve(&dsRef, 0, interfaceIndex, instanceName, regtype, replyDomain, OnServiceResolveCallback, prop); @@ -219,16 +204,14 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, } } -static void OnUseServiceCallback(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); +static void TestAddEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer, int ifIndex) { + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - if (t->ifIndex == kDNSServiceInterfaceIndexAny) { + if (ifIndex == kDNSServiceInterfaceIndexAny) { celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - } else if (t->ifIndex > 0) { + } else if (ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -240,20 +223,21 @@ static void OnUseServiceCallback(void *handle, void *svc) { auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); - epl->endpointAdded(epl->handle, endpoint, nullptr); - int ifIndex = t->ifIndex; + discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); + int loopbackIfIndex = GetLoopBackIfIndex(); if (loopbackIfIndex != 0 && ifIndex == loopbackIfIndex) { // If it is a loopback interface,we will announce the service on the local only interface. ifIndex = kDNSServiceInterfaceIndexLocalOnly; } DNSServiceRef dsRef{nullptr}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, ifIndex, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, t); + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, ifIndex, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, + nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); DNSServiceRefDeallocate(dsRef); - epl->endpointRemoved(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); endpointDescription_destroy(endpoint); } @@ -262,9 +246,7 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpoint) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexAny; - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallback); - EXPECT_TRUE(found); + TestAddEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexAny); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -272,18 +254,41 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveLocalOnlyEndpoint) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexLocalOnly; - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallback); - EXPECT_TRUE(found); + TestAddEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexLocalOnly); discoveryZeroconfAnnouncer_destroy(announcer); } +TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpointOnSpecificInterface) { + discovery_zeroconf_announcer_t *announcer{}; + auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); + EXPECT_EQ(status, CELIX_SUCCESS); + int ifIndex = 0; + struct ifaddrs *ifaddr, *ifa; + char host[NI_MAXHOST]; + if (getifaddrs(&ifaddr) != -1) + { + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == nullptr) + continue; + + if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST) == 0)) { + if (strcmp(host, "127.0.0.1") != 0) { + ifIndex = (int)if_nametoindex(ifa->ifa_name); + break; + } + } + } + freeifaddrs(ifaddr); + } + TestAddEndpoint(ctx.get(), announcer, ifIndex); -static void OnUseServiceCallbackForRegisterServiceFailure(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); + discoveryZeroconfAnnouncer_destroy(announcer); +} + +static void TestAddEndPointForRegisterServiceFailure(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -295,9 +300,9 @@ static void OnUseServiceCallbackForRegisterServiceFailure(void *handle, void *sv auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); - epl->endpointAdded(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); sleep(1); - epl->endpointRemoved(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); endpointDescription_destroy(endpoint); } @@ -306,9 +311,8 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, SetTxtRecordFailed) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - celix_ei_expect_TXTRecordSetValue(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory, 2); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallbackForRegisterServiceFailure); - EXPECT_TRUE(found); + celix_ei_expect_TXTRecordSetValue(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory, 3); + TestAddEndPointForRegisterServiceFailure(ctx.get(), announcer); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -317,54 +321,7 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, FailedToRegisterService) { auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); celix_ei_expect_DNSServiceRegister(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallbackForRegisterServiceFailure); - EXPECT_TRUE(found); - discoveryZeroconfAnnouncer_destroy(announcer); -} - -static void OnUseServiceCallbackForNameConflict(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); - celix_properties_t *properties = celix_properties_create(); - if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - } else if (t->ifIndex > 0) { - char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); - } - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); - celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); - endpoint_description_t *endpoint{}; - auto status = endpointDescription_create(properties,&endpoint); - EXPECT_EQ(status, CELIX_SUCCESS); - - celix_ei_expect_DNSServiceRegister(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NameConflict); - - epl->endpointAdded(epl->handle, endpoint, nullptr); - - DNSServiceRef dsRef{nullptr}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, t->ifIndex, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, t); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - DNSServiceProcessResult(dsRef); - DNSServiceRefDeallocate(dsRef); - - epl->endpointRemoved(epl->handle, endpoint, nullptr); - - endpointDescription_destroy(endpoint); -} - -TEST_F(DiscoveryZeroconfAnnouncerTestSuite, RegisterServiceNameConflict) { - discovery_zeroconf_announcer_t *announcer{}; - auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); - EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexLocalOnly; - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallbackForNameConflict); - EXPECT_TRUE(found); + TestAddEndPointForRegisterServiceFailure(ctx.get(), announcer); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -372,10 +329,8 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, HandleMDNSEventFailed1) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexLocalOnly; celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_ServiceNotRunning); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallback); - EXPECT_TRUE(found); + TestAddEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexLocalOnly); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -383,10 +338,8 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, HandleMDNSEventFailed2) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexLocalOnly; celix_ei_expect_DNSServiceProcessResult(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_Unknown); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallback); - EXPECT_TRUE(found); + TestAddEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexLocalOnly); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -422,21 +375,18 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveLoopBackEndpoint) { auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); ifIndex = GetLoopBackIfIndex(); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceCallback); - EXPECT_TRUE(found); + TestAddEndpoint(ctx.get(), announcer, ifIndex); discoveryZeroconfAnnouncer_destroy(announcer); } -static void OnUseServiceWithJumboEndpointCallback(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); +static void TestAddJumboEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer, int ifIndex) { + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - if (t->ifIndex == kDNSServiceInterfaceIndexAny) { + if (ifIndex == kDNSServiceInterfaceIndexAny) { celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - } else if (t->ifIndex > 0) { + } else if (ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); } celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -453,15 +403,15 @@ static void OnUseServiceWithJumboEndpointCallback(void *handle, void *svc) { auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); - epl->endpointAdded(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, t); + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, NULL); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); DNSServiceRefDeallocate(dsRef); - epl->endpointRemoved(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); endpointDescription_destroy(endpoint); } @@ -470,9 +420,7 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddJumboEndpoint) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexAny; - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceWithJumboEndpointCallback); - EXPECT_TRUE(found); + TestAddJumboEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexAny); discoveryZeroconfAnnouncer_destroy(announcer); } @@ -480,23 +428,19 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddLocalOnlyJumboEndpoint) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - ifIndex = kDNSServiceInterfaceIndexLocalOnly; - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceWithJumboEndpointCallback); - EXPECT_TRUE(found); + TestAddJumboEndpoint(ctx.get(), announcer, kDNSServiceInterfaceIndexLocalOnly); discoveryZeroconfAnnouncer_destroy(announcer); } -static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; +static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { celix_status_t status; - status = epl->endpointAdded(epl->handle, nullptr, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, nullptr, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); - status = epl->endpointRemoved(epl->handle, nullptr, nullptr); + status = discoveryZeroconfAnnouncer_endpointRemoved(announcer, nullptr, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -509,15 +453,26 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { EXPECT_EQ(status, CELIX_SUCCESS); //Invalid service type - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + + //ifname not exist + celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "if_not_exist"); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); + EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + + //ifname too long + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "ifname__too__long"); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //imported config too long celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_ifname-------------------------------------------------------------------------.subtype"); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //too many imported configs @@ -528,18 +483,18 @@ static void OnUseServiceWithInvalidEndpointCallback(void *handle, void *svc) { offset += snprintf(configTypes + offset, 256 - offset, ",config_type-%d", ++i); } celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, configTypes); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //lost imported config celix_properties_unset(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //lost service name celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); celix_properties_unset(properties, CELIX_FRAMEWORK_SERVICE_NAME); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); endpointDescription_destroy(endpoint); @@ -549,22 +504,14 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddInvalidEndpoint) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceWithInvalidEndpointCallback); - EXPECT_TRUE(found); + TestAddInvalidEndpoint(ctx.get(), announcer); discoveryZeroconfAnnouncer_destroy(announcer); } -static void OnUseServiceForAddEndpointENOMEM(void *handle, void *svc) { - DiscoveryZeroconfAnnouncerTestSuite *t = (DiscoveryZeroconfAnnouncerTestSuite *)handle; - endpoint_listener_t *epl = (endpoint_listener_t *)svc; - const char *fwUuid = celix_bundleContext_getProperty(t->ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); +static void TestAddEndpointWithENOMEM(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - if (t->ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - } else if (t->ifIndex > 0) { - char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(t->ifIndex, ifName)); - } + celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); @@ -576,45 +523,45 @@ static void OnUseServiceForAddEndpointENOMEM(void *handle, void *svc) { EXPECT_EQ(status, CELIX_SUCCESS); celix_ei_expect_celix_properties_copy(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr); celix_ei_expect_celix_stringHashMap_createWithOptions(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_stringHashMap_createWithOptions(nullptr, 0, nullptr); celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 2); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_stringHashMap_put(nullptr, 0, 0); celix_ei_expect_celix_stringHashMap_putLong(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); - status = epl->endpointAdded(epl->handle, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ENOMEM); celix_ei_expect_celix_stringHashMap_putLong(nullptr, 0, 0); - epl->endpointRemoved(epl->handle, endpoint, nullptr); + discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); endpointDescription_destroy(endpoint); } @@ -623,7 +570,6 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddEndpointENOMEM) { discovery_zeroconf_announcer_t *announcer{}; auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); EXPECT_EQ(status, CELIX_SUCCESS); - auto found = celix_bundleContext_useService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE, this, OnUseServiceForAddEndpointENOMEM); - EXPECT_TRUE(found); + TestAddEndpointWithENOMEM(ctx.get(), announcer); discoveryZeroconfAnnouncer_destroy(announcer); } diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 9179918d5..24fd4b18d 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #define DZC_TEST_CONFIG_TYPE "celix.config_type.test" @@ -53,7 +53,7 @@ static const char *DZC_TEST_ENDPOINT_FW_UUID = "61EC83D5-A808-DA12-3615-B68376C3 static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *instanceName, const char *serviceType, const char *domain, void *data); -static DNSServiceRef RegisterTestService(const char *endpointId = "60f49d89-d105-430c-b12b-93fbb54b1d19", const char *serviceId = "100"); +static DNSServiceRef RegisterTestService(int ifIndex = kDNSServiceInterfaceIndexLocalOnly, const char *endpointId = "60f49d89-d105-430c-b12b-93fbb54b1d19", const char *serviceId = "100"); static const char *expectErrMsg = nullptr; static sem_t msgSyncSem; @@ -167,6 +167,37 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { celix_bundleContext_unregisterService(ctx.get(), eplId); } + long TrackRsaService(discovery_zeroconf_watcher_t *watcher) { + celix_service_tracking_options_t opts{}; + opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.filter = "(remote.configs.supported=*)"; + opts.callbackHandle = watcher; + opts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { + discoveryZeroConfWatcher_addRSA(handle, svc, props); + }; + opts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { + discoveryZeroConfWatcher_removeRSA(handle, svc, props); + }; + auto id = celix_bundleContext_trackServicesWithOptions(ctx.get(), &opts); + EXPECT_GT(id, 0); + return id; + } + + long TrackEndpointListenerService(discovery_zeroconf_watcher_t *watcher) { + celix_service_tracking_options_t opts{}; + opts.filter.serviceName = OSGI_ENDPOINT_LISTENER_SERVICE; + opts.callbackHandle = watcher; + opts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { + discoveryZeroconfWatcher_addEPL(handle, svc, props); + }; + opts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { + discoveryZeroconfWatcher_removeEPL(handle, svc, props); + }; + auto id = celix_bundleContext_trackServicesWithOptions(ctx.get(), &opts); + EXPECT_GT(id, 0); + return id; + } + void TestRsaServiceAddAndRemove(void (*beforeAddRsaAction)(void), void (*afterAddRsaAction)(void), void (*beforeRemoveRsaAction)(void) = nullptr, void (*afterRemoveRsaAction)(void) = nullptr, const char *remoteConfigsSupported = DZC_TEST_CONFIG_TYPE) { celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service @@ -174,7 +205,6 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - celix_bundleContext_waitForEvents(ctx.get()); beforeAddRsaAction(); @@ -182,6 +212,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { celix_properties_set(rsaSvcProps, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, remoteConfigsSupported); auto rsaId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", OSGI_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); EXPECT_LE(0, rsaId); + auto trkId = TrackRsaService(watcher); afterAddRsaAction(); @@ -189,6 +220,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { beforeRemoveRsaAction(); } + celix_bundleContext_stopTracker(ctx.get(), trkId); celix_bundleContext_unregisterService(ctx.get(), rsaId); if (afterRemoveRsaAction != nullptr) { @@ -199,20 +231,24 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { } - void TestAddEndpoint(void (*beforeAddEndpoint)(void), void (*afterAddEndpoint)(void)) { + void TestAddEndpoint(void (*beforeAddEndpoint)(void), void (*afterAddEndpoint)(void), int ifIndex = kDNSServiceInterfaceIndexLocalOnly) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - celix_bundleContext_waitForEvents(ctx.get()); + auto eplTrkId = TrackEndpointListenerService(watcher); beforeAddEndpoint(); - auto dsRef = RegisterTestService(); + auto rsaTrkId = TrackRsaService(watcher); + + auto dsRef = RegisterTestService(ifIndex); afterAddEndpoint(); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -220,7 +256,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - celix_bundleContext_waitForEvents(ctx.get()); + auto rsaTrkId = TrackRsaService(watcher); char txtBuf[1300] = {0}; TXTRecordRef txtRecord; @@ -234,7 +270,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { DNSServiceRef dsRef{}; DNSServiceErrorType dnsErr; dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", - DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_TEST_SERVICE_PORT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); @@ -244,6 +280,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -251,15 +288,19 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); + auto eplTrkId = TrackEndpointListenerService(watcher); beforeRegServiceAction(); - DNSServiceRef dsRef = RegisterTestService(); + DNSServiceRef dsRef = RegisterTestService(kDNSServiceInterfaceIndexAny); afterRegServiceAction(); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -307,12 +348,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed2) { EXPECT_EQ(CELIX_ENOMEM, status); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed3) { - discovery_zeroconf_watcher_t *watcher; - celix_ei_expect_celix_bundleContext_trackServicesWithOptionsAsync((void*)&discoveryZeroconfWatcher_create, 0, -1); - celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); - EXPECT_EQ(CELIX_BUNDLE_EXCEPTION, status); -} TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed4) { discovery_zeroconf_watcher_t *watcher; @@ -363,12 +398,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed10) { EXPECT_EQ(CELIX_ENOMEM, status); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateWatcherFailed11) { - discovery_zeroconf_watcher_t *watcher; - celix_ei_expect_celix_bundleContext_trackServicesWithOptionsAsync((void*)&discoveryZeroconfWatcher_create, 0, -1, 2); - celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); - EXPECT_EQ(CELIX_BUNDLE_EXCEPTION, status); -} TEST_F(DiscoveryZeroconfWatcherTestSuite, AddRsaServiceWithOutRemoteConfigsSupported) { TestRsaServiceAddAndRemove([](){ @@ -429,6 +458,14 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutBrowserEntryToCache) { }); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, AddRsaServiceWithNoNameSpaceConfigType) { + TestRsaServiceAddAndRemove([](){}, [](){}, nullptr, nullptr, "config_type_without_namespace"); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, AddRsaServiceWithMultiConfigTypes) { + TestRsaServiceAddAndRemove([](){}, [](){}, nullptr, nullptr, "celix.test1.http,celix.test1.http-json,celix.test2.http,celix.test2.http-json"); +} + static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *instanceName, const char *serviceType, const char *domain, void *data) { (void)sdRef;//unused (void)data;//unused @@ -440,7 +477,7 @@ static void OnDNSServiceRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags fl return; } -static DNSServiceRef RegisterTestService(const char *endpointId, const char *serviceId) { +static DNSServiceRef RegisterTestService(int ifIndex, const char *endpointId, const char *serviceId) { char txtBuf[1300] = {0}; TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); @@ -461,8 +498,8 @@ static DNSServiceRef RegisterTestService(const char *endpointId, const char *ser conflictCount++;//avoid conflict char name[32]={0}; snprintf(name, sizeof(name), "dzc_test_service_%d", conflictCount); - dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, name, - DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_TEST_SERVICE_PORT), + dnsErr = DNSServiceRegister(&dsRef, 0, ifIndex /*kDNSServiceInterfaceIndexAny*/, name, + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_TEST_SERVICE_PORT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); @@ -483,12 +520,13 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddMultiEndpoint) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - celix_bundleContext_waitForEvents(ctx.get()); + auto rsaTrkId = TrackRsaService(watcher); + auto eplTrkId = TrackEndpointListenerService(watcher); ExpectMsgOutPut("Endpoint added: %s."); - auto dsRef1 = RegisterTestService(); - auto dsRef2 = RegisterTestService("65d17a8c-f31b-478c-b13e-da743c96ab51", "101"); + auto dsRef1 = RegisterTestService(kDNSServiceInterfaceIndexAny); + auto dsRef2 = RegisterTestService(kDNSServiceInterfaceIndexAny, "65d17a8c-f31b-478c-b13e-da743c96ab51", "101"); //wait for endpoint1 added auto timeOut = CheckMsgWithTimeOutInS(30); @@ -512,6 +550,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddMultiEndpoint) { timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -527,6 +567,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyEndpointProperties) { TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForEndpointEntry) { TestAddEndpoint([](){ + //first calloc:service_browser_entry_t; second calloc:watched_service_entry_t; third calloc: endpointDescription_create celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); ExpectMsgOutPut("Watcher: Failed to alloc endpoint entry."); }, [](){ @@ -537,8 +578,9 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForEndpointEntry) { TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyHostNameForEndpointEntry) { TestAddEndpoint([](){ + //celix_utils_strdup call: first:addRsa; second:OnServiceResolveCallback; third: endpointDescription_create celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); - ExpectMsgOutPut("Watcher: Failed to create hostname for endpoint %s."); + ExpectMsgOutPut("Watcher: Failed to dup hostname for endpoint %s."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); @@ -548,11 +590,22 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyHostNameForEndpointEntry) TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetHostIpAddressesWhenCreateEndpoint) { TestAddEndpoint([](){ celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); - ExpectMsgOutPut("Watcher: Failed to create ip address list."); + ExpectMsgOutPut("Watcher: Failed to create endpoint for %s. %d."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }); + }, kDNSServiceInterfaceIndexAny); + sleep(2);//wait for mdnsd remove service, avoid affect other test case +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetLocalHostIpAddressesWhenCreateEndpoint) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); + ExpectMsgOutPut("Watcher: Failed to create endpoint for %s. %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }, kDNSServiceInterfaceIndexLocalOnly); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupImportedConfigsWhenCreateEndpoint) { @@ -566,7 +619,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupImportedConfigsWhenCreateEn } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutEndpointToCache) { - celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 5); + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 4); TestAddEndpoint([](){ ExpectMsgOutPut("Watcher: Failed to add endpoint for %s."); }, [](){ @@ -583,7 +636,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); //No endpoint framework uuid - ExpectMsgOutPut("Watcher: Failed to create endpoint description."); + ExpectMsgOutPut("Watcher: Failed to create endpoint description. %d."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); @@ -593,7 +646,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); @@ -609,7 +662,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); @@ -627,7 +680,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs2) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, sizeof(DZC_TEST_ENDPOINT_FW_UUID)-1, DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); @@ -650,6 +703,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateDNSServiceConnectionFailedOnce) celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); auto dsRef = RegisterTestService(); @@ -657,6 +711,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateDNSServiceConnectionFailedOnce) EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -668,6 +723,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceBrowseFailedOnce) { celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); auto dsRef = RegisterTestService(); @@ -675,12 +731,11 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceBrowseFailedOnce) { EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed1) { - celix_bundleContext_unregisterService(ctx.get(), rsaSvcId);//reset rsa service - rsaSvcId = -1; discovery_zeroconf_watcher_t *watcher; celix_ei_expect_celix_stringHashMap_create(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4); @@ -688,13 +743,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed1) { celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); - - auto dsRef = RegisterTestService(); + auto rsaTrkId = TrackRsaService(watcher); auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -706,6 +760,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed2) { celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); auto dsRef = RegisterTestService(); @@ -713,14 +768,17 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed2) { EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed3) { +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDeleteServiceBrowser) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); + auto eplTrkId = TrackEndpointListenerService(watcher); ExpectMsgOutPut("Endpoint added: %s."); @@ -732,19 +790,30 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, BrowseServicesFailed3) { celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); ExpectMsgOutPut("Watcher: Failed to put browse entry, %d."); - celix_bundleContext_unregisterService(ctx.get(), rsaSvcId); - rsaSvcId = -1; + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); discoveryZeroconfWatcher_destroy(watcher); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutWatchedServiceToCache) { + TestAddEndpoint([](){ + celix_ei_expect_celix_stringHashMap_putLong(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to cache service instance name, %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForSvcEntry) { TestAddEndpoint([](){ - celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2);//first calloc:service_browser_entry_t ExpectMsgOutPut("Watcher: Failed to alloc service entry."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); @@ -772,11 +841,33 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutSvcEntryToCache) { }); } +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToSetTxtRecordToSvcEntry) { + TestAddEndpoint([](){ + celix_ei_expect_celix_properties_set(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to set txt record item(%s), %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForSvcEntry) { + TestAddEndpoint([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + ExpectMsgOutPut("Watcher: Failed to dup hostname."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + TEST_F(DiscoveryZeroconfWatcherTestSuite, UnregisterRsaWhenBrowseServices) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); + auto eplTrkId = TrackEndpointListenerService(watcher); ExpectMsgOutPut("Endpoint added: %s."); @@ -785,10 +876,10 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, UnregisterRsaWhenBrowseServices) { auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - celix_bundleContext_unregisterService(ctx.get(), rsaSvcId); - rsaSvcId = -1; + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -802,10 +893,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResultProcessFailed1) { celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); DNSServiceRefDeallocate(dsRef); } @@ -820,10 +913,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResultProcessFailed2) { celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); DNSServiceRefDeallocate(dsRef); } @@ -832,6 +927,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResolveFailedOnce) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); celix_ei_expect_DNSServiceResolve(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory); ExpectMsgOutPut("Watcher: Failed to resolve %s on %d, %d."); @@ -841,6 +937,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceResolveFailedOnce) { EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -848,6 +945,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); char txtBuf[1300] = {0}; TXTRecordRef txtRecord; @@ -867,8 +965,9 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { ExpectMsgOutPut("Watcher: Ignore self endpoint for %s."); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_self_fw_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, - nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, + "dzc_test_self_fw_service", DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), + TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); @@ -876,6 +975,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -886,27 +986,27 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceGetAddrInfoFailedOnce) { }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }); + }, kDNSServiceInterfaceIndexAny); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForHostEntry) { TestAddEndpoint([](){ - celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 3);//first calloc:service_browser_entry_t; second calloc:watched_service_entry_t ExpectMsgOutPut("Watcher: Failed to alloc host entry for %s."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }); + }, kDNSServiceInterfaceIndexAny); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForHostEntry) { TestAddEndpoint([](){ - celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 2); - ExpectMsgOutPut("Watcher: Failed to create hostname for endpoint %s."); + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 3); + ExpectMsgOutPut("Watcher: Failed to dup hostname for %s."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }); + }, kDNSServiceInterfaceIndexAny); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { @@ -916,7 +1016,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }); + }, kDNSServiceInterfaceIndexAny); } TEST_F(DiscoveryZeroconfWatcherTestSuite, GetAddrInfo) { @@ -942,6 +1042,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); + auto eplTrkId = TrackEndpointListenerService(watcher); char txtBuf[1300] = {0}; TXTRecordRef txtRecord; @@ -960,7 +1062,9 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { ExpectMsgOutPut("Endpoint added: %s."); DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), + TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); TXTRecordDeallocate(&txtRecord); @@ -984,6 +1088,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { EXPECT_FALSE(timeOut); DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); discoveryZeroconfWatcher_destroy(watcher); } @@ -991,6 +1097,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); EXPECT_EQ(CELIX_SUCCESS, status); + auto rsaTrkId = TrackRsaService(watcher); char txtBuf[1300] = {0}; TXTRecordRef txtRecord; @@ -1006,26 +1113,40 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); - ExpectMsgOutPut("Endpoint added: %s."); - DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", DZC_TEST_SERVICE_TYPE, "local", NULL, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), + TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); + ExpectMsgOutPut("Endpoint added: %s."); + auto eplTrkId = TrackEndpointListenerService(watcher); auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - endpoint_listener_t epListener{logHelper.get(),discoveryZeroconfWatcherTest_endpointAdded, discoveryZeroconfWatcherTest_endpointRemoved}; + ExpectMsgOutPut("Endpoint removed: %s."); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + DNSServiceRefDeallocate(dsRef); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); + discoveryZeroconfWatcher_destroy(watcher); +} - long listenerId = celix_bundleContext_registerService(ctx.get(), &epListener, OSGI_ENDPOINT_LISTENER_SERVICE, nullptr); - EXPECT_LE(0, listenerId); +TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForEPL) { + discovery_zeroconf_watcher_t *watcher; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); + EXPECT_EQ(CELIX_SUCCESS, status); - timeOut = CheckMsgWithTimeOutInS(30); + ExpectMsgOutPut("Watcher: Failed to alloc endpoint listener entry."); + celix_ei_expect_calloc((void*)&discoveryZeroconfWatcher_addEPL, 0, nullptr); + auto eplTrkId = TrackEndpointListenerService(watcher); + auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - celix_bundleContext_unregisterService(ctx.get(), listenerId); + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); - DNSServiceRefDeallocate(dsRef); discoveryZeroconfWatcher_destroy(watcher); } \ No newline at end of file diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c index 239f0b1da..09802b97d 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c @@ -18,43 +18,116 @@ */ #include "discovery_zeroconf_announcer.h" #include "discovery_zeroconf_watcher.h" +#include "endpoint_listener.h" +#include "remote_constants.h" +#include "remote_service_admin.h" #include "celix_log_helper.h" #include "celix_bundle_activator.h" -#include "celix_types.h" +#include "celix_dm_component.h" +#include "celix_dm_service_dependency.h" +#include "celix_constants.h" #include "celix_errno.h" +#include +#include typedef struct discovery_zeroconf_activator { celix_log_helper_t *logHelper; discovery_zeroconf_announcer_t *announcer; discovery_zeroconf_watcher_t *watcher; + endpoint_listener_t endpointListener; }discovery_zeroconf_activator_t; celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t *act, celix_bundle_context_t *ctx) { celix_status_t status = CELIX_SUCCESS; - celix_autoptr(celix_log_helper_t) logger = celix_logHelper_create(ctx,"celix_rsa_zeroconf_discovery"); + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); + if (fwUuid == NULL) { + return CELIX_BUNDLE_EXCEPTION; + } + celix_autoptr(celix_log_helper_t) logger = celix_logHelper_create(ctx, "celix_rsa_zeroconf_discovery"); if (logger == NULL) { return CELIX_ENOMEM; } - celix_autoptr(discovery_zeroconf_announcer_t) announcer = NULL; - status = discoveryZeroconfAnnouncer_create(ctx, logger, &announcer); + //init announcer + celix_autoptr(celix_dm_component_t) announcerCmp = celix_dmComponent_create(ctx, "DZC_ANNOUNCER_CMP"); + if (announcerCmp == NULL) { + return CELIX_ENOMEM; + } + status = discoveryZeroconfAnnouncer_create(ctx, logger, &act->announcer); if (status != CELIX_SUCCESS) { return status; } - celix_autoptr(discovery_zeroconf_watcher_t) watcher = NULL; - status = discoveryZeroconfWatcher_create(ctx, logger, &watcher); + celix_dmComponent_setImplementation(announcerCmp, act->announcer); + CELIX_DM_COMPONENT_SET_IMPLEMENTATION_DESTROY_FUNCTION(announcerCmp, discovery_zeroconf_announcer_t, discoveryZeroconfAnnouncer_destroy); + celix_properties_t *props = celix_properties_create(); + if (props == NULL) { + return CELIX_ENOMEM; + } + char scope[256] = {0}; + (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, + OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(props, OSGI_ENDPOINT_LISTENER_SCOPE, scope); + celix_properties_set(props, "DISCOVERY", "true");//Only use to avoid the discovery calls to unnecessary endpoint listener service.Endpoint should be filtered by the scope. + act->endpointListener.handle = act->announcer; + act->endpointListener.endpointAdded = discoveryZeroconfAnnouncer_endpointAdded; + act->endpointListener.endpointRemoved = discoveryZeroconfAnnouncer_endpointRemoved; + celix_dmComponent_addInterface(announcerCmp, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, + &act->endpointListener, props); + + //init watcher + celix_autoptr(celix_dm_component_t) watcherCmp = celix_dmComponent_create(ctx, "DZC_WATCHER_CMP"); + if (watcherCmp == NULL) { + return CELIX_ENOMEM; + } + status = discoveryZeroconfWatcher_create(ctx, logger, &act->watcher); if (status != CELIX_SUCCESS) { return status; } - act->watcher = celix_steal_ptr(watcher); - act->announcer = celix_steal_ptr(announcer); + celix_dmComponent_setImplementation(watcherCmp, act->watcher); + CELIX_DM_COMPONENT_SET_IMPLEMENTATION_DESTROY_FUNCTION(watcherCmp, discovery_zeroconf_watcher_t, discoveryZeroconfWatcher_destroy); + { + celix_dm_service_dependency_t *discoveredEplDep = celix_dmServiceDependency_create(); + if (discoveredEplDep == NULL) { + return CELIX_ENOMEM; + } + celix_dmServiceDependency_setService(discoveredEplDep, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, "(!(DISCOVERY=true))"); + celix_dm_service_dependency_callback_options_t opts = CELIX_EMPTY_DM_SERVICE_DEPENDENCY_CALLBACK_OPTIONS; + opts.addWithProps = discoveryZeroconfWatcher_addEPL; + opts.removeWithProps = discoveryZeroconfWatcher_removeEPL; + celix_dmServiceDependency_setCallbacksWithOptions(discoveredEplDep, &opts); + celix_dmServiceDependency_setStrategy(discoveredEplDep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING); + celix_dmComponent_addServiceDependency(watcherCmp, discoveredEplDep); + } + { + celix_dm_service_dependency_t *rsaDep = celix_dmServiceDependency_create(); + if (rsaDep == NULL) { + return CELIX_ENOMEM; + } + celix_dmServiceDependency_setService(rsaDep, OSGI_RSA_REMOTE_SERVICE_ADMIN, + NULL, "(remote.configs.supported=*)"); + celix_dm_service_dependency_callback_options_t opts = CELIX_EMPTY_DM_SERVICE_DEPENDENCY_CALLBACK_OPTIONS; + opts.addWithProps = discoveryZeroConfWatcher_addRSA; + opts.removeWithProps = discoveryZeroConfWatcher_removeRSA; + celix_dmServiceDependency_setCallbacksWithOptions(rsaDep, &opts); + celix_dmServiceDependency_setStrategy(rsaDep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING); + celix_dmComponent_addServiceDependency(watcherCmp, rsaDep); + } + + celix_dependency_manager_t *mng = celix_bundleContext_getDependencyManager(ctx); + if (mng == NULL) { + return CELIX_ENOMEM; + } + celix_dependencyManager_addAsync(mng, celix_steal_ptr(announcerCmp)); + celix_dependencyManager_addAsync(mng, celix_steal_ptr(watcherCmp)); + act->logHelper = celix_steal_ptr(logger); return CELIX_SUCCESS; } celix_status_t discoveryZeroconfActivator_stop(discovery_zeroconf_activator_t *act, celix_bundle_context_t *ctx) { - (void)ctx;//unused - discoveryZeroconfWatcher_destroy(act->watcher); - discoveryZeroconfAnnouncer_destroy(act->announcer); + celix_dependency_manager_t *mng = celix_bundleContext_getDependencyManager(ctx); + assert(mng != NULL); + celix_dependencyManager_removeAllComponents(mng); + celix_bundleContext_waitForEvents(ctx); celix_logHelper_destroy(act->logHelper); return CELIX_SUCCESS; } diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index 961c37a0b..bbb1c7ff4 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -24,7 +24,6 @@ #include "celix_properties.h" #include "celix_constants.h" #include "celix_threads.h" -#include "celix_bundle_context.h" #include "celix_string_hash_map.h" #include "celix_array_list.h" #include "celix_log_helper.h" @@ -52,8 +51,6 @@ #include -#define DZC_MAX_CONFLICT_CNT 256 - //According to rfc6763, Using TXT records larger than 1300 bytes is NOT RECOMMENDED #define DZC_MAX_TXT_RECORD_SIZE 1300 @@ -64,9 +61,6 @@ struct discovery_zeroconf_announcer { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; pid_t pid; - char fwUuid[64]; - endpoint_listener_t epListener; - long epListenerSvcId; DNSServiceRef sharedRef; int eventFd; celix_thread_t refreshEPThread; @@ -85,12 +79,11 @@ typedef struct announce_endpoint_entry { const char *serviceName; char *serviceType; bool announced; + uint32_t conflictCnt; }announce_endpoint_entry_t; static void endpointEntry_destroy(announce_endpoint_entry_t *entry); static void discoveryZeroconfAnnouncer_eventNotify(discovery_zeroconf_announcer_t *announcer); -static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter); -static celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter); static void *discoveryZeroconfAnnouncer_refreshEndpointThread(void *data); @@ -138,34 +131,6 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce return CELIX_ENOMEM; } - const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); - if (fwUuid == NULL || strlen(fwUuid) >= sizeof(announcer->fwUuid)) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to get framework uuid."); - return CELIX_BUNDLE_EXCEPTION; - } - strcpy(announcer->fwUuid, fwUuid); - - announcer->epListener.handle = announcer; - announcer->epListener.endpointAdded = discoveryZeroconfAnnouncer_endpointAdded; - announcer->epListener.endpointRemoved = discoveryZeroconfAnnouncer_endpointRemoved; - char scope[256] = {0}; - (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); - - celix_properties_t *props = celix_properties_create(); - assert(props != NULL); - celix_properties_set(props, "DISCOVERY", "true"); - celix_properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); - celix_service_registration_options_t opt = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opt.serviceName = OSGI_ENDPOINT_LISTENER_SERVICE; - opt.properties = props; - opt.svc = &announcer->epListener; - announcer->epListenerSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx, &opt); - if (announcer->epListenerSvcId < 0) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to register endpoint listener."); - return CELIX_BUNDLE_EXCEPTION; - } - celix_auto(celix_service_registration_guard_t) epListenerSvcReg - = celix_serviceRegistrationGuard_init(ctx, announcer->epListenerSvcId); announcer->running = true; status = celixThread_create(&announcer->refreshEPThread, NULL, discoveryZeroconfAnnouncer_refreshEndpointThread, announcer); if (status != CELIX_SUCCESS) { @@ -174,7 +139,6 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce } celixThread_setName(&announcer->refreshEPThread, "DiscAnnouncer"); - epListenerSvcReg.svcId = -1; celix_steal_ptr(conflictCntMap); celix_steal_ptr(revokedEndpoints); celix_steal_ptr(endpoints); @@ -190,8 +154,6 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce celixThreadMutex_unlock(&announcer->mutex); discoveryZeroconfAnnouncer_eventNotify(announcer); celixThread_join(announcer->refreshEPThread, NULL); - celix_bundleContext_unregisterServiceAsync(announcer->ctx, announcer->epListenerSvcId, NULL, NULL); - celix_bundleContext_waitForAsyncUnregistration(announcer->ctx, announcer->epListenerSvcId); celix_stringHashMap_destroy(announcer->conflictCntMap); announce_endpoint_entry_t *entry = NULL; @@ -269,6 +231,7 @@ static int discoveryZeroconfAnnouncer_createEndpointEntry(discovery_zeroconf_ann } entry->registerRef = NULL; entry->announced = false; + entry->conflictCnt = 0; if (ifName != NULL) { if (strcmp(ifName, "all") == 0) { entry->ifIndex = kDNSServiceInterfaceIndexAny; @@ -323,7 +286,32 @@ static void endpointEntry_destroy(announce_endpoint_entry_t *entry) { } CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(announce_endpoint_entry_t, endpointEntry_destroy) -static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { +static int discoveryZeroconfAnnouncer_generateServiceNameConflictCnt(discovery_zeroconf_announcer_t *announcer, const char *serviceName, uint32_t *conflictCntOut) { + uint32_t conflictCnt = (uint32_t)celix_stringHashMap_getLong(announcer->conflictCntMap, serviceName, 0); + bool conflicted; + do { + conflicted = false; + conflictCnt++; + CELIX_STRING_HASH_MAP_ITERATE(announcer->endpoints, iter) { + announce_endpoint_entry_t *entry = (announce_endpoint_entry_t *)iter.value.ptrValue; + if (strcmp(entry->serviceName, serviceName) == 0 && entry->conflictCnt == conflictCnt) { + conflicted = true; + break; + } + } + }while(conflicted); + + int status = celix_stringHashMap_putLong(announcer->conflictCntMap, serviceName, conflictCnt); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to update conflict count for %s.", serviceName); + return status; + } + *conflictCntOut = conflictCnt; + return CELIX_SUCCESS; +} + +celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { (void)matchedFilter;//unused int status = CELIX_SUCCESS; discovery_zeroconf_announcer_t *announcer = (discovery_zeroconf_announcer_t *)handle; @@ -397,18 +385,14 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en } celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&announcer->mutex); - long conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); - status = celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, conflictCnt + 1); + status = discoveryZeroconfAnnouncer_generateServiceNameConflictCnt(announcer, entry->serviceName, &entry->conflictCnt); if (status != CELIX_SUCCESS) { - celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put conflict count for %s.", entry->serviceName); return status; } status = celix_stringHashMap_put(announcer->endpoints, endpoint->id, entry); if (status == CELIX_SUCCESS) { celix_steal_ptr(entry); } else { - celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, conflictCnt); celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); celix_logHelper_error(announcer->logHelper, "Announcer: Failed to put endpoint entry for %s.", endpoint->id); return status; @@ -419,7 +403,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, en return CELIX_SUCCESS; } -static celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { +celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter) { (void)matchedFilter;//unused discovery_zeroconf_announcer_t *announcer = (discovery_zeroconf_announcer_t *)handle; assert(announcer != NULL); @@ -436,6 +420,7 @@ static celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, e (void)celix_stringHashMap_remove(announcer->endpoints, endpoint->id); celix_arrayList_add(announcer->revokedEndpoints, entry); } + celix_stringHashMap_putLong(announcer->conflictCntMap, endpoint->serviceName, 0);//reset conflict count celixThreadMutex_unlock(&announcer->mutex); discoveryZeroconfAnnouncer_eventNotify(announcer); return CELIX_SUCCESS; @@ -515,61 +500,44 @@ static void discoveryZeroconfAnnouncer_announceEndpoints(discovery_zeroconf_anno continue; } - celixThreadMutex_lock(&announcer->mutex); - long conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); - celixThreadMutex_unlock(&announcer->mutex); DNSServiceErrorType dnsErr; char instanceName[64] = {0}; - bool registered = false; - int resolvedConflictCnt = 0; - DNSServiceRef dsRef; - do { - dsRef = announcer->sharedRef;//DNSServiceRegister will set a new value for dsRef - int bytes = 0; - if (conflictCnt <= 1) { - bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld", entry->serviceName, (long)announcer->pid); - } else { - bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld(%ld)", entry->serviceName, (long)announcer->pid, conflictCnt); - } - if (bytes >= sizeof(instanceName)) { - celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service name for %s.", entry->serviceName); - break; - } - celix_logHelper_info(announcer->logHelper, "Announcer: Register service %s on interface %d.", instanceName, entry->ifIndex); - dnsErr = DNSServiceRegister(&dsRef, kDNSServiceFlagsShareConnection, entry->ifIndex, instanceName, entry->serviceType, "local", NULL, htons(entry->port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, announcer); - if (dnsErr == kDNSServiceErr_NoError) { - registered = true; - } else { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to announce service, %s. %d", instanceName, dnsErr); - } - if (dnsErr == kDNSServiceErr_NameConflict) { - celixThreadMutex_lock(&announcer->mutex); - conflictCnt = celix_stringHashMap_getLong(announcer->conflictCntMap, entry->serviceName, 0); - celix_stringHashMap_putLong(announcer->conflictCntMap, entry->serviceName, ++conflictCnt); - celixThreadMutex_unlock(&announcer->mutex); - } - //LocalOnly service may be return kDNSServiceErr_NameConflict, but mDNS daemon will resolve the instance name conflicts for non-LocalOnly service - } while (dnsErr == kDNSServiceErr_NameConflict && resolvedConflictCnt++ < DZC_MAX_CONFLICT_CNT); - + DNSServiceRef dsRef = announcer->sharedRef;//DNSServiceRegister will set a new value for dsRef + int bytes = 0; + if (entry->conflictCnt <= 1) { + bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld", entry->serviceName, (long)announcer->pid); + } else { + bytes = snprintf(instanceName, sizeof(instanceName), "%s-%ld(%u)", entry->serviceName, (long)announcer->pid, entry->conflictCnt); + } + if (bytes >= sizeof(instanceName)) { + celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of service name for %s.", entry->serviceName); + TXTRecordDeallocate(&txtRecord); + continue; + } + celix_logHelper_info(announcer->logHelper, "Announcer: Register service %s on interface %d.", instanceName, entry->ifIndex); + dnsErr = DNSServiceRegister(&dsRef, kDNSServiceFlagsShareConnection, entry->ifIndex, instanceName, entry->serviceType, "local", NULL, htons(entry->port), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, announcer); + if (dnsErr != kDNSServiceErr_NoError) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to announce service, %s. %d", instanceName, dnsErr); + TXTRecordDeallocate(&txtRecord); + continue; + } TXTRecordDeallocate(&txtRecord); - if (registered) { - entry->registerRef = dsRef; - while (!celix_propertiesIterator_isEnd(&propIter)) { - TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); - if (!discoveryZeroconfAnnouncer_copyPropertiesToTxtRecord(announcer, &propIter, &txtRecord, sizeof(txtBuf), true)) { - TXTRecordDeallocate(&txtRecord); - break; - } - DNSRecordRef rdRef;//It will be free when deallocate dsRef - dnsErr = DNSServiceAddRecord(dsRef, &rdRef, 0, kDNSServiceType_TXT, TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), 0); - if (dnsErr != kDNSServiceErr_NoError) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to add record for %s. %d", instanceName, dnsErr); - TXTRecordDeallocate(&txtRecord); - break; - } + entry->registerRef = dsRef; + while (!celix_propertiesIterator_isEnd(&propIter)) { + TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); + if (!discoveryZeroconfAnnouncer_copyPropertiesToTxtRecord(announcer, &propIter, &txtRecord, sizeof(txtBuf), true)) { TXTRecordDeallocate(&txtRecord); + break; } + DNSRecordRef rdRef;//It will be free when deallocate dsRef + dnsErr = DNSServiceAddRecord(dsRef, &rdRef, 0, kDNSServiceType_TXT, TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), 0); + if (dnsErr != kDNSServiceErr_NoError) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to add record for %s. %d", instanceName, dnsErr); + TXTRecordDeallocate(&txtRecord); + break; + } + TXTRecordDeallocate(&txtRecord); } } return; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.h b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.h index f8f85923e..a34c35973 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.h +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.h @@ -22,7 +22,7 @@ #ifdef __cplusplus extern "C" { #endif - +#include "endpoint_description.h" #include "celix_cleanup.h" #include "celix_log_helper.h" #include "celix_types.h" @@ -36,6 +36,10 @@ void discoveryZeroconfAnnouncer_destroy(discovery_zeroconf_announcer_t *announce CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(discovery_zeroconf_announcer_t, discoveryZeroconfAnnouncer_destroy) +celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_description_t *endpoint, char *matchedFilter); + +celix_status_t discoveryZeroconfAnnouncer_endpointRemoved(void *handle, endpoint_description_t *endpoint, char *matchedFilter); + #ifdef __cplusplus } #endif diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 1365ab69d..21bda57e1 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -18,7 +18,6 @@ */ #include "discovery_zeroconf_watcher.h" #include "discovery_zeroconf_constants.h" -#include "remote_service_admin.h" #include "endpoint_listener.h" #include "remote_constants.h" #include "celix_bundle_context.h" @@ -57,13 +56,11 @@ struct discovery_zeroconf_watcher { celix_bundle_context_t *ctx; celix_log_helper_t *logHelper; - long epListenerTrkId; - long rsaTrkId; char fwUuid[64]; DNSServiceRef sharedRef; int eventFd; celix_thread_t watchEPThread; - celix_string_hash_map_t *watchedServices;//key:instanceName+interfaceIndex, val:watched_service_entry_t* + celix_string_hash_map_t *watchedServices;//key:instanceName+'/'+interfaceIndex, val:watched_service_entry_t* celix_string_hash_map_t *watchedHosts;//key:hostname+interfaceIndex, val:watched_host_entry_t* celix_thread_mutex_t mutex;//projects below bool running; @@ -120,10 +117,6 @@ typedef struct watched_host_entry { bool markDeleted; }watched_host_entry_t; -static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props); -static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props); -static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props); -static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props); static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context); static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *instanceName, const char *regtype, const char *replyDomain, void *context); static void *discoveryZeroconfWatcher_watchEPThread(void *data); @@ -194,36 +187,9 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi return CELIX_ENOMEM; } - celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = OSGI_ENDPOINT_LISTENER_SERVICE; - opts.filter.filter = "(!(DISCOVERY=true))"; - opts.callbackHandle = watcher; - opts.addWithProperties = discoveryZeroconfWatcher_addEPL; - opts.removeWithProperties = discoveryZeroconfWatcher_removeEPL; - watcher->epListenerTrkId = celix_bundleContext_trackServicesWithOptionsAsync(ctx, &opts); - if (watcher->epListenerTrkId < 0) { - celix_logHelper_fatal(logHelper, "Watcher: Failed to register endpoint listener service."); - return CELIX_BUNDLE_EXCEPTION; - } - - celix_service_tracking_options_t rsaOpts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - rsaOpts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; - rsaOpts.filter.filter = "(remote.configs.supported=*)"; - rsaOpts.callbackHandle = watcher; - rsaOpts.addWithProperties = discoveryZeroConfWatcher_addRSA; - rsaOpts.removeWithProperties = discoveryZeroConfWatcher_removeRSA; - watcher->rsaTrkId = celix_bundleContext_trackServicesWithOptionsAsync(ctx, &rsaOpts); - if (watcher->rsaTrkId < 0) { - celix_bundleContext_stopTracker(ctx, watcher->epListenerTrkId); - celix_logHelper_fatal(logHelper, "Watcher: Failed to register remote service admin service tracker."); - return CELIX_BUNDLE_EXCEPTION; - } - watcher->running = true; status = celixThread_create(&watcher->watchEPThread,NULL, discoveryZeroconfWatcher_watchEPThread, watcher); if (status != CELIX_SUCCESS) { - celix_bundleContext_stopTracker(ctx, watcher->rsaTrkId); - celix_bundleContext_stopTracker(ctx, watcher->epListenerTrkId); return status; } celixThread_setName(&watcher->watchEPThread, "DiscWatcher"); @@ -246,8 +212,6 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { eventfd_t val = 1; eventfd_write(watcher->eventFd, val); celixThread_join(watcher->watchEPThread, NULL); - celix_bundleContext_stopTracker(watcher->ctx, watcher->rsaTrkId); - celix_bundleContext_stopTracker(watcher->ctx, watcher->epListenerTrkId); celix_longHashMap_destroy(watcher->epls); assert(celix_stringHashMap_size(watcher->watchedServices) == 0); celix_stringHashMap_destroy(watcher->watchedServices); @@ -267,7 +231,7 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher) { return; } -static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props) { +int discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props) { assert(handle != NULL); assert(svc != NULL); assert(props != NULL); @@ -275,12 +239,13 @@ static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix endpoint_listener_t *epl = (endpoint_listener_t *)svc; long serviceId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1); if (serviceId == -1) { - return; + return CELIX_ILLEGAL_ARGUMENT; } watched_epl_entry_t *eplEntry = (watched_epl_entry_t *)calloc(1, sizeof(*eplEntry)); if (eplEntry == NULL) { - return; + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc endpoint listener entry."); + return CELIX_ENOMEM; } const char *scope = celix_properties_get(props, OSGI_ENDPOINT_LISTENER_SCOPE, NULL);//matching on empty filter is always true @@ -300,10 +265,10 @@ static void discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix celix_longHashMap_put(watcher->epls, serviceId, eplEntry); celixThreadMutex_unlock(&watcher->mutex); - return; + return CELIX_SUCCESS; } -static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props) { +int discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props) { assert(handle != NULL); assert(svc != NULL); assert(props != NULL); @@ -311,7 +276,7 @@ static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const ce endpoint_listener_t *epl = (endpoint_listener_t *)svc; long serviceId = celix_properties_getAsLong(props, CELIX_FRAMEWORK_SERVICE_ID, -1); if (serviceId == -1) { - return; + return CELIX_ILLEGAL_ARGUMENT; } celixThreadMutex_lock(&watcher->mutex); @@ -330,10 +295,10 @@ static void discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const ce } celixThreadMutex_unlock(&watcher->mutex); - return; + return CELIX_SUCCESS; } -static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props) { +int discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props) { assert(handle != NULL); assert(svc != NULL); assert(props != NULL); @@ -342,7 +307,7 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); - return; + return CELIX_ENOMEM; } bool refreshBrowsers = false; char *token = strtok(configsSupportedCopy, ","); @@ -356,7 +321,7 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix } do { size_t subTypeLen = strlen(svcSubType); - if (subTypeLen > 63) { + if (subTypeLen > 63) {//the subtype identifier is allowed to be up to 63 bytes,https://www.rfc-editor.org/rfc/rfc6763.txt#section-7.2 celix_logHelper_error(watcher->logHelper, "Watcher: Invalid service type for %s.", token); break; } @@ -400,10 +365,10 @@ static void discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix eventfd_write(watcher->eventFd, val); } - return; + return CELIX_SUCCESS; } -static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props) { +int discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props) { assert(handle != NULL); assert(svc != NULL); assert(props != NULL); @@ -412,7 +377,7 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); - return; + return CELIX_ENOMEM; } bool refreshBrowsers = false; char *token = strtok(configsSupportedCopy, ","); @@ -427,13 +392,7 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce celixThreadMutex_lock(&watcher->mutex); service_browser_entry_t *browserEntry = (service_browser_entry_t *)celix_stringHashMap_get(watcher->serviceBrowsers, svcSubType); if ((browserEntry != NULL) && (--browserEntry->refCnt == 0)) { - if (browserEntry->browseRef == NULL) {//if browser is not browsing, remove it directly, otherwise, let the watchEPThread remove it - celix_stringHashMap_remove(watcher->serviceBrowsers, svcSubType); - celix_stringHashMap_destroy(browserEntry->watchedServices);//TODO fix bug - free(browserEntry); - } else { - refreshBrowsers = true; - } + refreshBrowsers = true; } celixThreadMutex_unlock(&watcher->mutex); token = strtok(NULL, ","); @@ -444,13 +403,12 @@ static void discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const ce eventfd_write(watcher->eventFd, val); } - return; + return CELIX_SUCCESS; } static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullname, const char *host, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) { (void)sdRef;//unused (void)flags;//unused - (void)interfaceIndex;//unused (void)port;//unused (void)fullname;//unused watched_service_entry_t *svcEntry = (watched_service_entry_t *)context; @@ -491,6 +449,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, if (propSize == celix_properties_size(properties) && strcmp(DZC_CURRENT_TXT_RECORD_VERSION, version) == 0) { svcEntry->port = ntohs(port); if (svcEntry->ifIndex != kDNSServiceInterfaceIndexLocalOnly || svcEntry->port != DZC_PORT_DEFAULT) {//if it is not network service, no need to resolve ip address + free(svcEntry->hostname);//free old hostname svcEntry->hostname = celix_utils_strdup(host); if (svcEntry->hostname == NULL) { celix_logHelper_error(svcEntry->logHelper, "Watcher: Failed to dup hostname."); @@ -633,6 +592,7 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ svcEntry->resolveRef = NULL; } svcEntry->resolvedCnt = 0; + svcEntry->resolved = false; nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry resolve after 5 seconds } } @@ -770,7 +730,7 @@ static watched_host_entry_t *discoveryZeroconfWatcher_getHostEntry(discovery_zer return (watched_host_entry_t *)celix_stringHashMap_get(watcher->watchedHosts, key); } -static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { +static void discoveryZeroconfWatcher_updateWatchedHosts(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; //mark deleted hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) { @@ -802,7 +762,7 @@ static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watc celix_autofree char *hostname = hostEntry->hostname = celix_utils_strdup(svcEntry->hostname); if (hostname == NULL) { nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create hostname for endpoint %s.", svcEntry->instanceName); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup hostname for %s.", svcEntry->instanceName); continue; } hostEntry->sdRef = NULL; @@ -825,14 +785,6 @@ static void discoveryZeroconfWatcher_addHosts(discovery_zeroconf_watcher_t *watc } } } - *pNextWorkIntervalTime = nextWorkIntervalTime; - return; -} - -static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { - unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; - - discoveryZeroconfWatcher_addHosts(watcher, &nextWorkIntervalTime); //delete hosts celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedHosts); @@ -851,6 +803,15 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher } } + *pNextWorkIntervalTime = nextWorkIntervalTime; + return; +} + +static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { + unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime; + + discoveryZeroconfWatcher_updateWatchedHosts(watcher, &nextWorkIntervalTime); + //resolve hosts CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter1) { watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; @@ -902,7 +863,6 @@ static int discoveryZeroConfWatcher_getHostIpAddresses(discovery_zeroconf_watche asprintf(&tmp, "%s,%s", ipAddressesStr, ip); } if (tmp == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create ip address list."); return CELIX_ENOMEM; } free(ipAddressesStr); @@ -910,7 +870,6 @@ static int discoveryZeroConfWatcher_getHostIpAddresses(discovery_zeroconf_watche } } if (ipAddressesStr == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get ip address list."); return CELIX_ILLEGAL_STATE; } *ipAddressesStrOut = celix_steal_ptr(ipAddressesStr); @@ -926,7 +885,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_autoptr(endpoint_description_t) ep = NULL; int status = endpointDescription_create(properties, &ep); if (status != CELIX_SUCCESS) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create endpoint description."); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create endpoint description. %d.", status); return status; } celix_steal_ptr(properties);//properties now owned by ep @@ -950,7 +909,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_autofree char *hostname = epEntry->hostname = celix_utils_strdup(svcEntry->hostname); if (hostname == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create hostname for endpoint %s.", svcEntry->instanceName); + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup hostname for endpoint %s.", svcEntry->instanceName); return CELIX_ENOMEM; } @@ -1037,6 +996,18 @@ static void discoveryZeroconfWatcher_filterSameFrameWorkServices(discovery_zeroc if (epFwUuid != NULL && strcmp(epFwUuid, watcher->fwUuid) == 0) { celix_logHelper_debug(watcher->logHelper, "Watcher: Ignore self endpoint for %s.", celix_properties_get(svcEntry->txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, "unknown")); celix_stringHashMapIterator_remove(&iter); + + //remove service instance name from service browser + char instanceNameKey[128]={0}; + (void)snprintf(instanceNameKey, sizeof(instanceNameKey), "%s/%d", svcEntry->instanceName, svcEntry->ifIndex); + celixThreadMutex_lock(&watcher->mutex); + CELIX_STRING_HASH_MAP_ITERATE(watcher->serviceBrowsers, iter2) { + service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter2.value.ptrValue; + celix_stringHashMap_remove(browserEntry->watchedServices, instanceNameKey); + } + celixThreadMutex_unlock(&watcher->mutex); + + //release service info if (svcEntry->resolveRef) { DNSServiceRefDeallocate(svcEntry->resolveRef); } @@ -1069,9 +1040,8 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z int i = 0; int ipCnt = 0; while (p <= end && i < INET6_ADDRSTRLEN){ - ip[i++] = *p; - if (*p == ',' || *p == '\0') { - ip[i] = '\0'; + ip[i] = (*p == ',') ? '\0' : *p; + if (ip[i++] == '\0') { if (!celix_stringHashMap_hasKey(hostEntry->ipAddresses, ip)) { return true; } @@ -1087,6 +1057,19 @@ static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_z return false; } +static bool endpointEntry_matchServiceEntry(watched_endpoint_entry_t *epEntry, watched_service_entry_t *svcEntry) { + if (epEntry->ifIndex != svcEntry->ifIndex) { + return false; + } + if (epEntry->hostname == NULL && svcEntry->hostname == NULL) { + return true; + } + if (epEntry->hostname != NULL && svcEntry->hostname != NULL && strcmp(epEntry->hostname, svcEntry->hostname) == 0) { + return true; + } + return false; +} + static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) { watched_endpoint_entry_t *epEntry = NULL; watched_service_entry_t *svcEntry = NULL; @@ -1094,12 +1077,14 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&watcher->mutex); - //remove the endpoint which ip address list changed, and mark expired time of the endpoint. + struct timespec now = celix_gettime(CLOCK_MONOTONIC); + //remove the endpoint which ip address list changed and expired endpoint, and mark expired time of the endpoint. celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); while (!celix_stringHashMapIterator_isEnd(&epIter)) { epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; - if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry)) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Remove ip changed endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); + if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry) + || celix_compareTime(&now, &epEntry->expiredTime) >= 0) { + celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); celix_stringHashMapIterator_remove(&epIter); discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); endpointEntry_destroy(epEntry); @@ -1127,6 +1112,7 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher } else { nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds } + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create endpoint for %s. %d.", svcEntry->instanceName, status); continue; } celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); @@ -1138,29 +1124,20 @@ static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher endpointEntry_destroy(epEntry); nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds } - } else if (epEntry != NULL) { + } else if (epEntry != NULL && endpointEntry_matchServiceEntry(epEntry, svcEntry)) { epEntry->expiredTime.tv_sec = INT_MAX; epEntry->expiredTime.tv_nsec = 0; } } } - //remove expired endpoint - epIter = celix_stringHashMap_begin(watcher->watchedEndpoints); - while (!celix_stringHashMapIterator_isEnd(&epIter)) { - epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue; - int elapsed = (int)celix_elapsedtime(CLOCK_MONOTONIC, epEntry->expiredTime); - if (elapsed >= 0) { - celix_logHelper_debug(watcher->logHelper, "Watcher: Remove expired endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex); - celix_stringHashMapIterator_remove(&epIter); - discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false); - endpointEntry_destroy(epEntry); - } else { - if (epEntry->expiredTime.tv_sec != INT_MAX) { - unsigned int tmp = abs(elapsed); - nextWorkIntervalTime = nextWorkIntervalTime < tmp ? nextWorkIntervalTime : tmp; - } - celix_stringHashMapIterator_next(&epIter); + //calculate next work time + CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedEndpoints, iter) { + epEntry = (watched_endpoint_entry_t *)iter.value.ptrValue; + if (epEntry->expiredTime.tv_sec != INT_MAX) { + int timeOut = celix_difftime(&now, &epEntry->expiredTime) + 1; + assert(timeOut >= 0);//We have removed expired endpoint before. + nextWorkIntervalTime = MIN(nextWorkIntervalTime, timeOut); } } diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.h b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.h index ee9c97d15..da1b2a4e8 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.h +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.h @@ -36,6 +36,14 @@ void discoveryZeroconfWatcher_destroy(discovery_zeroconf_watcher_t *watcher); CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(discovery_zeroconf_watcher_t, discoveryZeroconfWatcher_destroy) +int discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_properties_t *props); + +int discoveryZeroconfWatcher_removeEPL(void *handle, void *svc, const celix_properties_t *props); + +int discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_properties_t *props); + +int discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_properties_t *props); + #ifdef __cplusplus } #endif diff --git a/libs/framework/error_injector/CMakeLists.txt b/libs/framework/error_injector/CMakeLists.txt index 636a68539..229a383a8 100644 --- a/libs/framework/error_injector/CMakeLists.txt +++ b/libs/framework/error_injector/CMakeLists.txt @@ -16,4 +16,5 @@ # under the License. add_subdirectory(celix_bundle_ctx) -add_subdirectory(celix_bundle) \ No newline at end of file +add_subdirectory(celix_bundle) +add_subdirectory(celix_dm_component) \ No newline at end of file diff --git a/libs/framework/error_injector/celix_bundle_ctx/CMakeLists.txt b/libs/framework/error_injector/celix_bundle_ctx/CMakeLists.txt index 33873f032..4bf883232 100644 --- a/libs/framework/error_injector/celix_bundle_ctx/CMakeLists.txt +++ b/libs/framework/error_injector/celix_bundle_ctx/CMakeLists.txt @@ -31,5 +31,6 @@ target_link_options(bundle_ctx_ei INTERFACE LINKER:--wrap,celix_bundleContext_registerServiceAsync LINKER:--wrap,celix_bundleContext_registerServiceFactoryAsync LINKER:--wrap,celix_bundleContext_scheduleEvent + LINKER:--wrap,celix_bundleContext_getDependencyManager ) add_library(Celix::bundle_ctx_ei ALIAS bundle_ctx_ei) diff --git a/libs/framework/error_injector/celix_bundle_ctx/include/celix_bundle_context_ei.h b/libs/framework/error_injector/celix_bundle_ctx/include/celix_bundle_context_ei.h index 96be32d12..0af9a8f27 100644 --- a/libs/framework/error_injector/celix_bundle_ctx/include/celix_bundle_context_ei.h +++ b/libs/framework/error_injector/celix_bundle_ctx/include/celix_bundle_context_ei.h @@ -24,6 +24,7 @@ extern "C" { #endif #include "celix_error_injector.h" #include "celix_errno.h" +#include "celix_bundle_context.h" CELIX_EI_DECLARE(celix_bundleContext_getProperty, const char*); CELIX_EI_DECLARE(celix_bundleContext_registerServiceWithOptionsAsync, long); @@ -34,6 +35,7 @@ CELIX_EI_DECLARE(bundleContext_retainServiceReference, celix_status_t); CELIX_EI_DECLARE(celix_bundleContext_registerServiceAsync, long); CELIX_EI_DECLARE(celix_bundleContext_registerServiceFactoryAsync, long); CELIX_EI_DECLARE(celix_bundleContext_scheduleEvent, long); +CELIX_EI_DECLARE(celix_bundleContext_getDependencyManager, celix_dependency_manager_t*); #ifdef __cplusplus } diff --git a/libs/framework/error_injector/celix_bundle_ctx/src/celix_bundle_context_ei.cc b/libs/framework/error_injector/celix_bundle_ctx/src/celix_bundle_context_ei.cc index 6c465e327..5319214bf 100644 --- a/libs/framework/error_injector/celix_bundle_ctx/src/celix_bundle_context_ei.cc +++ b/libs/framework/error_injector/celix_bundle_ctx/src/celix_bundle_context_ei.cc @@ -102,4 +102,11 @@ long __wrap_celix_bundleContext_scheduleEvent(celix_bundle_context_t *__ctx, con return __real_celix_bundleContext_scheduleEvent(__ctx, __options); } +celix_dependency_manager_t* __real_celix_bundleContext_getDependencyManager(celix_bundle_context_t *__ctx); +CELIX_EI_DEFINE(celix_bundleContext_getDependencyManager, celix_dependency_manager_t*) +celix_dependency_manager_t* __wrap_celix_bundleContext_getDependencyManager(celix_bundle_context_t *__ctx) { + CELIX_EI_IMPL(celix_bundleContext_getDependencyManager); + return __real_celix_bundleContext_getDependencyManager(__ctx); +} + } \ No newline at end of file diff --git a/libs/framework/error_injector/celix_dm_component/CMakeLists.txt b/libs/framework/error_injector/celix_dm_component/CMakeLists.txt new file mode 100644 index 000000000..a1e1d5ccb --- /dev/null +++ b/libs/framework/error_injector/celix_dm_component/CMakeLists.txt @@ -0,0 +1,28 @@ +# 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. + +add_library(dm_component_ei STATIC src/celix_dm_component_ei.cc) + +target_include_directories(dm_component_ei PUBLIC include) +target_link_libraries(dm_component_ei PUBLIC Celix::error_injector) +target_link_libraries(dm_component_ei PRIVATE Celix::framework) + +target_link_options(dm_component_ei INTERFACE + LINKER:--wrap,celix_dmComponent_create + LINKER:--wrap,celix_dmServiceDependency_create + ) +add_library(Celix::dm_component_ei ALIAS dm_component_ei) diff --git a/libs/framework/error_injector/celix_dm_component/include/celix_dm_component_ei.h b/libs/framework/error_injector/celix_dm_component/include/celix_dm_component_ei.h new file mode 100644 index 000000000..22b9e5216 --- /dev/null +++ b/libs/framework/error_injector/celix_dm_component/include/celix_dm_component_ei.h @@ -0,0 +1,36 @@ +/* + * 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_CELIX_DM_COMPONENT_EI_H +#define CELIX_CELIX_DM_COMPONENT_EI_H +#ifdef __cplusplus +extern "C" { +#endif +#include "celix_error_injector.h" +#include "celix_dm_component.h" +#include "celix_dm_service_dependency.h" + +CELIX_EI_DECLARE(celix_dmComponent_create, celix_dm_component_t*); +CELIX_EI_DECLARE(celix_dmServiceDependency_create, celix_dm_service_dependency_t*); + +#ifdef __cplusplus +} +#endif + +#endif //CELIX_CELIX_DM_COMPONENT_EI_H diff --git a/libs/framework/error_injector/celix_dm_component/src/celix_dm_component_ei.cc b/libs/framework/error_injector/celix_dm_component/src/celix_dm_component_ei.cc new file mode 100644 index 000000000..cb5f9ca66 --- /dev/null +++ b/libs/framework/error_injector/celix_dm_component/src/celix_dm_component_ei.cc @@ -0,0 +1,38 @@ +/* + * 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 "celix_dm_component_ei.h" +#include "celix_error_injector.h" + +extern "C" { + +celix_dm_component_t* __real_celix_dmComponent_create(bundle_context_t *context, const char* name); +CELIX_EI_DEFINE(celix_dmComponent_create, celix_dm_component_t*) +celix_dm_component_t* __wrap_celix_dmComponent_create(bundle_context_t *context, const char* name) { + CELIX_EI_IMPL(celix_dmComponent_create); + return __real_celix_dmComponent_create(context, name); +} + +celix_dm_service_dependency_t* __real_celix_dmServiceDependency_create(); +CELIX_EI_DEFINE(celix_dmServiceDependency_create, celix_dm_service_dependency_t*) +celix_dm_service_dependency_t* __wrap_celix_dmServiceDependency_create() { + CELIX_EI_IMPL(celix_dmServiceDependency_create); + return __real_celix_dmServiceDependency_create(); +} + +} \ No newline at end of file diff --git a/libs/framework/include/celix_dm_component.h b/libs/framework/include/celix_dm_component.h index 1c4a228fd..5154daef6 100644 --- a/libs/framework/include/celix_dm_component.h +++ b/libs/framework/include/celix_dm_component.h @@ -28,6 +28,7 @@ #include "celix_array_list.h" #include "celix_dm_info.h" #include "celix_framework_export.h" +#include "celix_cleanup.h" #ifdef __cplusplus extern "C" { @@ -86,6 +87,8 @@ CELIX_FRAMEWORK_EXPORT const char* celix_dmComponent_getUUID(celix_dm_component_ */ CELIX_FRAMEWORK_EXPORT void celix_dmComponent_destroy(celix_dm_component_t* cmp); +CELIX_DEFINE_AUTOPTR_CLEANUP_FUNC(celix_dm_component_t, celix_dmComponent_destroy); + /** * Destroys a DM Component on the event thread. * Will call doneCallback (if not NULL) when done. From 47366913868e424ca79638e5949c80a969b645c5 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 29 Dec 2023 16:36:49 +0800 Subject: [PATCH 20/29] Fix unit test failure --- .../DiscoveryZeroconfAnnouncerTestSuite.cc | 9 ++--- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 33 ++++++++++++++++--- .../topology_manager/tms_tst/tms_tests.cpp | 4 +++ 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index 79f4549e5..c40f91350 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -264,7 +264,6 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpointOnSpecificInterf EXPECT_EQ(status, CELIX_SUCCESS); int ifIndex = 0; struct ifaddrs *ifaddr, *ifa; - char host[NI_MAXHOST]; if (getifaddrs(&ifaddr) != -1) { for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) @@ -272,11 +271,9 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpointOnSpecificInterf if (ifa->ifa_addr == nullptr) continue; - if ((getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST) == 0)) { - if (strcmp(host, "127.0.0.1") != 0) { - ifIndex = (int)if_nametoindex(ifa->ifa_name); - break; - } + ifIndex = (int)if_nametoindex(ifa->ifa_name);// use non-loopback interface first, if not exist, use loopback interface + if (!(ifa->ifa_flags & IFF_LOOPBACK)) { + break; } } freeifaddrs(ifaddr); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 24fd4b18d..d035e2eb1 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -44,6 +44,9 @@ #include #include #include +#include +#include +#include #define DZC_TEST_CONFIG_TYPE "celix.config_type.test" #define DZC_TEST_SERVICE_TYPE DZC_SERVICE_PRIMARY_TYPE",test" //use the last word of config type as service subtype @@ -100,6 +103,26 @@ static celix_status_t discoveryZeroconfWatcherTest_endpointRemoved(void *handle return CELIX_SUCCESS; } +static int GetTestNetInterfaceIndex() { + int ifIndex = 0; + struct ifaddrs *ifaddr, *ifa; + if (getifaddrs(&ifaddr) != -1) + { + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) + { + if (ifa->ifa_addr == nullptr) + continue; + + ifIndex = (int)if_nametoindex(ifa->ifa_name);// use non-loopback interface first, if not exist, use loopback interface + if (!(ifa->ifa_flags & IFF_LOOPBACK)) { + break; + } + } + freeifaddrs(ifaddr); + } + return ifIndex; +} + class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { public: @@ -498,7 +521,7 @@ static DNSServiceRef RegisterTestService(int ifIndex, const char *endpointId, co conflictCount++;//avoid conflict char name[32]={0}; snprintf(name, sizeof(name), "dzc_test_service_%d", conflictCount); - dnsErr = DNSServiceRegister(&dsRef, 0, ifIndex /*kDNSServiceInterfaceIndexAny*/, name, + dnsErr = DNSServiceRegister(&dsRef, 0, ifIndex, name, DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_TEST_SERVICE_PORT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); @@ -594,7 +617,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetHostIpAddressesWhenCreateEn }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexAny); + }, GetTestNetInterfaceIndex()); sleep(2);//wait for mdnsd remove service, avoid affect other test case } @@ -996,7 +1019,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForHostEntry) { }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexAny); + }, GetTestNetInterfaceIndex()); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForHostEntry) { @@ -1006,7 +1029,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForHostEntry) { }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexAny); + }, GetTestNetInterfaceIndex()); } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { @@ -1016,7 +1039,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexAny); + }, GetTestNetInterfaceIndex()); } TEST_F(DiscoveryZeroconfWatcherTestSuite, GetAddrInfo) { diff --git a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp index 2636da9f8..971acb972 100644 --- a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp +++ b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp @@ -482,6 +482,7 @@ extern "C" { celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); @@ -534,6 +535,7 @@ extern "C" { celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); @@ -585,6 +587,7 @@ extern "C" { celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec celix_properties_set(props, "zone", "a_zone"); @@ -631,6 +634,7 @@ extern "C" { celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); From 4de2144a50969c09996c44904d99815ee3867639 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 29 Dec 2023 21:10:37 +0800 Subject: [PATCH 21/29] Fix unit test failure --- .../gtest/src/DiscoveryZeroconfWatcherTestSuite.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index d035e2eb1..ec0f4d300 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -1010,6 +1010,7 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceGetAddrInfoFailedOnce) { auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); }, kDNSServiceInterfaceIndexAny); + sleep(2);//wait for mdnsd remove service, avoid affect other test case } TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForHostEntry) { From 768c5c75319d67f958b7377aad28913ce2df1018 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Mon, 1 Jan 2024 13:50:19 +0800 Subject: [PATCH 22/29] Merge master --- .../gtest/src/DiscoveryZeroconfWatcherTestSuite.cc | 2 +- bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index ec0f4d300..5e5a2fd4f 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -1044,8 +1044,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { } TEST_F(DiscoveryZeroconfWatcherTestSuite, GetAddrInfo) { + ExpectMsgOutPut("Endpoint added: %s."); TestGetAddrInfo([](){ - ExpectMsgOutPut("Endpoint added: %s."); }, [](){ auto timeOut = CheckMsgWithTimeOutInS(30); EXPECT_FALSE(timeOut); diff --git a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h index 8c9027237..875b77b24 100644 --- a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h +++ b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h @@ -33,12 +33,6 @@ extern "C" { */ #define RSA_RPC_TYPE_KEY "celix.remote.admin.rpc_type" -/** - * @brief The prefix for RPC type value, and the RPC type value belongs to `service.exported.configs`. - * A whole RPC type value as follows: celix.remote.admin.rpc_type.json,celix.remote.admin.rpc_type.avpr. - */ -#define RSA_RPC_TYPE_PREFIX "celix.remote.admin.rpc_type." - #define RSA_RPC_FACTORY_NAME "rsa_rpc_factory" #define RSA_RPC_FACTORY_VERSION "1.0.0" #define RSA_RPC_FACTORY_USE_RANGE "[1.0.0,2.0.0)" From 356ec2ba3de26ab90440222124cdf408d7512040 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 19 Jan 2024 14:54:27 +0800 Subject: [PATCH 23/29] Add CELIX_RSA prefix for constants of rsa_spi --- .../discovery_common/src/discovery.c | 4 +- .../src/discovery_activator.c | 10 +-- .../src/endpoint_descriptor_writer.c | 2 +- .../DiscoveryZeroconfAnnouncerTestSuite.cc | 62 ++++++------- .../DiscoveryZeroconfIntegrationTestSuite.cc | 2 +- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 90 +++++++++---------- .../src/discovery_zeroconf_activator.c | 10 +-- .../src/discovery_zeroconf_announcer.c | 2 +- .../src/discovery_zeroconf_watcher.c | 12 +-- .../src/calculator_activator.c | 4 +- .../src/rs_interceptor_activator.c | 8 +- .../src/remote_example_activator.c | 2 +- .../src/remote_example_impl.c | 2 +- .../gtest/src/rsa_client_server_tests.cc | 12 +-- .../gtest/src/rsa_tests.cc | 24 ++--- .../src/export_registration_dfi.c | 2 +- .../src/remote_service_admin_activator.c | 4 +- .../src/remote_service_admin_dfi.c | 34 +++---- .../gtest/src/RsaShmActivatorUnitTestSuite.cc | 2 +- .../RsaShmExportRegistrationUnitTestSuite.cc | 30 +++---- .../gtest/src/RsaShmImplUnitTestSuite.cc | 36 ++++---- .../RsaShmImportRegistrationUnitTestSuite.cc | 26 +++--- .../gtest/src/RsaShmIntegrationTestSuite.cc | 2 +- .../rsa_shm/src/rsa_shm_activator.c | 4 +- .../rsa_shm/src/rsa_shm_export_registration.c | 16 ++-- .../rsa_shm/src/rsa_shm_impl.c | 32 +++---- .../rsa_shm/src/rsa_shm_import_registration.c | 10 +-- .../src/EndpointDescriptionUnitTestSuite.cc | 12 +-- .../rsa_common/src/endpoint_description.c | 10 +-- .../rsa_common/src/export_registration_impl.c | 2 +- .../rsa_common/src/import_registration_impl.c | 2 +- .../src/remote_interceptors_handler.c | 2 +- .../src/RsaJsonRpcIntegrationTestSuite.cc | 2 +- .../gtest/src/RsaJsonRpcUnitTestSuite.cc | 36 ++++---- .../RsaRequestSenderTrackerUnitTestSuite.cc | 4 +- .../rsa_rpc_json/src/rsa_json_rpc_activator.c | 6 +- .../src/rsa_json_rpc_endpoint_impl.c | 4 +- .../src/rsa_request_sender_tracker.c | 4 +- .../rsa_spi/include/endpoint_listener.h | 4 +- .../rsa_spi/include/remote_constants.h | 18 ++-- .../rsa_spi/include/remote_endpoint.h | 2 +- .../rsa_spi/include/remote_interceptor.h | 4 +- .../rsa_spi/include/remote_proxy.h | 4 +- .../rsa_spi/include/remote_service_admin.h | 2 +- .../include/rsa_request_handler_service.h | 6 +- .../include/rsa_request_sender_service.h | 6 +- .../rsa_spi/include/rsa_rpc_factory.h | 8 +- .../topology_manager/src/activator.c | 12 +-- .../topology_manager/src/topology_manager.c | 14 +-- .../topology_manager/src/topology_manager.h | 2 +- .../tms_tst/disc_mock/disc_mock_activator.c | 6 +- .../topology_manager/tms_tst/tms_tests.cpp | 38 ++++---- 52 files changed, 327 insertions(+), 327 deletions(-) diff --git a/bundles/remote_services/discovery_common/src/discovery.c b/bundles/remote_services/discovery_common/src/discovery.c index 2387cb768..1ef701f6b 100644 --- a/bundles/remote_services/discovery_common/src/discovery.c +++ b/bundles/remote_services/discovery_common/src/discovery.c @@ -89,7 +89,7 @@ celix_status_t discovery_endpointListenerAdded(void* handle, service_reference_p const char *discoveryListener = NULL; serviceReference_getProperty(reference, "DISCOVERY", &discoveryListener); const char *scope = NULL; - serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); celix_autoptr(celix_filter_t) filter = celix_filter_create(scope); @@ -166,7 +166,7 @@ celix_status_t discovery_informEndpointListeners(discovery_t *discovery, endpoin endpoint_listener_t *listener = NULL; const char* scope = NULL; - serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); celix_autoptr(celix_filter_t) filter = celix_filter_create(scope); bool matchResult = celix_filter_match(filter, endpoint->properties); diff --git a/bundles/remote_services/discovery_common/src/discovery_activator.c b/bundles/remote_services/discovery_common/src/discovery_activator.c index 0b6b591f5..0179c50f1 100644 --- a/bundles/remote_services/discovery_common/src/discovery_activator.c +++ b/bundles/remote_services/discovery_common/src/discovery_activator.c @@ -56,7 +56,7 @@ celix_status_t bundleActivator_createEPLTracker(struct activator *activator, ser discovery_endpointListenerRemoved, &customizer); if (status == CELIX_SUCCESS) { - status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker); + status = serviceTracker_create(activator->context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, customizer, tracker); } return status; @@ -103,7 +103,7 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context } char* scope = NULL; - int rc = asprintf(&scope, "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + int rc = asprintf(&scope, "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); status = rc < 0 ? CELIX_ENOMEM : CELIX_SUCCESS; celix_autoptr(celix_properties_t) props = NULL; @@ -112,7 +112,7 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context props = celix_properties_create(); celix_properties_set(props, "DISCOVERY", "true"); - celix_properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); + celix_properties_set(props, (char *) CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); } if (status == CELIX_SUCCESS) { @@ -131,8 +131,8 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context endpointListener->endpointAdded = discovery_endpointAdded; endpointListener->endpointRemoved = discovery_endpointRemoved; - status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, - celix_steal_ptr(props), &activator->endpointListenerService); + status = bundleContext_registerService(context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, endpointListener, + celix_steal_ptr(props), &activator->endpointListenerService); if (status == CELIX_SUCCESS) { activator->endpointListener = endpointListener; diff --git a/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c b/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c index 2c8d32217..df1ba91db 100644 --- a/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c +++ b/bundles/remote_services/discovery_common/src/endpoint_descriptor_writer.c @@ -147,7 +147,7 @@ static celix_status_t endpointDescriptorWriter_writeEndpoint(endpoint_descriptor if (strcmp(CELIX_FRAMEWORK_SERVICE_NAME, (char*) iter.key) == 0) { // objectClass *must* be represented as array of string values... endpointDescriptorWriter_writeArrayValue(writer->writer, propertyValue); - } else if (strcmp(OSGI_RSA_ENDPOINT_SERVICE_ID, (char*) iter.key) == 0) { + } else if (strcmp(CELIX_RSA_ENDPOINT_SERVICE_ID, (char*) iter.key) == 0) { // endpoint.service.id *must* be represented as long value... endpointDescriptorWriter_writeTypedValue(writer->writer, VALUE_TYPE_LONG, propertyValue); } else { diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index c40f91350..925f46623 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -213,12 +213,12 @@ static void TestAddEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announ char ifName[IF_NAMESIZE] = {0}; celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); } - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -287,12 +287,12 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpointOnSpecificInterf static void TestAddEndPointForRegisterServiceFailure(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -385,12 +385,12 @@ static void TestAddJumboEndpoint(celix_bundle_context *ctx, discovery_zeroconf_a char ifName[IF_NAMESIZE] = {0}; celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); } - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); for (int i = 0; i < 500; ++i) { char key[20]{}; sprintf(key,"custom_key%d", i); @@ -439,12 +439,12 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.invalid_service_type_because_the_size_large_than_64_----------------"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.invalid_service_type_because_the_size_large_than_64_----------------"); endpoint_description_t *endpoint{}; status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); @@ -454,7 +454,7 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //ifname not exist - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "if_not_exist"); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); @@ -465,10 +465,10 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //imported config too long - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_ifname-------------------------------------------------------------------------.subtype"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_ifname-------------------------------------------------------------------------.subtype"); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); @@ -479,17 +479,17 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf while (offset < 256) { offset += snprintf(configTypes + offset, 256 - offset, ",config_type-%d", ++i); } - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, configTypes); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, configTypes); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //lost imported config - celix_properties_unset(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + celix_properties_unset(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //lost service name - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); celix_properties_unset(properties, CELIX_FRAMEWORK_SERVICE_NAME); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); @@ -509,12 +509,12 @@ static void TestAddEndpointWithENOMEM(celix_bundle_context *ctx, discovery_zeroc const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); endpoint_description_t *endpoint{}; auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfIntegrationTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfIntegrationTestSuite.cc index 704b28cce..c91b571f0 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfIntegrationTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfIntegrationTestSuite.cc @@ -44,6 +44,6 @@ class DiscoveryZeroconfIntegrationTestSuite : public ::testing::Test { }; TEST_F(DiscoveryZeroconfIntegrationTestSuite, FindEndpointListener) { - auto found = celix_bundleContext_findService(ctx.get(), OSGI_ENDPOINT_LISTENER_SERVICE); + auto found = celix_bundleContext_findService(ctx.get(), CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME); EXPECT_TRUE(found); } diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 5e5a2fd4f..e2e2afe57 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -146,11 +146,11 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { auto* logHelperPtr = celix_logHelper_create(ctxPtr,"DiscoveryZeroconf"); logHelper = std::shared_ptr{logHelperPtr, [](auto*l){ celix_logHelper_destroy(l);}}; epListener.handle = logHelperPtr; - eplId = celix_bundleContext_registerService(ctxPtr, &epListener, OSGI_ENDPOINT_LISTENER_SERVICE, nullptr); + eplId = celix_bundleContext_registerService(ctxPtr, &epListener, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, nullptr); EXPECT_LE(0, eplId); auto rsaSvcProps = celix_properties_create(); - celix_properties_set(rsaSvcProps, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, DZC_TEST_CONFIG_TYPE); - rsaSvcId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", OSGI_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); + celix_properties_set(rsaSvcProps, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, DZC_TEST_CONFIG_TYPE); + rsaSvcId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", CELIX_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); EXPECT_LE(0, rsaSvcId); logService.handle = nullptr; logService.vlogDetails = vlogDetails; @@ -192,7 +192,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { long TrackRsaService(discovery_zeroconf_watcher_t *watcher) { celix_service_tracking_options_t opts{}; - opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; opts.filter.filter = "(remote.configs.supported=*)"; opts.callbackHandle = watcher; opts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { @@ -208,7 +208,7 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { long TrackEndpointListenerService(discovery_zeroconf_watcher_t *watcher) { celix_service_tracking_options_t opts{}; - opts.filter.serviceName = OSGI_ENDPOINT_LISTENER_SERVICE; + opts.filter.serviceName = CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME; opts.callbackHandle = watcher; opts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *props) { discoveryZeroconfWatcher_addEPL(handle, svc, props); @@ -232,8 +232,8 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { beforeAddRsaAction(); auto rsaSvcProps = celix_properties_create(); - celix_properties_set(rsaSvcProps, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, remoteConfigsSupported); - auto rsaId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", OSGI_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); + celix_properties_set(rsaSvcProps, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, remoteConfigsSupported); + auto rsaId = celix_bundleContext_registerService(ctx.get(), (void*)"dummy_service", CELIX_RSA_REMOTE_SERVICE_ADMIN, rsaSvcProps); EXPECT_LE(0, rsaId); auto trkId = TrackRsaService(watcher); @@ -505,12 +505,12 @@ static DNSServiceRef RegisterTestService(int ifIndex, const char *endpointId, co TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen(endpointId), endpointId); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen(serviceId), serviceId); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_ID, strlen(endpointId), endpointId); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, strlen(serviceId), serviceId); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED, strlen("true"), "true"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE) - 1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); @@ -654,10 +654,10 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutEndpointToCache) { TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "-1"); - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "-1"); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); //No endpoint framework uuid ExpectMsgOutPut("Watcher: Failed to create endpoint description. %d."); }, [](){ @@ -669,11 +669,11 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); //NO imported configs ExpectMsgOutPut("Watcher: No imported configs."); }, [](){ @@ -685,13 +685,13 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); const char *invalidImportedConfigs = "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"; - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); }, [](){ @@ -703,13 +703,13 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs2) { TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); + TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); const char *invalidImportedConfigs = "celix.imported_config_too_long_for_ipaddresses--------------------------------------------------------------------.subtype"; - TXTRecordSetValue(txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); + TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); }, [](){ @@ -975,12 +975,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); const char *fwUuid = celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid == nullptr ? 0 : strlen(fwUuid), fwUuid); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid == nullptr ? 0 : strlen(fwUuid), fwUuid); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_self_fw_service"), "dzc_test_self_fw_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED, strlen("true"), "true"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); @@ -1073,12 +1073,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d18"), "60f49d89-d105-430c-b12b-93fbb54b1d18"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d18"), "60f49d89-d105-430c-b12b-93fbb54b1d18"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED, strlen("true"), "true"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1 + 5); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); @@ -1127,12 +1127,12 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { TXTRecordRef txtRecord; TXTRecordCreate(&txtRecord, sizeof(txtBuf), txtBuf); TXTRecordSetValue(&txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); TXTRecordSetValue(&txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, strlen("dzc_test_service"), "dzc_test_service"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED, strlen("true"), "true"); - TXTRecordSetValue(&txtRecord, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_ID, strlen("60f49d89-d105-430c-b12b-93fbb54b1d19"), "60f49d89-d105-430c-b12b-93fbb54b1d19"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, strlen("100"), "100"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED, strlen("true"), "true"); + TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE)-1, DZC_TEST_CONFIG_TYPE); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c index 09802b97d..222d25130 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c @@ -64,13 +64,13 @@ celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t * } char scope[256] = {0}; (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, - OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); - celix_properties_set(props, OSGI_ENDPOINT_LISTENER_SCOPE, scope); + CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(props, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); celix_properties_set(props, "DISCOVERY", "true");//Only use to avoid the discovery calls to unnecessary endpoint listener service.Endpoint should be filtered by the scope. act->endpointListener.handle = act->announcer; act->endpointListener.endpointAdded = discoveryZeroconfAnnouncer_endpointAdded; act->endpointListener.endpointRemoved = discoveryZeroconfAnnouncer_endpointRemoved; - celix_dmComponent_addInterface(announcerCmp, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, + celix_dmComponent_addInterface(announcerCmp, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, NULL, &act->endpointListener, props); //init watcher @@ -89,7 +89,7 @@ celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t * if (discoveredEplDep == NULL) { return CELIX_ENOMEM; } - celix_dmServiceDependency_setService(discoveredEplDep, OSGI_ENDPOINT_LISTENER_SERVICE, NULL, "(!(DISCOVERY=true))"); + celix_dmServiceDependency_setService(discoveredEplDep, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, NULL, "(!(DISCOVERY=true))"); celix_dm_service_dependency_callback_options_t opts = CELIX_EMPTY_DM_SERVICE_DEPENDENCY_CALLBACK_OPTIONS; opts.addWithProps = discoveryZeroconfWatcher_addEPL; opts.removeWithProps = discoveryZeroconfWatcher_removeEPL; @@ -102,7 +102,7 @@ celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t * if (rsaDep == NULL) { return CELIX_ENOMEM; } - celix_dmServiceDependency_setService(rsaDep, OSGI_RSA_REMOTE_SERVICE_ADMIN, + celix_dmServiceDependency_setService(rsaDep, CELIX_RSA_REMOTE_SERVICE_ADMIN, NULL, "(remote.configs.supported=*)"); celix_dm_service_dependency_callback_options_t opts = CELIX_EMPTY_DM_SERVICE_DEPENDENCY_CALLBACK_OPTIONS; opts.addWithProps = discoveryZeroConfWatcher_addRSA; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index bbb1c7ff4..736b583d0 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -323,7 +323,7 @@ celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_d celix_logHelper_info(announcer->logHelper, "Announcer: Add endpoint for %s(%s).", endpoint->serviceName, endpoint->id); - const char *importedConfigs = celix_properties_get(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importedConfigs = celix_properties_get(endpoint->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); if (importedConfigs == NULL) { celix_logHelper_error(announcer->logHelper, "Announcer: No imported configs for %s.", endpoint->serviceName); return CELIX_ILLEGAL_ARGUMENT; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 21bda57e1..7071ce09c 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -248,7 +248,7 @@ int discoveryZeroconfWatcher_addEPL(void *handle, void *svc, const celix_propert return CELIX_ENOMEM; } - const char *scope = celix_properties_get(props, OSGI_ENDPOINT_LISTENER_SCOPE, NULL);//matching on empty filter is always true + const char *scope = celix_properties_get(props, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, NULL);//matching on empty filter is always true celix_filter_t *filter = scope == NULL ? NULL : celix_filter_create(scope); celixThreadMutex_lock(&watcher->mutex); @@ -303,7 +303,7 @@ int discoveryZeroConfWatcher_addRSA(void *handle, void *svc, const celix_propert assert(svc != NULL); assert(props != NULL); discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; - const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); + const char *configsSupported = celix_properties_get(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); @@ -373,7 +373,7 @@ int discoveryZeroConfWatcher_removeRSA(void *handle, void *svc, const celix_prop assert(svc != NULL); assert(props != NULL); discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)handle; - const char *configsSupported = celix_properties_get(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); + const char *configsSupported = celix_properties_get(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, NULL); celix_autofree char *configsSupportedCopy = celix_utils_strdup(configsSupported); if (configsSupportedCopy == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup remote configs supported."); @@ -442,7 +442,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, return; } } - svcEntry->endpointId = celix_properties_get(properties, OSGI_RSA_ENDPOINT_ID, NULL); + svcEntry->endpointId = celix_properties_get(properties, CELIX_RSA_ENDPOINT_ID, NULL); long propSize = celix_properties_getAsLong(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0); const char *version = celix_properties_get(properties, DZC_TXT_RECORD_VERSION_KEY, ""); @@ -919,7 +919,7 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero return status; } - const char *importedConfigs = celix_properties_get(ep->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importedConfigs = celix_properties_get(ep->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); if (importedConfigs == NULL) { celix_logHelper_error(watcher->logHelper, "Watcher: No imported configs."); return CELIX_ILLEGAL_ARGUMENT; @@ -992,7 +992,7 @@ static void discoveryZeroconfWatcher_filterSameFrameWorkServices(discovery_zeroc while (!celix_stringHashMapIterator_isEnd(&iter)) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; if (svcEntry->resolved) { - const char *epFwUuid = celix_properties_get(svcEntry->txtRecord, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); + const char *epFwUuid = celix_properties_get(svcEntry->txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); if (epFwUuid != NULL && strcmp(epFwUuid, watcher->fwUuid) == 0) { celix_logHelper_debug(watcher->logHelper, "Watcher: Ignore self endpoint for %s.", celix_properties_get(svcEntry->txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, "unknown")); celix_stringHashMapIterator_remove(&iter); diff --git a/bundles/remote_services/examples/calculator_service/src/calculator_activator.c b/bundles/remote_services/examples/calculator_service/src/calculator_activator.c index 261169e0e..30ab57dca 100644 --- a/bundles/remote_services/examples/calculator_service/src/calculator_activator.c +++ b/bundles/remote_services/examples/calculator_service/src/calculator_activator.c @@ -40,9 +40,9 @@ celix_status_t calculatorBndStart(struct activator *act, celix_bundle_context_t act->service.sqrt = (void*)calculator_sqrt; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, CALCULATOR_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, CALCULATOR_CONFIGURATION_TYPE); act->svcId = celix_bundleContext_registerService(ctx, &act->service, CALCULATOR_SERVICE, properties); } diff --git a/bundles/remote_services/examples/interceptors/src/rs_interceptor_activator.c b/bundles/remote_services/examples/interceptors/src/rs_interceptor_activator.c index d580ca41b..79c7ef6dd 100644 --- a/bundles/remote_services/examples/interceptors/src/rs_interceptor_activator.c +++ b/bundles/remote_services/examples/interceptors/src/rs_interceptor_activator.c @@ -55,8 +55,8 @@ static int interceptor_start(struct interceptorActivator *act, celix_bundle_cont celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; opts.svc = interceptorSvc; - opts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - opts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; opts.properties = props; act->interceptorSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &opts); @@ -79,8 +79,8 @@ static int interceptor_start(struct interceptorActivator *act, celix_bundle_cont celix_service_registration_options_t secondOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; secondOpts.svc = secondInterceptorSvc; - secondOpts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - secondOpts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + secondOpts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + secondOpts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; secondOpts.properties = secondProps; act->secondInterceptorSvcId = celix_bundleContext_registerServiceWithOptions(ctx, &secondOpts); diff --git a/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c b/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c index 59522e30d..461bccf30 100644 --- a/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c +++ b/bundles/remote_services/examples/remote_example_service/src/remote_example_activator.c @@ -45,7 +45,7 @@ celix_status_t remoteExampleBndStart(struct activator *act, celix_bundle_context act->service.createAdditionalRemoteService = (void*)remoteExample_createAdditionalRemoteService; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, REMOTE_EXAMPLE_NAME); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, REMOTE_EXAMPLE_NAME); act->svcId = celix_bundleContext_registerService(ctx, &act->service, REMOTE_EXAMPLE_NAME, properties); } return CELIX_SUCCESS; diff --git a/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c index f462d3427..3a95ff610 100644 --- a/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c +++ b/bundles/remote_services/examples/remote_example_service/src/remote_example_impl.c @@ -160,7 +160,7 @@ int remoteExample_createAdditionalRemoteService(remote_example_impl_t* impl) { fprintf(stdout, "additional remote already created\n"); } else { celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, REMOTE_EXAMPLE_NAME); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, REMOTE_EXAMPLE_NAME); long newSvcId = celix_bundleContext_registerService(impl->ctx, &impl->additionalSvc, REMOTE_EXAMPLE_NAME, properties); pthread_mutex_lock(&impl->mutex); prevSvcId = impl->additionalSvcId; diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc index 919075ac4..28c84013d 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc @@ -88,8 +88,8 @@ typedef struct rsa_dfi_exception_test_service { static void registerExceptionTestServer(void) { celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_DIF_EXCEPTION_TEST_SERVICE); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, "org.amdatu.remote.admin.http"); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, RSA_DIF_EXCEPTION_TEST_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, "org.amdatu.remote.admin.http"); exceptionTestService = (rsa_dfi_exception_test_service_t *)calloc(1,sizeof(*exceptionTestService)); exceptionTestService->handle = NULL; exceptionTestService->func1 = rsaDfi_excepTestFunc1; @@ -145,8 +145,8 @@ typedef struct rsa_dfi_exception_test_service { celix_properties_setLong(svcInterceptorProps, CELIX_FRAMEWORK_SERVICE_RANKING, 10); celix_service_registration_options_t svcInterceptorOpts{}; svcInterceptorOpts.svc = serverSvcInterceptor; - svcInterceptorOpts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - svcInterceptorOpts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + svcInterceptorOpts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + svcInterceptorOpts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; svcInterceptorOpts.properties = svcInterceptorProps; serverSvcInterceptorSvcId = celix_bundleContext_registerServiceWithOptions(serverContext, &svcInterceptorOpts); @@ -161,8 +161,8 @@ typedef struct rsa_dfi_exception_test_service { celix_properties_setLong(clientInterceptorProps, CELIX_FRAMEWORK_SERVICE_RANKING, 10); celix_service_registration_options_t clientInterceptorOpts{}; clientInterceptorOpts.svc = clientSvcInterceptor; - clientInterceptorOpts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - clientInterceptorOpts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + clientInterceptorOpts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + clientInterceptorOpts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; clientInterceptorOpts.properties = clientInterceptorProps; clientSvcInterceptorSvcId = celix_bundleContext_registerServiceWithOptions(clientContext, &clientInterceptorOpts); } diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc index b905f0119..bc5887f13 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc @@ -74,7 +74,7 @@ extern "C" { static void testServices(void) { celix_service_use_options_t opts{}; - opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; opts.use = testServicesCallback; opts.waitTimeoutInSeconds = 0.25; bool called = celix_bundleContext_useServiceWithOptions(context, &opts); @@ -101,7 +101,7 @@ extern "C" { static void testExportService(void) { celix_service_use_options_t opts{}; - opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; opts.use = testExportServiceCallback; opts.waitTimeoutInSeconds = 0.25; bool called = celix_bundleContext_useServiceWithOptions(context, &opts); @@ -114,10 +114,10 @@ extern "C" { if (init) { auto *rsa = static_cast(svc); celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8888/service/42/org.apache.celix.Example"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.Example"); @@ -138,7 +138,7 @@ extern "C" { static void testImportService(void) { celix_service_use_options_t opts{}; - opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; opts.use = testImportServiceCallback; opts.waitTimeoutInSeconds = 0.25; @@ -161,10 +161,10 @@ extern "C" { if (init) { auto *rsa = static_cast(svc); celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "celix.remote.admin.dfi.zeroconf.http"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.remote.admin.dfi.zeroconf.http"); celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.port", "8888"); celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.ipaddresses", "127.0.0.1"); celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.path", "/service/42/org.apache.celix.Example"); @@ -187,7 +187,7 @@ extern "C" { static void testImportServiceForZeroconfConfigType(void) { celix_service_use_options_t opts{}; - opts.filter.serviceName = OSGI_RSA_REMOTE_SERVICE_ADMIN; + opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; opts.use = testImportServiceCallbackForZeroconfConfigType; opts.waitTimeoutInSeconds = 0.25; diff --git a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c index ff45b0bea..f3b615899 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c @@ -98,7 +98,7 @@ celix_status_t exportRegistration_create(celix_log_helper_t *helper, service_ref } const char *exports = NULL; - CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &exports)); + CELIX_DO_IF(status, serviceReference_getProperty(reference, (char *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &exports)); celix_bundle_t *bundle = NULL; CELIX_DO_IF(status, serviceReference_getBundle(reference, &bundle)); diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c index 3d0e78aa3..6102fa6b5 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c @@ -38,7 +38,7 @@ static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* ac if (props == NULL) { return CELIX_ENOMEM; } - status = celix_properties_set(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); + status = celix_properties_set(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); if (status != CELIX_SUCCESS) { return status; } @@ -65,7 +65,7 @@ static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* ac activator->adminService.importRegistration_getException = importRegistration_getException; activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference; - activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, OSGI_RSA_REMOTE_SERVICE_ADMIN, + activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, CELIX_RSA_REMOTE_SERVICE_ADMIN, celix_steal_ptr(props)); } 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 index 103a3ea81..e94c9f4fd 100644 --- 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 @@ -117,8 +117,8 @@ struct celix_get_data_reply { size_t size; }; -#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory" -#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout" +#define CELIX_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory" +#define CELIX_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout" static const char *data_response_headers = "HTTP/1.1 200 OK\r\n" @@ -569,7 +569,7 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_t *admin, c celix_status_t status = CELIX_SUCCESS; bool export = false; - const char *exportConfigs = celix_properties_get(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_DFI_CONFIGURATION_TYPE); + const char *exportConfigs = celix_properties_get(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_DFI_CONFIGURATION_TYPE); if (exportConfigs != NULL) { // See if the EXPORT_CONFIGS matches this RSA. If so, try to export. @@ -625,7 +625,7 @@ celix_status_t remoteServiceAdmin_exportService(remote_service_admin_t *admin, c 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 *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &exports); serviceReference_getProperty(reference, (char *) CELIX_FRAMEWORK_SERVICE_NAME, &provided); if (exports == NULL || provided == NULL || strcmp(exports, provided) != 0) { @@ -726,8 +726,8 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic 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_RSA_SERVICE_EXPORTED_CONFIGS) != 0 + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_INTERFACES) != 0 + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_CONFIGS) != 0 && strcmp(key, (char*) CELIX_FRAMEWORK_SERVICE_NAME) != 0) { celix_properties_set(endpointProperties, key, value); } @@ -748,12 +748,12 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic uuid_unparse_lower(endpoint_uid, endpoint_uuid); bundleContext_getProperty(admin->context, CELIX_FRAMEWORK_UUID, &uuid); - celix_properties_set(endpointProperties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + celix_properties_set(endpointProperties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); celix_properties_set(endpointProperties, CELIX_FRAMEWORK_SERVICE_NAME, interface); - celix_properties_set(endpointProperties, OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId); - celix_properties_set(endpointProperties, OSGI_RSA_ENDPOINT_ID, endpoint_uuid); - celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, (char*) RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); + celix_properties_set(endpointProperties, CELIX_RSA_ENDPOINT_SERVICE_ID, serviceId); + celix_properties_set(endpointProperties, CELIX_RSA_ENDPOINT_ID, endpoint_uuid); + celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, (char*) RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); celix_properties_set(endpointProperties, RSA_DFI_ENDPOINT_URL, url); if (admin->discoveryInterface != NULL) { celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IFNAME, admin->discoveryInterface); @@ -771,9 +771,9 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic if (!*endpoint) { status = CELIX_ENOMEM; } else { - (*endpoint)->id = (char*) celix_properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, NULL); + (*endpoint)->id = (char*) celix_properties_get(endpointProperties, (char*) CELIX_RSA_ENDPOINT_ID, NULL); (*endpoint)->serviceId = serviceReference_getServiceId(reference); - (*endpoint)->frameworkUUID = (char*) celix_properties_get(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); + (*endpoint)->frameworkUUID = (char*) celix_properties_get(endpointProperties, (char*) CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); (*endpoint)->serviceName = strndup(interface, 1024*10); (*endpoint)->properties = endpointProperties; } @@ -901,7 +901,7 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, e celix_status_t status = CELIX_SUCCESS; bool importService = false; - const char *importConfigs = celix_properties_get(endpointDescription->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importConfigs = celix_properties_get(endpointDescription->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); if (importConfigs != NULL) { // Check whether this RSA must be imported char *ecCopy = strndup(importConfigs, strlen(importConfigs)); @@ -921,7 +921,7 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, e free(ecCopy); } else { celix_logHelper_log(admin->loghelper, CELIX_LOG_LEVEL_WARNING, "Mandatory %s element missing from endpoint description", - OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + CELIX_RSA_SERVICE_IMPORTED_CONFIGS); } if (importService) { @@ -1036,10 +1036,10 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description const char *timeoutStr = NULL; // Check if the endpoint has a timeout, if so, use it. - timeoutStr = (char*) celix_properties_get(endpointDescription->properties, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, NULL); + timeoutStr = (char*) celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_REMOTE_PROXY_TIMEOUT, NULL); if (timeoutStr == NULL) { // If not, get the global variable and use that one. - bundleContext_getProperty(rsa->context, (char*) OSGI_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr); + bundleContext_getProperty(rsa->context, (char*) CELIX_RSA_REMOTE_PROXY_TIMEOUT, &timeoutStr); } // Update timeout if a property is used to set it. diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc index 4ae275c6e..d680b706b 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmActivatorUnitTestSuite.cc @@ -58,7 +58,7 @@ TEST_F(RsaShmActivatorUnitTestSuite, RsaShmActivatorStart) { status = celix_bundleActivator_start(userData, ctx.get()); EXPECT_EQ(status, CELIX_SUCCESS); - bool found = celix_bundleContext_findService(ctx.get(), OSGI_RSA_REMOTE_SERVICE_ADMIN); + bool found = celix_bundleContext_findService(ctx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN); EXPECT_TRUE(found); status = celix_bundleActivator_stop(userData, ctx.get()); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc index 8992bda43..9c8c0d15b 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmExportRegistrationUnitTestSuite.cc @@ -56,8 +56,8 @@ static celix_status_t RpcFacCreateEndpoint(void *handle, const endpoint_descript }; celix_service_registration_options_t opts{}; opts.svc = &requestHandler; - opts.serviceName = RSA_REQUEST_HANDLER_SERVICE_NAME; - opts.serviceVersion = RSA_REQUEST_HANDLER_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REQUEST_HANDLER_SERVICE_VERSION; auto svcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx, &opts); EXPECT_GE(svcId, 0); *requestHandlerSvcId = svcId; @@ -91,9 +91,9 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { return CELIX_SUCCESS; }; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); calcSvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); EXPECT_GE(calcSvcId, 0); @@ -106,9 +106,9 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { rpcFactory.destroyEndpoint = RpcFacDestroyEndpoint; celix_properties_t *rpcFacProps = celix_properties_create(); - celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); - rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, RSA_RPC_FACTORY_NAME, rpcFacProps); + celix_properties_set(rpcFacProps, CELIX_RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); + celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, CELIX_RSA_RPC_FACTORY_VERSION); + rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, CELIX_RSA_RPC_FACTORY_NAME, rpcFacProps); EXPECT_GE(rpcFactorySvcId, 1); celix_bundleContext_waitForEvents(ctx.get()); @@ -131,12 +131,12 @@ class RsaShmExportRegUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); - celix_properties_setLong(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, calcSvcId); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, "")); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); + celix_properties_setLong(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, calcSvcId); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, "")); celix_properties_set(properties, RSA_SHM_SERVER_NAME_KEY, "ShmServ-dummy"); endpoint_description_t *endpoint = nullptr; auto status = endpointDescription_create(properties, &endpoint); @@ -301,9 +301,9 @@ TEST_F(RsaShmExportRegUnitTestSuite, RegisterMoreThanOneRpcFactory) { //register another rpc factory celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); - auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", RSA_RPC_FACTORY_NAME, props); + celix_properties_set(props, CELIX_RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); + celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, CELIX_RSA_RPC_FACTORY_VERSION); + auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", CELIX_RSA_RPC_FACTORY_NAME, props); EXPECT_GE(svcId, 1); celix_bundleContext_waitForEvents(ctx.get()); celix_bundleContext_unregisterServiceAsync(ctx.get(), svcId, nullptr, nullptr); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc index fd92e6d36..e602ee9ee 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImplUnitTestSuite.cc @@ -81,9 +81,9 @@ class RsaShmUnitTestSuite : public ::testing::Test { calcService.handle = nullptr, calcService.add = calculator_add; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); calcSvcId = celix_bundleContext_registerService(ctx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); @@ -97,12 +97,12 @@ class RsaShmUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, "1234"); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "0a068612-9f95-4f1b-bf0b-ffa6916dae12"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, "1234"); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "0a068612-9f95-4f1b-bf0b-ffa6916dae12"); celix_properties_set(properties, RSA_SHM_SERVER_NAME_KEY, "ShmServ-dummy"); endpoint_description_t *endpoint = nullptr; auto status = endpointDescription_create(properties, &endpoint); @@ -219,10 +219,10 @@ TEST_F(RsaShmUnitTestSuite, ExportService) { status = exportReference_getExportedEndpoint(ref, &endpoint); EXPECT_EQ(CELIX_SUCCESS, status); EXPECT_STREQ("AdditionValue", celix_properties_get(endpoint->properties, "AdditionKey", nullptr)); - EXPECT_EQ(nullptr, celix_properties_get(endpoint->properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, nullptr)); + EXPECT_EQ(nullptr, celix_properties_get(endpoint->properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, nullptr)); EXPECT_STREQ(RSA_SHM_CALCULATOR_SERVICE, celix_properties_get(endpoint->properties, CELIX_FRAMEWORK_SERVICE_NAME, nullptr)); - EXPECT_STREQ("true", celix_properties_get(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED, nullptr)); - EXPECT_EQ(calcSvcId, celix_properties_getAsLong(endpoint->properties, OSGI_RSA_ENDPOINT_SERVICE_ID, -1)); + EXPECT_STREQ("true", celix_properties_get(endpoint->properties, CELIX_RSA_SERVICE_IMPORTED, nullptr)); + EXPECT_EQ(calcSvcId, celix_properties_getAsLong(endpoint->properties, CELIX_RSA_ENDPOINT_SERVICE_ID, -1)); free(ref); status = rsaShm_removeExportedService(admin, reg); @@ -245,7 +245,7 @@ TEST_F(RsaShmUnitTestSuite, ExportServiceWithObjectClass) { RegisterCalculatorService(); celix_properties_t *prop = celix_properties_create(); - celix_properties_set(prop, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, "*"); + celix_properties_set(prop, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, "*"); celix_array_list_t *regs = nullptr; status = rsaShm_exportService(admin, const_cast(std::to_string(calcSvcId).c_str()), prop, ®s); EXPECT_EQ(CELIX_SUCCESS, status); @@ -290,7 +290,7 @@ TEST_F(RsaShmUnitTestSuite, ExportedInterfaceNotMatchObjectClass) { RegisterCalculatorService(); celix_properties_t *prop = celix_properties_create(); - celix_properties_set(prop, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, "unmatched-interface"); + celix_properties_set(prop, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, "unmatched-interface"); celix_array_list_t *regs = nullptr; status = rsaShm_exportService(admin, const_cast(std::to_string(calcSvcId).c_str()), prop, ®s); EXPECT_EQ(CELIX_SUCCESS, status); @@ -312,7 +312,7 @@ TEST_F(RsaShmUnitTestSuite, ExportServiceWithUnmatchedConfigType) { RegisterCalculatorService(); celix_properties_t *prop = celix_properties_create(); - celix_properties_set(prop, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, "unmatched-config-type"); + celix_properties_set(prop, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, "unmatched-config-type"); celix_array_list_t *regs = nullptr; status = rsaShm_exportService(admin, const_cast(std::to_string(calcSvcId).c_str()), prop, ®s); EXPECT_EQ(CELIX_SUCCESS, status); @@ -337,7 +337,7 @@ TEST_F(RsaShmUnitTestSuite, ServiceLostExportedInterfaceProperty) { }; celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); calcSvcId = celix_bundleContext_registerService(ctx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); celix_array_list_t *regs = nullptr; @@ -535,7 +535,7 @@ TEST_F(RsaShmUnitTestSuite, ImportServiceWithUnmatchedConfigType) { endpoint_description_t *endpoint = CreateEndpointDescription(); EXPECT_NE(nullptr, endpoint); - celix_properties_set(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, "unmatched-config-type"); + celix_properties_set(endpoint->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "unmatched-config-type"); status = rsaShm_importService(admin, endpoint, ®s); @@ -556,7 +556,7 @@ TEST_F(RsaShmUnitTestSuite, EndpointLostConfigType) { endpoint_description_t *endpoint = CreateEndpointDescription(); EXPECT_NE(nullptr, endpoint); - celix_properties_unset(endpoint->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + celix_properties_unset(endpoint->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS); status = rsaShm_importService(admin, endpoint, ®s); EXPECT_EQ(CELIX_SUCCESS, status); @@ -758,9 +758,9 @@ class RsaShmRpcTestSuite : public ::testing::Test { .add = calculator_add, }; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE ",celix.remote.admin.rpc_type.json"); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE ",celix.remote.admin.rpc_type.json"); calcSvcId = celix_bundleContext_registerService(serverCtx.get(), &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); EXPECT_TRUE(calcSvcId >= 0); } diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc index 10e83d352..d2ada2bb2 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmImportRegistrationUnitTestSuite.cc @@ -51,9 +51,9 @@ static celix_status_t RpcFacCreateProxy(void *handle, const endpoint_description return CELIX_SUCCESS; }; celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); auto calcSvcId = celix_bundleContext_registerServiceAsync(ctx, &calcService, RSA_SHM_CALCULATOR_SERVICE, properties); EXPECT_GE(calcSvcId, 0); @@ -88,9 +88,9 @@ class RsaShmImportRegUnitTestSuite : public ::testing::Test { rpcFactory.destroyEndpoint = nullptr; celix_properties_t *rpcFacProps = celix_properties_create(); - celix_properties_set(rpcFacProps, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); - rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, RSA_RPC_FACTORY_NAME, rpcFacProps); + celix_properties_set(rpcFacProps, CELIX_RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); + celix_properties_set(rpcFacProps, CELIX_FRAMEWORK_SERVICE_VERSION, CELIX_RSA_RPC_FACTORY_VERSION); + rpcFactorySvcId = celix_bundleContext_registerServiceAsync(ctx.get(), &rpcFactory, CELIX_RSA_RPC_FACTORY_NAME, rpcFacProps); EXPECT_GE(rpcFactorySvcId, 1); celix_bundleContext_waitForEvents(ctx.get()); @@ -110,12 +110,12 @@ class RsaShmImportRegUnitTestSuite : public ::testing::Test { celix_properties_t *properties = celix_properties_create(); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_SHM_CALCULATOR_SERVICE); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_SHM_CALCULATOR_SERVICE_VERSION); - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CALCULATOR_CONFIGURATION_TYPE); celix_properties_set(properties, RSA_SHM_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); - celix_properties_setLong(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, 100);//Set a dummy service id - celix_properties_set(properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, "")); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "7f7efba5-500f-4ee9-b733-68de012091da"); + celix_properties_setLong(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, 100);//Set a dummy service id + celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, "")); celix_properties_set(properties, RSA_SHM_SERVER_NAME_KEY, "ShmServ-dummy"); endpoint_description_t *endpoint = nullptr; auto status = endpointDescription_create(properties, &endpoint); @@ -230,9 +230,9 @@ TEST_F(RsaShmImportRegUnitTestSuite, RegisterMoreThanOneRpcFactory) { //register another rpc factory celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); - celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, RSA_RPC_FACTORY_VERSION); - auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", RSA_RPC_FACTORY_NAME, props); + celix_properties_set(props, CELIX_RSA_RPC_TYPE_KEY, RSA_RPC_TYPE_FOR_TEST); + celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, CELIX_RSA_RPC_FACTORY_VERSION); + auto svcId = celix_bundleContext_registerServiceAsync(ctx.get(), (void*)"dumb-rpc-service", CELIX_RSA_RPC_FACTORY_NAME, props); EXPECT_GE(svcId, 1); celix_bundleContext_waitForEvents(ctx.get()); celix_bundleContext_unregisterServiceAsync(ctx.get(), svcId, nullptr, nullptr); diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmIntegrationTestSuite.cc b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmIntegrationTestSuite.cc index c0b36cdbb..d7af36be3 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmIntegrationTestSuite.cc +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/gtest/src/RsaShmIntegrationTestSuite.cc @@ -43,6 +43,6 @@ class RsaShmActivatorTestSuite : public ::testing::Test { TEST_F(RsaShmActivatorTestSuite, FindRsaShmService) { celix_bundleContext_waitForEvents(ctx.get()); - long found = celix_bundleContext_findService(ctx.get(), OSGI_RSA_REMOTE_SERVICE_ADMIN); + long found = celix_bundleContext_findService(ctx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN); EXPECT_GE(found, 0); } diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c index 3d9f0f258..50a1d74bb 100755 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_activator.c @@ -54,7 +54,7 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t *activator, celix_bundl return CELIX_ENOMEM; } - status = celix_properties_set(props, OSGI_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_SHM_CONFIGURATION_TYPE); + status = celix_properties_set(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_SHM_CONFIGURATION_TYPE); if (status != CELIX_SUCCESS) { return status; } @@ -80,7 +80,7 @@ celix_status_t rsaShmActivator_start(rsa_shm_activator_t *activator, celix_bundl activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference; activator->adminSvcId = celix_bundleContext_registerServiceAsync(context, &activator->adminService, - OSGI_RSA_REMOTE_SERVICE_ADMIN, celix_steal_ptr(props)); + CELIX_RSA_REMOTE_SERVICE_ADMIN, celix_steal_ptr(props)); if (activator->adminSvcId < 0) { return CELIX_BUNDLE_EXCEPTION; } diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c index 805f602ed..736593470 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_export_registration.c @@ -116,21 +116,21 @@ celix_status_t exportRegistration_create(celix_bundle_context_t *context, } char filter[128] = {0}; - int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaShmRpcType); + int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", CELIX_RSA_RPC_TYPE_KEY, rsaShmRpcType); if (bytes >= sizeof(filter)) { - celix_logHelper_error(logHelper,"RSA export reg: The value(%s) of %s is too long.", rsaShmRpcType, RSA_RPC_TYPE_KEY); + celix_logHelper_error(logHelper, "RSA export reg: The value(%s) of %s is too long.", rsaShmRpcType, CELIX_RSA_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; opts.filter.filter = filter; - opts.filter.serviceName = RSA_RPC_FACTORY_NAME; - opts.filter.versionRange = RSA_RPC_FACTORY_USE_RANGE; + opts.filter.serviceName = CELIX_RSA_RPC_FACTORY_NAME; + opts.filter.versionRange = CELIX_RSA_RPC_FACTORY_USE_RANGE; opts.callbackHandle = export; opts.add = exportRegistration_addRpcFac; opts.remove = exportRegistration_removeRpcFac; export->rpcSvcTrkId = celix_bundleContext_trackServicesWithOptionsAsync(context, &opts); if (export->rpcSvcTrkId < 0) { - celix_logHelper_error(logHelper,"RSA export reg: Error Tracking service for %s.", RSA_RPC_FACTORY_NAME); + celix_logHelper_error(logHelper, "RSA export reg: Error Tracking service for %s.", CELIX_RSA_RPC_FACTORY_NAME); return CELIX_SERVICE_EXCEPTION; } @@ -227,8 +227,8 @@ static void exportRegistration_addRpcFac(void *handle, void *svc) { reqHandlerSvcId); celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; opts.filter.filter = filter; - opts.filter.serviceName = RSA_REQUEST_HANDLER_SERVICE_NAME; - opts.filter.versionRange = RSA_REQUEST_HANDLER_SERVICE_USE_RANGE; + opts.filter.serviceName = CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME; + opts.filter.versionRange = CELIX_RSA_REQUEST_HANDLER_SERVICE_USE_RANGE; opts.callbackHandle = export->reqHandlerSvcEntry; // exportRegistration_removeRequestHandlerSvc maybe occur after exportRegistration_destroyCallback. Therefore,Using refrence count here. exportRegistration_retainReqHandlerSvcEntry(export->reqHandlerSvcEntry); @@ -236,7 +236,7 @@ static void exportRegistration_addRpcFac(void *handle, void *svc) { opts.remove = exportRegistration_removeRequestHandlerSvc; export->reqHandlerSvcTrkId = celix_bundleContext_trackServicesWithOptionsAsync(export->context, &opts); if (export->reqHandlerSvcTrkId < 0) { - celix_logHelper_error(export->logHelper,"RSA export reg: Error Tracking service for %s(%ld)", RSA_REQUEST_HANDLER_SERVICE_NAME, export->reqHandlerSvcId); + celix_logHelper_error(export->logHelper, "RSA export reg: Error Tracking service for %s(%ld)", CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, export->reqHandlerSvcId); exportRegistration_releaseReqHandlerSvcEntry(export->reqHandlerSvcEntry); rpcFac->destroyEndpoint(rpcFac->handle, reqHandlerSvcId); return; diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c index 2e0c760a1..c4441da4c 100755 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c @@ -103,8 +103,8 @@ celix_status_t rsaShm_create(celix_bundle_context_t *context, celix_log_helper_t ad->reqSenderService.handle = ad; ad->reqSenderService.sendRequest = (void*)rsaShm_send; celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.serviceName = RSA_REQUEST_SENDER_SERVICE_NAME; - opts.serviceVersion = RSA_REQUEST_SENDER_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REQUEST_SENDER_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REQUEST_SENDER_SERVICE_VERSION; opts.svc = &ad->reqSenderService; ad->reqSenderSvcId = celix_bundleContext_registerServiceWithOptionsAsync(context, &opts); if (ad->reqSenderSvcId < 0) { @@ -188,7 +188,7 @@ static celix_status_t rsaShm_receiveMsgCB(void *handle, rsa_shm_server_t *shmSer } rsa_shm_t *admin = handle; - long serviceId = celix_properties_getAsLong(metadata, OSGI_RSA_ENDPOINT_SERVICE_ID, -1); + long serviceId = celix_properties_getAsLong(metadata, CELIX_RSA_ENDPOINT_SERVICE_ID, -1); if (serviceId < 0) { celix_logHelper_error(admin->logHelper, "Service id is invalid."); return CELIX_ILLEGAL_ARGUMENT; @@ -220,7 +220,7 @@ celix_status_t rsaShm_send(rsa_shm_t *admin, endpoint_description_t *endpoint, return CELIX_SERVICE_EXCEPTION; } celix_autoptr(celix_properties_t) newMetadata = celix_properties_copy(metadata); - celix_properties_setLong(newMetadata,OSGI_RSA_ENDPOINT_SERVICE_ID, endpoint->serviceId); + celix_properties_setLong(newMetadata, CELIX_RSA_ENDPOINT_SERVICE_ID, endpoint->serviceId); status = rsaShmClientManager_sendMsgTo(admin->shmClientManager, shmServerName, (long)endpoint->serviceId, newMetadata, request, response); @@ -259,7 +259,7 @@ static bool rsaShm_isConfigTypeMatched(celix_properties_t *properties) { * Admin implementation must choose a convenient configuration type. */ const char *exportConfigs = celix_properties_get(properties, - OSGI_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CONFIGURATION_TYPE); + CELIX_RSA_SERVICE_EXPORTED_CONFIGS, RSA_SHM_CONFIGURATION_TYPE); if (exportConfigs != NULL) { // See if the EXPORT_CONFIGS matches this RSA. If so, try to export. @@ -330,10 +330,10 @@ celix_status_t rsaShm_exportService(rsa_shm_t *admin, char *serviceId, celix_autoptr(celix_array_list_t) registrations = NULL; if (rsaShm_isConfigTypeMatched(exportedProperties)) { - const char *exportsProp = celix_properties_get(exportedProperties, (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, NULL); + const char *exportsProp = celix_properties_get(exportedProperties, (char *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, NULL); const char *providedProp = celix_properties_get(exportedProperties, (char *) CELIX_FRAMEWORK_SERVICE_NAME, NULL); if (exportsProp == NULL || providedProp == NULL) { - celix_logHelper_error(admin->logHelper, "Error exporting service %s. Missing property %s or %s.", serviceId, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, CELIX_FRAMEWORK_SERVICE_NAME); + celix_logHelper_error(admin->logHelper, "Error exporting service %s. Missing property %s or %s.", serviceId, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, CELIX_FRAMEWORK_SERVICE_NAME); return CELIX_ILLEGAL_STATE; } celix_autofree char *exports = celix_utils_trim(exportsProp); @@ -463,8 +463,8 @@ static celix_status_t rsaShm_createEndpointDescription(rsa_shm_t *admin, celix_autoptr(celix_properties_t) endpointProperties = celix_properties_copy(exportedProperties); celix_properties_unset(endpointProperties,CELIX_FRAMEWORK_SERVICE_NAME); - celix_properties_unset(endpointProperties,OSGI_RSA_SERVICE_EXPORTED_INTERFACES); - celix_properties_unset(endpointProperties,OSGI_RSA_SERVICE_EXPORTED_CONFIGS); + celix_properties_unset(endpointProperties, CELIX_RSA_SERVICE_EXPORTED_INTERFACES); + celix_properties_unset(endpointProperties, CELIX_RSA_SERVICE_EXPORTED_CONFIGS); celix_properties_unset(endpointProperties, CELIX_FRAMEWORK_SERVICE_ID); long serviceId = celix_properties_getAsLong(exportedProperties, CELIX_FRAMEWORK_SERVICE_ID, -1); @@ -479,12 +479,12 @@ static celix_status_t rsaShm_createEndpointDescription(rsa_shm_t *admin, celix_logHelper_error(admin->logHelper, "Cannot get framework uuid"); return CELIX_FRAMEWORK_EXCEPTION; } - celix_properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + celix_properties_set(endpointProperties, (char*) CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); celix_properties_set(endpointProperties, (char*) CELIX_FRAMEWORK_SERVICE_NAME, interface); - celix_properties_setLong(endpointProperties, (char*) OSGI_RSA_ENDPOINT_SERVICE_ID, serviceId); - celix_properties_set(endpointProperties, (char*) OSGI_RSA_ENDPOINT_ID, endpoint_uuid); - celix_properties_set(endpointProperties, (char*) OSGI_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(endpointProperties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CONFIGURATION_TYPE); + celix_properties_setLong(endpointProperties, (char*) CELIX_RSA_ENDPOINT_SERVICE_ID, serviceId); + celix_properties_set(endpointProperties, (char*) CELIX_RSA_ENDPOINT_ID, endpoint_uuid); + celix_properties_set(endpointProperties, (char*) CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, RSA_SHM_CONFIGURATION_TYPE); //If the rpc type of RSA_SHM_CONFIGURATION_TYPE is not set, then set a default value. if (celix_properties_get(endpointProperties, RSA_SHM_RPC_TYPE_KEY, NULL) == NULL) { celix_properties_set(endpointProperties, RSA_SHM_RPC_TYPE_KEY, RSA_SHM_RPC_TYPE_DEFAULT); @@ -524,7 +524,7 @@ celix_status_t rsaShm_importService(rsa_shm_t *admin, endpoint_description_t *en celix_logHelper_info(admin->logHelper, "Import service %s", endpointDesc->serviceName); bool importService = false; - const char *importConfigs = celix_properties_get(endpointDesc->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importConfigs = celix_properties_get(endpointDesc->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); if (importConfigs != NULL) { // Check whether this RSA must be imported celix_autofree char *ecCopy = strndup(importConfigs, strlen(importConfigs)); @@ -541,7 +541,7 @@ celix_status_t rsaShm_importService(rsa_shm_t *admin, endpoint_description_t *en token = strtok_r(NULL, delimiter, &savePtr); } } else { - celix_logHelper_warning(admin->logHelper, "Mandatory %s element missing from endpoint description", OSGI_RSA_SERVICE_IMPORTED_CONFIGS); + celix_logHelper_warning(admin->logHelper, "Mandatory %s element missing from endpoint description", CELIX_RSA_SERVICE_IMPORTED_CONFIGS); } if (!importService) { return CELIX_SUCCESS; diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c index f0f4bdef4..3f3d86660 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c @@ -71,21 +71,21 @@ celix_status_t importRegistration_create(celix_bundle_context_t *context, } char filter[128] = {0}; - int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", RSA_RPC_TYPE_KEY, rsaShmRpcType); + int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", CELIX_RSA_RPC_TYPE_KEY, rsaShmRpcType); if (bytes >= sizeof(filter)) { - celix_logHelper_error(logHelper,"RSA import reg: The value(%s) of %s is too long.", rsaShmRpcType, RSA_RPC_TYPE_KEY); + celix_logHelper_error(logHelper, "RSA import reg: The value(%s) of %s is too long.", rsaShmRpcType, CELIX_RSA_RPC_TYPE_KEY); return CELIX_ILLEGAL_ARGUMENT; } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; opts.filter.filter = filter; - opts.filter.serviceName = RSA_RPC_FACTORY_NAME; - opts.filter.versionRange = RSA_RPC_FACTORY_USE_RANGE; + opts.filter.serviceName = CELIX_RSA_RPC_FACTORY_NAME; + opts.filter.versionRange = CELIX_RSA_RPC_FACTORY_USE_RANGE; opts.callbackHandle = import; opts.add = importRegistration_addRpcFac; opts.remove = importRegistration_removeRpcFac; import->rpcSvcTrkId = celix_bundleContext_trackServicesWithOptionsAsync(context, &opts); if (import->rpcSvcTrkId < 0) { - celix_logHelper_error(logHelper,"RSA import reg: Error Tracking service for %s.", RSA_RPC_FACTORY_NAME); + celix_logHelper_error(logHelper, "RSA import reg: Error Tracking service for %s.", CELIX_RSA_RPC_FACTORY_NAME); return CELIX_SERVICE_EXCEPTION; } diff --git a/bundles/remote_services/rsa_common/gtest/src/EndpointDescriptionUnitTestSuite.cc b/bundles/remote_services/rsa_common/gtest/src/EndpointDescriptionUnitTestSuite.cc index 7ef2ba492..bf4a51ad2 100644 --- a/bundles/remote_services/rsa_common/gtest/src/EndpointDescriptionUnitTestSuite.cc +++ b/bundles/remote_services/rsa_common/gtest/src/EndpointDescriptionUnitTestSuite.cc @@ -38,10 +38,10 @@ class EndpointDescriptionUnitTestSuite : public ::testing::Test { fw = std::shared_ptr{celix_frameworkFactory_createFramework(props), [](auto* f) {celix_frameworkFactory_destroyFramework(f);}}; properties = std::shared_ptr(celix_properties_create(), [](celix_properties_t* p) {celix_properties_destroy(p);}); - celix_properties_set(properties.get(), OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "e7c2a8ab-79a8-40c5-a926-85ae64c9382a"); + celix_properties_set(properties.get(), CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "e7c2a8ab-79a8-40c5-a926-85ae64c9382a"); celix_properties_set(properties.get(), CELIX_FRAMEWORK_SERVICE_NAME, "org.example.api.Foo"); - celix_properties_set(properties.get(), OSGI_RSA_ENDPOINT_ID, "983e0ad8-5de9-44a8-b336-b3dc79d364b5"); - celix_properties_set(properties.get(), OSGI_RSA_ENDPOINT_SERVICE_ID, "100"); + celix_properties_set(properties.get(), CELIX_RSA_ENDPOINT_ID, "983e0ad8-5de9-44a8-b336-b3dc79d364b5"); + celix_properties_set(properties.get(), CELIX_RSA_ENDPOINT_SERVICE_ID, "100"); } ~EndpointDescriptionUnitTestSuite() override { @@ -87,7 +87,7 @@ TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithENOMEM) { TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithInvalidProperties1) { endpoint_description_t* endpointDescription = nullptr; celix_properties_t *props = celix_properties_copy(properties.get()); - celix_properties_unset(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID); + celix_properties_unset(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID); auto status = endpointDescription_create(props, &endpointDescription); EXPECT_EQ(status, CELIX_BUNDLE_EXCEPTION); @@ -106,7 +106,7 @@ TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithInvalidPro TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithInvalidProperties3) { endpoint_description_t* endpointDescription = nullptr; celix_properties_t *props = celix_properties_copy(properties.get()); - celix_properties_unset(props, OSGI_RSA_ENDPOINT_ID); + celix_properties_unset(props, CELIX_RSA_ENDPOINT_ID); auto status = endpointDescription_create(props, &endpointDescription); EXPECT_EQ(status, CELIX_BUNDLE_EXCEPTION); celix_properties_destroy(props); @@ -115,7 +115,7 @@ TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithInvalidPro TEST_F(EndpointDescriptionUnitTestSuite, CreateEndpointDescriptionWithInvalidProperties4) { endpoint_description_t* endpointDescription = nullptr; celix_properties_t *props = celix_properties_copy(properties.get()); - celix_properties_unset(props, OSGI_RSA_ENDPOINT_SERVICE_ID); + celix_properties_unset(props, CELIX_RSA_ENDPOINT_SERVICE_ID); auto status = endpointDescription_create(props, &endpointDescription); EXPECT_EQ(status, CELIX_BUNDLE_EXCEPTION); celix_properties_destroy(props); diff --git a/bundles/remote_services/rsa_common/src/endpoint_description.c b/bundles/remote_services/rsa_common/src/endpoint_description.c index e9e9affa1..be9c1fdaf 100644 --- a/bundles/remote_services/rsa_common/src/endpoint_description.c +++ b/bundles/remote_services/rsa_common/src/endpoint_description.c @@ -49,10 +49,10 @@ celix_status_t endpointDescription_create(celix_properties_t *properties, endpoi return CELIX_ENOMEM; } ep->properties = properties; - ep->frameworkUUID = (char*)celix_properties_get(properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); - ep->id = (char*)celix_properties_get(properties, OSGI_RSA_ENDPOINT_ID, NULL); + ep->frameworkUUID = (char*)celix_properties_get(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); + ep->id = (char*)celix_properties_get(properties, CELIX_RSA_ENDPOINT_ID, NULL); ep->serviceName = celix_utils_strdup(celix_properties_get(properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL)); - ep->serviceId = celix_properties_getAsLong(properties, OSGI_RSA_ENDPOINT_SERVICE_ID, -1); + ep->serviceId = celix_properties_getAsLong(properties, CELIX_RSA_ENDPOINT_SERVICE_ID, -1); if (!(ep->frameworkUUID) || !(ep->id) || !(ep->serviceName) || ep->serviceId < 0) { fw_log(celix_frameworkLogger_globalLogger(), CELIX_LOG_LEVEL_ERROR, "ENDPOINT_DESCRIPTION: incomplete description!."); @@ -95,9 +95,9 @@ endpoint_description_t *endpointDescription_clone(const endpoint_description_t * if (newDesc->properties == NULL) { return NULL; } - newDesc->frameworkUUID = (char*)celix_properties_get(newDesc->properties,OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); + newDesc->frameworkUUID = (char*)celix_properties_get(newDesc->properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, NULL); newDesc->serviceId = description->serviceId; - newDesc->id = (char*)celix_properties_get(newDesc->properties, OSGI_RSA_ENDPOINT_ID, NULL); + newDesc->id = (char*)celix_properties_get(newDesc->properties, CELIX_RSA_ENDPOINT_ID, NULL); newDesc->serviceName = celix_utils_strdup(description->serviceName); if (newDesc->serviceName == NULL) { return NULL; diff --git a/bundles/remote_services/rsa_common/src/export_registration_impl.c b/bundles/remote_services/rsa_common/src/export_registration_impl.c index 32f28f72f..ad541e5fb 100644 --- a/bundles/remote_services/rsa_common/src/export_registration_impl.c +++ b/bundles/remote_services/rsa_common/src/export_registration_impl.c @@ -127,7 +127,7 @@ celix_status_t exportRegistration_createEndpointTracker(export_registration_t *r if (status == CELIX_SUCCESS) { char filter[512]; - snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) CELIX_FRAMEWORK_SERVICE_NAME, (char*) OSGI_RSA_REMOTE_ENDPOINT, registration->endpointDescription->serviceName); + snprintf(filter, 512, "(&(%s=%s)(remote.interface=%s))", (char*) CELIX_FRAMEWORK_SERVICE_NAME, (char*) CELIX_RSA_REMOTE_ENDPOINT, registration->endpointDescription->serviceName); status = serviceTracker_createWithFilter(registration->context, filter, customizer, tracker); } diff --git a/bundles/remote_services/rsa_common/src/import_registration_impl.c b/bundles/remote_services/rsa_common/src/import_registration_impl.c index 95c67db8d..79fa48908 100644 --- a/bundles/remote_services/rsa_common/src/import_registration_impl.c +++ b/bundles/remote_services/rsa_common/src/import_registration_impl.c @@ -167,7 +167,7 @@ celix_status_t importRegistration_createProxyFactoryTracker(import_registration_ if (status == CELIX_SUCCESS) { char filter[512]; - snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) CELIX_FRAMEWORK_SERVICE_NAME, (char*) OSGI_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName); + snprintf(filter, 512, "(&(%s=%s)(proxy.interface=%s))", (char*) CELIX_FRAMEWORK_SERVICE_NAME, (char*) CELIX_RSA_REMOTE_PROXY_FACTORY, registration_factory->serviceName); status = serviceTracker_createWithFilter(registration_factory->context, filter, customizer, tracker); if (status == CELIX_SUCCESS) diff --git a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c index 234b40fbf..8f3d7beaa 100644 --- a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c +++ b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c @@ -64,7 +64,7 @@ celix_status_t remoteInterceptorsHandler_create(celix_bundle_context_t *ctx, rem if (status == CELIX_SUCCESS) { // Create service tracker here, and not in the activator celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; + opts.filter.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; opts.callbackHandle = *handler; opts.addWithProperties = remoteInterceptorsHandler_addInterceptor; opts.removeWithProperties = remoteInterceptorsHandler_removeInterceptor; diff --git a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcIntegrationTestSuite.cc b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcIntegrationTestSuite.cc index 843e6f48a..0fcbfa776 100644 --- a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcIntegrationTestSuite.cc +++ b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcIntegrationTestSuite.cc @@ -45,6 +45,6 @@ class RsaJsonRpcIntegrationTestSuite : public ::testing::Test { TEST_F(RsaJsonRpcIntegrationTestSuite, FindRsaJsonRpcService) { celix_bundleContext_waitForEvents(ctx.get()); -long found = celix_bundleContext_findService(ctx.get(), RSA_RPC_FACTORY_NAME); +long found = celix_bundleContext_findService(ctx.get(), CELIX_RSA_RPC_FACTORY_NAME); EXPECT_GE(found, 0); } \ No newline at end of file diff --git a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcUnitTestSuite.cc b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcUnitTestSuite.cc index 47f906fb6..7cb09b273 100644 --- a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcUnitTestSuite.cc +++ b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaJsonRpcUnitTestSuite.cc @@ -87,14 +87,14 @@ class RsaJsonRpcUnitTestSuite : public ::testing::Test { endpointDesc->properties = celix_properties_create(); EXPECT_TRUE(endpointDesc->properties != nullptr); const char *uuid = celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); - celix_properties_set(endpointDesc->properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + celix_properties_set(endpointDesc->properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); celix_properties_set(endpointDesc->properties, CELIX_FRAMEWORK_SERVICE_NAME, RSA_RPC_JSON_TEST_SERVICE); celix_properties_set(endpointDesc->properties, CELIX_FRAMEWORK_SERVICE_VERSION, "1.0.0"); - celix_properties_set(endpointDesc->properties, OSGI_RSA_ENDPOINT_ID, "8cf05b2d-421e-4c46-b55e-c3f1900b7cba"); - celix_properties_set(endpointDesc->properties, OSGI_RSA_SERVICE_IMPORTED, "true"); - endpointDesc->frameworkUUID = (char*)celix_properties_get(endpointDesc->properties, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, nullptr); + celix_properties_set(endpointDesc->properties, CELIX_RSA_ENDPOINT_ID, "8cf05b2d-421e-4c46-b55e-c3f1900b7cba"); + celix_properties_set(endpointDesc->properties, CELIX_RSA_SERVICE_IMPORTED, "true"); + endpointDesc->frameworkUUID = (char*)celix_properties_get(endpointDesc->properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, nullptr); endpointDesc->serviceId = svcId; - endpointDesc->id = (char*)celix_properties_get(endpointDesc->properties, OSGI_RSA_ENDPOINT_ID, nullptr); + endpointDesc->id = (char*)celix_properties_get(endpointDesc->properties, CELIX_RSA_ENDPOINT_ID, nullptr); endpointDesc->serviceName = strdup(RSA_RPC_JSON_TEST_SERVICE); return endpointDesc; } @@ -342,8 +342,8 @@ class RsaJsonRpcProxyUnitTestSuite : public RsaJsonRpcUnitTestSuite { return CELIX_SUCCESS; }; celix_service_registration_options_t opts{}; - opts.serviceName = RSA_REQUEST_SENDER_SERVICE_NAME; - opts.serviceVersion = RSA_REQUEST_SENDER_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REQUEST_SENDER_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REQUEST_SENDER_SERVICE_VERSION; opts.svc = &reqSenderSvc; reqSenderSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx.get(), &opts); EXPECT_NE(-1, reqSenderSvcId); @@ -627,8 +627,8 @@ TEST_F(RsaJsonRpcProxyUnitTestSuite2, ServiceInvocationIsIntercepted) { }; celix_service_registration_options_t opts{}; - opts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - opts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; opts.svc = &interceptor; auto interceptorSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx.get(), &opts); celix_bundleContext_waitForAsyncRegistration(ctx.get(), interceptorSvcId); @@ -738,7 +738,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, UseRequestHandler) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -770,7 +770,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, FailedToFindInterfaceDescriptor) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -804,7 +804,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, FailedToGetServiceVersionFromInterfaceDe celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -836,7 +836,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, ServiceVersionMismatched) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -868,7 +868,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, EndpointLostServiceVersion) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -899,7 +899,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, UseRequestHandlerWithInvalidParams) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); @@ -960,8 +960,8 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, ServiceInvocationIsIntercepted) { return; }; celix_service_registration_options_t opts{}; - opts.serviceName = REMOTE_INTERCEPTOR_SERVICE_NAME; - opts.serviceVersion = REMOTE_INTERCEPTOR_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION; opts.svc = &interceptor; auto interceptorSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx.get(), &opts); celix_bundleContext_waitForAsyncRegistration(ctx.get(), interceptorSvcId); @@ -970,7 +970,7 @@ TEST_F(RsaJsonRpcEndPointUnitTestSuite, ServiceInvocationIsIntercepted) { celix_properties_t *metadata = celix_properties_create(); celix_properties_setLong(metadata, "SerialProtocolId", serialProtoId); - auto found = celix_bundleContext_useService(ctx.get(), RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { + auto found = celix_bundleContext_useService(ctx.get(), CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME, metadata, [](void *handle, void *svc) { celix_properties_t *metadata = static_cast< celix_properties_t *>(handle);//unused auto reqHandler = static_cast(svc); EXPECT_NE(nullptr, reqHandler); diff --git a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaRequestSenderTrackerUnitTestSuite.cc b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaRequestSenderTrackerUnitTestSuite.cc index 9728cde00..8c46cd839 100644 --- a/bundles/remote_services/rsa_rpc_json/gtest/src/RsaRequestSenderTrackerUnitTestSuite.cc +++ b/bundles/remote_services/rsa_rpc_json/gtest/src/RsaRequestSenderTrackerUnitTestSuite.cc @@ -58,8 +58,8 @@ class RsaRequestSenderTrackerUnitTestSuite : public ::testing::Test { return CELIX_SUCCESS; }; celix_service_registration_options_t opts{}; - opts.serviceName = RSA_REQUEST_SENDER_SERVICE_NAME; - opts.serviceVersion = RSA_REQUEST_SENDER_SERVICE_VERSION; + opts.serviceName = CELIX_RSA_REQUEST_SENDER_SERVICE_NAME; + opts.serviceVersion = CELIX_RSA_REQUEST_SENDER_SERVICE_VERSION; opts.svc = &reqSenderSvc; reqSenderSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx.get(), &opts); EXPECT_NE(-1, reqSenderSvcId); diff --git a/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_activator.c b/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_activator.c index 2aca6aafe..24a9d16e5 100644 --- a/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_activator.c +++ b/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_activator.c @@ -55,15 +55,15 @@ static celix_status_t rsaJsonRpc_start(rsa_json_rpc_activator_t* activator, celi celix_logHelper_error(activator->logHelper, "Error creating properties for json rpc."); return CELIX_ENOMEM; } - celix_properties_set(props, RSA_RPC_TYPE_KEY, "celix.remote.admin.rpc_type.json"); + celix_properties_set(props, CELIX_RSA_RPC_TYPE_KEY, "celix.remote.admin.rpc_type.json"); activator->rpcFac.handle = activator->jsonRpc; activator->rpcFac.createProxy = rsaJsonRpc_createProxy; activator->rpcFac.destroyProxy = rsaJsonRpc_destroyProxy; activator->rpcFac.createEndpoint = rsaJsonRpc_createEndpoint; activator->rpcFac.destroyEndpoint = rsaJsonRpc_destroyEndpoint; celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts.serviceName = RSA_RPC_FACTORY_NAME; - opts.serviceVersion = RSA_RPC_FACTORY_VERSION; + opts.serviceName = CELIX_RSA_RPC_FACTORY_NAME; + opts.serviceVersion = CELIX_RSA_RPC_FACTORY_VERSION; opts.properties = props; opts.svc = &activator->rpcFac; activator->rpcSvcId = celix_bundleContext_registerServiceWithOptionsAsync(ctx, &opts); diff --git a/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_endpoint_impl.c b/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_endpoint_impl.c index ee1dc5ef2..737eb14ce 100644 --- a/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_endpoint_impl.c +++ b/bundles/remote_services/rsa_rpc_json/src/rsa_json_rpc_endpoint_impl.c @@ -105,8 +105,8 @@ celix_status_t rsaJsonRpcEndpoint_create(celix_bundle_context_t* ctx, celix_log_ endpoint->reqHandlerSvc.handle = endpoint; endpoint->reqHandlerSvc.handleRequest = rsaJsonRpcEndpoint_handleRequest; celix_service_registration_options_t opts1 = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; - opts1.serviceName = RSA_REQUEST_HANDLER_SERVICE_NAME; - opts1.serviceVersion = RSA_REQUEST_HANDLER_SERVICE_VERSION; + opts1.serviceName = CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME; + opts1.serviceVersion = CELIX_RSA_REQUEST_HANDLER_SERVICE_VERSION; opts1.svc = &endpoint->reqHandlerSvc; celix_steal_ptr(lock); celix_steal_ptr(endpointDescCopy); diff --git a/bundles/remote_services/rsa_rpc_json/src/rsa_request_sender_tracker.c b/bundles/remote_services/rsa_rpc_json/src/rsa_request_sender_tracker.c index 57589d456..b746144f1 100644 --- a/bundles/remote_services/rsa_rpc_json/src/rsa_request_sender_tracker.c +++ b/bundles/remote_services/rsa_rpc_json/src/rsa_request_sender_tracker.c @@ -60,8 +60,8 @@ celix_status_t rsaRequestSenderTracker_create(celix_bundle_context_t* ctx, celix celix_autoptr(celix_long_hash_map_t) requestSenderSvcs = tracker->requestSenderSvcs = celix_longHashMap_create(); assert(tracker->requestSenderSvcs != NULL); celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - opts.filter.serviceName = RSA_REQUEST_SENDER_SERVICE_NAME; - opts.filter.versionRange = RSA_REQUEST_SENDER_SERVICE_USE_RANGE; + opts.filter.serviceName = CELIX_RSA_REQUEST_SENDER_SERVICE_NAME; + opts.filter.versionRange = CELIX_RSA_REQUEST_SENDER_SERVICE_USE_RANGE; opts.callbackHandle = tracker; opts.addWithProperties = rsaRequestSenderTracker_addServiceWithProperties; opts.removeWithProperties = rsaRequestSenderTracker_removeServiceWithProperties; diff --git a/bundles/remote_services/rsa_spi/include/endpoint_listener.h b/bundles/remote_services/rsa_spi/include/endpoint_listener.h index 68bad113e..18e3ffd90 100644 --- a/bundles/remote_services/rsa_spi/include/endpoint_listener.h +++ b/bundles/remote_services/rsa_spi/include/endpoint_listener.h @@ -32,9 +32,9 @@ #include "endpoint_description.h" -static const char * const OSGI_ENDPOINT_LISTENER_SERVICE = "endpoint_listener"; +#define CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME "endpoint_listener" -static const char * const OSGI_ENDPOINT_LISTENER_SCOPE = "endpoint.listener.scope"; +#define CELIX_RSA_ENDPOINT_LISTENER_SCOPE "endpoint.listener.scope" struct endpoint_listener { void *handle; diff --git a/bundles/remote_services/rsa_spi/include/remote_constants.h b/bundles/remote_services/rsa_spi/include/remote_constants.h index 1532d274a..a85eaffb6 100644 --- a/bundles/remote_services/rsa_spi/include/remote_constants.h +++ b/bundles/remote_services/rsa_spi/include/remote_constants.h @@ -27,19 +27,19 @@ #ifndef REMOTE_CONSTANTS_H_ #define REMOTE_CONSTANTS_H_ -static const char * const OSGI_RSA_SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces"; -static const char * const OSGI_RSA_ENDPOINT_FRAMEWORK_UUID = "endpoint.framework.uuid"; -static const char * const OSGI_RSA_ENDPOINT_SERVICE_ID = "endpoint.service.id"; -static const char * const OSGI_RSA_ENDPOINT_ID = "endpoint.id"; -static const char * const OSGI_RSA_SERVICE_IMPORTED = "service.imported"; -static const char * const OSGI_RSA_SERVICE_IMPORTED_CONFIGS = "service.imported.configs"; -static const char * const OSGI_RSA_SERVICE_EXPORTED_CONFIGS = "service.exported.configs"; -static const char * const OSGI_RSA_SERVICE_LOCATION = "service.location"; +#define CELIX_RSA_SERVICE_EXPORTED_INTERFACES "service.exported.interfaces" +#define CELIX_RSA_ENDPOINT_FRAMEWORK_UUID "endpoint.framework.uuid" +#define CELIX_RSA_ENDPOINT_SERVICE_ID "endpoint.service.id" +#define CELIX_RSA_ENDPOINT_ID "endpoint.id" +#define CELIX_RSA_SERVICE_IMPORTED "service.imported" +#define CELIX_RSA_SERVICE_IMPORTED_CONFIGS "service.imported.configs" +#define CELIX_RSA_SERVICE_EXPORTED_CONFIGS "service.exported.configs" +#define CELIX_RSA_SERVICE_LOCATION "service.location" /** * It identify which types of remote service configurations are supported by a distribution provider. * @ref https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1708968 */ -#define OSGI_RSA_REMOTE_CONFIGS_SUPPORTED "remote.configs.supported" +#define CELIX_RSA_REMOTE_CONFIGS_SUPPORTED "remote.configs.supported" #endif /* REMOTE_CONSTANTS_H_ */ diff --git a/bundles/remote_services/rsa_spi/include/remote_endpoint.h b/bundles/remote_services/rsa_spi/include/remote_endpoint.h index 45a1d7e9f..f96f22568 100644 --- a/bundles/remote_services/rsa_spi/include/remote_endpoint.h +++ b/bundles/remote_services/rsa_spi/include/remote_endpoint.h @@ -27,7 +27,7 @@ #ifndef REMOTE_ENDPOINT_H_ #define REMOTE_ENDPOINT_H_ -#define OSGI_RSA_REMOTE_ENDPOINT "remote_endpoint" +#define CELIX_RSA_REMOTE_ENDPOINT "remote_endpoint" typedef struct remote_endpoint remote_endpoint_t; diff --git a/bundles/remote_services/rsa_spi/include/remote_interceptor.h b/bundles/remote_services/rsa_spi/include/remote_interceptor.h index d1f501c1e..e8d726896 100644 --- a/bundles/remote_services/rsa_spi/include/remote_interceptor.h +++ b/bundles/remote_services/rsa_spi/include/remote_interceptor.h @@ -22,8 +22,8 @@ #include -#define REMOTE_INTERCEPTOR_SERVICE_NAME "remote.interceptor" -#define REMOTE_INTERCEPTOR_SERVICE_VERSION "1.0.0" +#define CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_NAME "remote.interceptor" +#define CELIX_RSA_REMOTE_INTERCEPTOR_SERVICE_VERSION "1.0.0" typedef struct remote_interceptor { void *handle; diff --git a/bundles/remote_services/rsa_spi/include/remote_proxy.h b/bundles/remote_services/rsa_spi/include/remote_proxy.h index 2643d01bd..78239d68e 100644 --- a/bundles/remote_services/rsa_spi/include/remote_proxy.h +++ b/bundles/remote_services/rsa_spi/include/remote_proxy.h @@ -30,8 +30,8 @@ #include "endpoint_listener.h" #include "remote_service_admin.h" -#define OSGI_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory" -#define OSGI_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout" +#define CELIX_RSA_REMOTE_PROXY_FACTORY "remote_proxy_factory" +#define CELIX_RSA_REMOTE_PROXY_TIMEOUT "remote_proxy_timeout" typedef celix_status_t (*sendToHandle)(remote_service_admin_t *remote_service_admin_ptr, endpoint_description_t *endpointDescription, char *request, char **reply, int* replyStatus); typedef celix_status_t (*createProxyService)(void *handle, endpoint_description_t *endpointDescription, remote_service_admin_t *rsa, sendToHandle sendToCallback, celix_properties_t *properties, void **service); diff --git a/bundles/remote_services/rsa_spi/include/remote_service_admin.h b/bundles/remote_services/rsa_spi/include/remote_service_admin.h index 346b11939..5c0ddd8df 100644 --- a/bundles/remote_services/rsa_spi/include/remote_service_admin.h +++ b/bundles/remote_services/rsa_spi/include/remote_service_admin.h @@ -32,7 +32,7 @@ #include "export_registration.h" #include "import_registration.h" -#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin" +#define CELIX_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin" typedef struct import_registration_factory import_registration_factory_t; diff --git a/bundles/remote_services/rsa_spi/include/rsa_request_handler_service.h b/bundles/remote_services/rsa_spi/include/rsa_request_handler_service.h index c94c19265..f13c50e8c 100644 --- a/bundles/remote_services/rsa_spi/include/rsa_request_handler_service.h +++ b/bundles/remote_services/rsa_spi/include/rsa_request_handler_service.h @@ -27,9 +27,9 @@ extern "C" { #include #include -#define RSA_REQUEST_HANDLER_SERVICE_NAME "rsa_request_handler_service" -#define RSA_REQUEST_HANDLER_SERVICE_VERSION "1.0.0" -#define RSA_REQUEST_HANDLER_SERVICE_USE_RANGE "[1.0.0,2)" +#define CELIX_RSA_REQUEST_HANDLER_SERVICE_NAME "rsa_request_handler_service" +#define CELIX_RSA_REQUEST_HANDLER_SERVICE_VERSION "1.0.0" +#define CELIX_RSA_REQUEST_HANDLER_SERVICE_USE_RANGE "[1.0.0,2)" /** * @brief The service handle RPC request diff --git a/bundles/remote_services/rsa_spi/include/rsa_request_sender_service.h b/bundles/remote_services/rsa_spi/include/rsa_request_sender_service.h index ba0cc62a0..8f0a0f4c3 100644 --- a/bundles/remote_services/rsa_spi/include/rsa_request_sender_service.h +++ b/bundles/remote_services/rsa_spi/include/rsa_request_sender_service.h @@ -28,9 +28,9 @@ extern "C" { #include #include -#define RSA_REQUEST_SENDER_SERVICE_NAME "rsa_request_sender_service" -#define RSA_REQUEST_SENDER_SERVICE_VERSION "1.0.0" -#define RSA_REQUEST_SENDER_SERVICE_USE_RANGE "[1.0.0,2)" +#define CELIX_RSA_REQUEST_SENDER_SERVICE_NAME "rsa_request_sender_service" +#define CELIX_RSA_REQUEST_SENDER_SERVICE_VERSION "1.0.0" +#define CELIX_RSA_REQUEST_SENDER_SERVICE_USE_RANGE "[1.0.0,2)" /** * @brief The service send RPC request diff --git a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h index 875b77b24..d1a112808 100644 --- a/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h +++ b/bundles/remote_services/rsa_spi/include/rsa_rpc_factory.h @@ -31,11 +31,11 @@ extern "C" { /** * @brief The RPC type indicates which protocol is used to (de)serialize the raw data. */ -#define RSA_RPC_TYPE_KEY "celix.remote.admin.rpc_type" +#define CELIX_RSA_RPC_TYPE_KEY "celix.remote.admin.rpc_type" -#define RSA_RPC_FACTORY_NAME "rsa_rpc_factory" -#define RSA_RPC_FACTORY_VERSION "1.0.0" -#define RSA_RPC_FACTORY_USE_RANGE "[1.0.0,2.0.0)" +#define CELIX_RSA_RPC_FACTORY_NAME "rsa_rpc_factory" +#define CELIX_RSA_RPC_FACTORY_VERSION "1.0.0" +#define CELIX_RSA_RPC_FACTORY_USE_RANGE "[1.0.0,2.0.0)" /** * @brief The service use to create remote service endpoint and remote service proxy diff --git a/bundles/remote_services/topology_manager/src/activator.c b/bundles/remote_services/topology_manager/src/activator.c index 79ed7c94a..62c5999a1 100644 --- a/bundles/remote_services/topology_manager/src/activator.c +++ b/bundles/remote_services/topology_manager/src/activator.c @@ -130,7 +130,7 @@ static celix_status_t bundleActivator_createEPLTracker(struct activator *activat status = serviceTrackerCustomizer_create(activator->manager, topologyManager_endpointListenerAdding, topologyManager_endpointListenerAdded, topologyManager_endpointListenerModified, topologyManager_endpointListenerRemoved, &customizer); if (status == CELIX_SUCCESS) { - status = serviceTracker_create(activator->context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, customizer, tracker); + status = serviceTracker_create(activator->context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, customizer, tracker); } return status; } @@ -140,7 +140,7 @@ static celix_status_t bundleActivator_createRSATracker(struct activator *activat service_tracker_customizer_t *customizer = NULL; status = serviceTrackerCustomizer_create(activator->manager, topologyManager_rsaAdding, topologyManager_rsaAdded, topologyManager_rsaModified, topologyManager_rsaRemoved, &customizer); if (status == CELIX_SUCCESS) { - status = serviceTracker_create(activator->context, OSGI_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker); + status = serviceTracker_create(activator->context, CELIX_RSA_REMOTE_SERVICE_ADMIN, customizer, tracker); } return status; } @@ -172,25 +172,25 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context return CELIX_ILLEGAL_STATE; } - size_t len = 14 + strlen(CELIX_FRAMEWORK_SERVICE_NAME) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); + size_t len = 14 + strlen(CELIX_FRAMEWORK_SERVICE_NAME) + strlen(CELIX_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); char *scope = malloc(len); if (!scope) { return CELIX_ENOMEM; } - snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", CELIX_FRAMEWORK_SERVICE_NAME, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + snprintf(scope, len, "(&(%s=*)(!(%s=%s)))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); celix_logHelper_log(activator->celix_logHelper, CELIX_LOG_LEVEL_INFO, "TOPOLOGY_MANAGER: endpoint listener scope is %s", scope); celix_properties_t *props = celix_properties_create(); // topology manager should ingore itself endpoint listener service celix_properties_set(props, "TOPOLOGY_MANAGER", "true"); - celix_properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); + celix_properties_set(props, (char *) CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); // We can release the scope, as celix_properties_set makes a copy of the key & value... free(scope); - bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &activator->endpointListenerService); + bundleContext_registerService(context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, endpointListener, props, &activator->endpointListenerService); listener_hook_service_pt hookService = malloc(sizeof(*hookService)); hookService->handle = activator->manager; diff --git a/bundles/remote_services/topology_manager/src/topology_manager.c b/bundles/remote_services/topology_manager/src/topology_manager.c index 5c91fefa7..b462fc7d7 100644 --- a/bundles/remote_services/topology_manager/src/topology_manager.c +++ b/bundles/remote_services/topology_manager/src/topology_manager.c @@ -358,7 +358,7 @@ celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) for (int i = 0; i < nrFound; i++) { // Question: can srvRefs become invalid meanwhile?? const char* export = NULL; - serviceReference_getProperty(srvRefs[i], (char *) OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export); + serviceReference_getProperty(srvRefs[i], (char *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &export); if (export) { celix_status_t substatus = topologyManager_removeExportedService_nolock(manager, srvRefs[i], srvIds[i]); @@ -532,7 +532,7 @@ static celix_status_t topologyManager_addExportedService_nolock(void * handle, s celix_properties_t *serviceProperties = NULL; const char *export = NULL; - serviceReference_getProperty(reference, OSGI_RSA_SERVICE_EXPORTED_INTERFACES, &export); + serviceReference_getProperty(reference, CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &export); assert(export != NULL); celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, "TOPOLOGY_MANAGER: Add exported service (%li).", serviceId); @@ -677,7 +677,7 @@ celix_status_t topologyManager_endpointListenerAdded(void* handle, service_refer hashMap_put(manager->listenerList, reference, NULL); - serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); celix_autoptr(celix_filter_t) filter = celix_filter_create(scope); @@ -755,7 +755,7 @@ static celix_status_t topologyManager_notifyListenersEndpointAdded(topology_mana endpoint_listener_t *epl = NULL; service_reference_pt reference = hashMapIterator_nextKey(iter); - serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); status = bundleContext_getService(manager->context, reference, (void **) &epl); if (status == CELIX_SUCCESS) { @@ -795,7 +795,7 @@ static celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_ma const char* scope = NULL; service_reference_pt reference = hashMapIterator_nextKey(iter); - serviceReference_getProperty(reference, OSGI_ENDPOINT_LISTENER_SCOPE, &scope); + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); substatus = bundleContext_getService(manager->context, reference, (void **) &epl); @@ -825,13 +825,13 @@ static celix_status_t topologyManager_extendFilter(topology_manager_pt manager, return CELIX_BUNDLE_EXCEPTION; } - int len = 10 + strlen(filter) + strlen(OSGI_RSA_ENDPOINT_FRAMEWORK_UUID) + strlen(uuid); + int len = 10 + strlen(filter) + strlen(CELIX_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, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); return status; } diff --git a/bundles/remote_services/topology_manager/src/topology_manager.h b/bundles/remote_services/topology_manager/src/topology_manager.h index e186d5761..116345745 100644 --- a/bundles/remote_services/topology_manager/src/topology_manager.h +++ b/bundles/remote_services/topology_manager/src/topology_manager.h @@ -33,7 +33,7 @@ #include "celix_log_helper.h" #include "scope.h" -#define OSGI_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin" +#define CELIX_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin" typedef struct topology_manager topology_manager_t; typedef struct topology_manager *topology_manager_pt; diff --git a/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c b/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c index bd5328bf4..4f156778b 100644 --- a/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c +++ b/bundles/remote_services/topology_manager/tms_tst/disc_mock/disc_mock_activator.c @@ -73,14 +73,14 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context } char* scope = NULL; - int rc = asprintf(&scope, "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); + int rc = asprintf(&scope, "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, uuid); status = rc < 0 ? CELIX_ENOMEM : CELIX_SUCCESS; celix_properties_t *props = NULL; if (status == CELIX_SUCCESS) { props = celix_properties_create(); celix_properties_set(props, "DISCOVERY", "true"); - celix_properties_set(props, (char *) OSGI_ENDPOINT_LISTENER_SCOPE, scope); + celix_properties_set(props, (char *) CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); } if (status == CELIX_SUCCESS) { @@ -91,7 +91,7 @@ celix_status_t celix_bundleActivator_start(void * userData, celix_bundle_context endpointListener->endpointAdded = discovery_endpointAdded; endpointListener->endpointRemoved = discovery_endpointRemoved; - status = bundleContext_registerService(context, (char *) OSGI_ENDPOINT_LISTENER_SERVICE, endpointListener, props, &act->endpointListenerService); + status = bundleContext_registerService(context, (char *) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, endpointListener, props, &act->endpointListenerService); if (status == CELIX_SUCCESS) { act->endpointListener = endpointListener; diff --git a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp index 971acb972..a7c64940e 100644 --- a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp +++ b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp @@ -90,7 +90,7 @@ extern "C" { rc = bundle_getContext(bundle, &context); EXPECT_EQ(CELIX_SUCCESS, rc); - rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef); + rc = bundleContext_getServiceReference(context, (char *)CELIX_RSA_REMOTE_SERVICE_ADMIN, &rsaRef); EXPECT_EQ(CELIX_SUCCESS, rc); EXPECT_TRUE(rsaRef != NULL); @@ -185,7 +185,7 @@ extern "C" { EXPECT_EQ(celix_arrayList_size(bundles), 4); //rsa, calculator, topman, test bundle celix_arrayList_destroy(bundles); - rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef); + rc = bundleContext_getServiceReference(context, (char *)CELIX_RSA_REMOTE_SERVICE_ADMIN, &rsaRef); EXPECT_EQ(CELIX_SUCCESS, rc); EXPECT_TRUE(rsaRef != NULL); @@ -206,7 +206,7 @@ extern "C" { rc = bundleContext_getService(context, testRef, (void **)&testImport); EXPECT_EQ(CELIX_SUCCESS, rc); - rc = bundleContext_getServiceReference(context, (char*)OSGI_ENDPOINT_LISTENER_SERVICE, &eplRef); + rc = bundleContext_getServiceReference(context, (char*) CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, &eplRef); EXPECT_EQ(CELIX_SUCCESS, rc); EXPECT_TRUE(eplRef != NULL); @@ -478,10 +478,10 @@ extern "C" { endpoint_description_t *endpoint = NULL; celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); @@ -531,10 +531,10 @@ extern "C" { endpoint_description_t *endpoint = NULL; celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); @@ -583,10 +583,10 @@ extern "C" { endpoint_description_t *endpoint = NULL; celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec @@ -630,10 +630,10 @@ extern "C" { endpoint_description_t *endpoint = NULL; celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); + celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); + celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); + celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); From 21b088f782dbd9638a3bd2d1ebcaee2e4fda8e56 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 19 Jan 2024 15:37:00 +0800 Subject: [PATCH 24/29] Fix code based on code review --- .../src/discovery_zeroconf_activator.c | 2 +- .../src/discovery_zeroconf_announcer.c | 18 ++++++++++-------- .../src/discovery_zeroconf_watcher.c | 18 +++++++++--------- .../rsa_shm/src/rsa_shm_import_registration.c | 4 ++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c index 222d25130..9fec2092a 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c @@ -66,7 +66,7 @@ celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t * (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(props, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); - celix_properties_set(props, "DISCOVERY", "true");//Only use to avoid the discovery calls to unnecessary endpoint listener service.Endpoint should be filtered by the scope. + celix_properties_set(props, "DISCOVERY", "true");//Only use to avoid the discovery calls to unnecessary endpoint listener service. Endpoint should be filtered by the scope. act->endpointListener.handle = act->announcer; act->endpointListener.endpointAdded = discoveryZeroconfAnnouncer_endpointAdded; act->endpointListener.endpointRemoved = discoveryZeroconfAnnouncer_endpointRemoved; diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index 736b583d0..e62468e1f 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -91,7 +91,7 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce celix_status_t status = CELIX_SUCCESS; celix_autofree discovery_zeroconf_announcer_t *announcer = (discovery_zeroconf_announcer_t *)calloc(1, sizeof(*announcer)); if (announcer == NULL) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to alloc announcer."); + celix_logHelper_error(logHelper, "Announcer: Failed to alloc announcer."); return CELIX_ENOMEM; } announcer->ctx = ctx; @@ -101,14 +101,14 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce announcer->eventFd = eventfd(0, 0); if (announcer->eventFd < 0) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to open event fd, %d.", errno); + celix_logHelper_error(logHelper, "Announcer: Failed to open event fd, %d.", errno); return CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO, errno); } celix_auto(celix_fd_t) eventFd = announcer->eventFd; status = celixThreadMutex_create(&announcer->mutex, NULL); if (status != CELIX_SUCCESS) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to create mutex, %d.", status); + celix_logHelper_error(logHelper, "Announcer: Failed to create mutex, %d.", status); return status; } celix_autoptr(celix_thread_mutex_t) mutex = &announcer->mutex; @@ -116,25 +116,25 @@ celix_status_t discoveryZeroconfAnnouncer_create(celix_bundle_context_t *ctx, ce celix_autoptr(celix_string_hash_map_t) endpoints = announcer->endpoints = celix_stringHashMap_create(); if (endpoints == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Announcer: Failed to create endpoints map."); + celix_logHelper_error(logHelper, "Announcer: Failed to create endpoints map."); return CELIX_ENOMEM; } celix_autoptr(celix_array_list_t) revokedEndpoints = announcer->revokedEndpoints = celix_arrayList_create(); if (revokedEndpoints == NULL) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to create revoked endpoints list."); + celix_logHelper_error(logHelper, "Announcer: Failed to create revoked endpoints list."); return CELIX_ENOMEM; } celix_autoptr(celix_string_hash_map_t) conflictCntMap = announcer->conflictCntMap = celix_stringHashMap_create(); if (conflictCntMap == NULL) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to create conflict count map."); + celix_logHelper_error(logHelper, "Announcer: Failed to create conflict count map."); return CELIX_ENOMEM; } announcer->running = true; status = celixThread_create(&announcer->refreshEPThread, NULL, discoveryZeroconfAnnouncer_refreshEndpointThread, announcer); if (status != CELIX_SUCCESS) { - celix_logHelper_fatal(logHelper, "Announcer: Failed to create refreshing endpoint thread, %d.", status); + celix_logHelper_error(logHelper, "Announcer: Failed to create refreshing endpoint thread, %d.", status); return status; } celixThread_setName(&announcer->refreshEPThread, "DiscAnnouncer"); @@ -631,7 +631,6 @@ static void *discoveryZeroconfAnnouncer_refreshEndpointThread(void *data) { } } } - running = announcer->running; celixThreadMutex_unlock(&announcer->mutex); discoveryZeroconfAnnouncer_revokeEndpoints(announcer, revokedEndpoints); @@ -647,6 +646,9 @@ static void *discoveryZeroconfAnnouncer_refreshEndpointThread(void *data) { celix_logHelper_error(announcer->logHelper, "Announcer: Error Selecting event, %d.", errno); sleep(1);//avoid busy loop } + celixThreadMutex_lock(&announcer->mutex); + running = announcer->running; + celixThreadMutex_unlock(&announcer->mutex); } if (announcer->sharedRef) { DNSServiceRefDeallocate(announcer->sharedRef); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 7071ce09c..4e5bfd21c 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -125,7 +125,7 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi celix_status_t status = CELIX_SUCCESS; celix_autofree discovery_zeroconf_watcher_t *watcher = (discovery_zeroconf_watcher_t *)calloc(1, sizeof(*watcher)); if (watcher == NULL) { - celix_logHelper_fatal(logHelper, "Watcher: Failed to alloc watcher."); + celix_logHelper_error(logHelper, "Watcher: Failed to alloc watcher."); return CELIX_ENOMEM; } watcher->logHelper = logHelper; @@ -133,28 +133,28 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi watcher->sharedRef = NULL; watcher->eventFd = eventfd(0, 0); if (watcher->eventFd < 0) { - celix_logHelper_fatal(logHelper, "Watcher: Failed to open event fd, %d.", errno); + celix_logHelper_error(logHelper, "Watcher: Failed to open event fd, %d.", errno); return CELIX_ERROR_MAKE(CELIX_FACILITY_CERRNO, errno); } celix_auto(celix_fd_t) eventFd = watcher->eventFd; const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, NULL); if (fwUuid == NULL || strlen(fwUuid) >= sizeof(watcher->fwUuid)) { - celix_logHelper_fatal(logHelper, "Watcher: Failed to get framework uuid."); + celix_logHelper_error(logHelper, "Watcher: Failed to get framework uuid."); return CELIX_BUNDLE_EXCEPTION; } strcpy(watcher->fwUuid, fwUuid); status = celixThreadMutex_create(&watcher->mutex, NULL); if (status != CELIX_SUCCESS) { - celix_logHelper_fatal(logHelper, "Watcher: Failed to create mutex, %d.", status); + celix_logHelper_error(logHelper, "Watcher: Failed to create mutex, %d.", status); return status; } celix_autoptr(celix_thread_mutex_t) mutex = &watcher->mutex; celix_autoptr(celix_string_hash_map_t) serviceBrowsers = watcher->serviceBrowsers = celix_stringHashMap_create(); if (serviceBrowsers == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Watcher: Failed to create service browsers map."); + celix_logHelper_error(logHelper, "Watcher: Failed to create service browsers map."); return CELIX_ENOMEM; } celix_string_hash_map_create_options_t epOpts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; @@ -163,27 +163,27 @@ celix_status_t discoveryZeroconfWatcher_create(celix_bundle_context_t *ctx, celi watcher->watchedEndpoints = celix_stringHashMap_createWithOptions(&epOpts); if (watchedEndpoints == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Watcher: Failed to create endpoints map."); + celix_logHelper_error(logHelper, "Watcher: Failed to create endpoints map."); return CELIX_ENOMEM; } celix_autoptr(celix_string_hash_map_t) watchedHosts = watcher->watchedHosts = celix_stringHashMap_create(); if (watchedHosts == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Watcher: Failed to create hosts map."); + celix_logHelper_error(logHelper, "Watcher: Failed to create hosts map."); return CELIX_ENOMEM; } celix_autoptr(celix_string_hash_map_t) watchedServices = watcher->watchedServices = celix_stringHashMap_create(); if (watchedServices == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Watcher: Failed to create services map."); + celix_logHelper_error(logHelper, "Watcher: Failed to create services map."); return CELIX_ENOMEM; } celix_autoptr(celix_long_hash_map_t) epls = watcher->epls = celix_longHashMap_create(); if (epls == NULL) { celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_fatal(logHelper, "Watcher: Failed to create endpoint listener map."); + celix_logHelper_error(logHelper, "Watcher: Failed to create endpoint listener map."); return CELIX_ENOMEM; } diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c index 3f3d86660..d232377b7 100644 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_import_registration.c @@ -73,8 +73,8 @@ celix_status_t importRegistration_create(celix_bundle_context_t *context, char filter[128] = {0}; int bytes = snprintf(filter, sizeof(filter), "(%s=%s)", CELIX_RSA_RPC_TYPE_KEY, rsaShmRpcType); if (bytes >= sizeof(filter)) { - celix_logHelper_error(logHelper, "RSA import reg: The value(%s) of %s is too long.", rsaShmRpcType, CELIX_RSA_RPC_TYPE_KEY); - return CELIX_ILLEGAL_ARGUMENT; + celix_logHelper_error(logHelper, "RSA import reg: The value(%s) of %s is too long.", rsaShmRpcType, CELIX_RSA_RPC_TYPE_KEY); + return CELIX_ILLEGAL_ARGUMENT; } celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; opts.filter.filter = filter; From e95dcefefddd8cd92dff660e3b0ab0e3de834f88 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Fri, 2 Feb 2024 15:23:48 +0800 Subject: [PATCH 25/29] Topology Manager implement dynamic IP mechanism --- bundles/remote_services/CMakeLists.txt | 8 +- .../DiscoveryZeroconfActivatorTestSuite.cc | 27 + .../DiscoveryZeroconfAnnouncerTestSuite.cc | 115 ++- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 352 ++++----- .../src/discovery_zeroconf_activator.c | 13 +- .../src/discovery_zeroconf_announcer.c | 149 ++-- .../src/discovery_zeroconf_watcher.c | 58 +- .../gtest/CMakeLists.txt | 4 + .../gtest/src/rsa_client_server_tests.cc | 142 ++++ .../gtest/src/rsa_tests.cc | 54 -- .../src/import_registration_dfi.c | 13 +- .../src/import_registration_dfi.h | 5 +- .../src/remote_service_admin_activator.c | 9 +- .../src/remote_service_admin_dfi.c | 227 +++--- .../src/remote_service_admin_dfi_constants.h | 21 +- .../rsa_spi/include/remote_constants.h | 33 +- .../topology_manager/CMakeLists.txt | 12 +- .../topology_manager/gtest/CMakeLists.txt | 64 ++ .../TopologyManagerErrorInjectionTestSuite.cc | 267 +++++++ .../gtest/src/TopologyManagerTestSuite.cc | 472 +++++++++++ .../src/TopologyManagerTestSuiteBaseClass.h | 274 +++++++ .../topology_manager/src/topology_manager.c | 748 ++++++++++++++---- .../topology_manager/tms_tst/tms_tests.cpp | 4 - libs/utils/include/celix_errno.h | 9 +- 24 files changed, 2410 insertions(+), 670 deletions(-) create mode 100644 bundles/remote_services/topology_manager/gtest/CMakeLists.txt create mode 100644 bundles/remote_services/topology_manager/gtest/src/TopologyManagerErrorInjectionTestSuite.cc create mode 100644 bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuite.cc create mode 100644 bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuiteBaseClass.h diff --git a/bundles/remote_services/CMakeLists.txt b/bundles/remote_services/CMakeLists.txt index 1d069192f..9525549f7 100644 --- a/bundles/remote_services/CMakeLists.txt +++ b/bundles/remote_services/CMakeLists.txt @@ -127,7 +127,9 @@ if (REMOTE_SERVICE_ADMIN) calculator USE_CONFIG PROPERTIES - CELIX_RSA_BIND_ON_ALL_INTERFACES=false + CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT=true + RSA_PORT=19999 + CELIX_RSA_INTERFACES_OF_PORT_19999=lo ) add_celix_container(remote-services-zeroconf-client @@ -147,7 +149,9 @@ if (REMOTE_SERVICE_ADMIN) calculator_shell USE_CONFIG PROPERTIES - CELIX_RSA_BIND_ON_ALL_INTERFACES=false + CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT=true + RSA_PORT=29999 + CELIX_RSA_INTERFACES_OF_PORT_29999=lo ) endif() diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc index 02d86c6bf..1ef6a94b2 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfActivatorTestSuite.cc @@ -51,6 +51,7 @@ class DiscoveryZeroconfActivatorTestSuite : public ::testing::Test { celix_ei_expect_celix_dmServiceDependency_create(nullptr, 0, nullptr); celix_ei_expect_celix_properties_create(nullptr, 0, nullptr); celix_ei_expect_celix_logHelper_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_set(nullptr, 0, 0); } std::shared_ptr fw{}; @@ -150,6 +151,32 @@ TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateAnnouncerEndpointListenerPrope EXPECT_EQ(CELIX_SUCCESS, status); } +TEST_F(DiscoveryZeroconfActivatorTestSuite, SetEndpointListenerSocpePropertyFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_properties_set((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + +TEST_F(DiscoveryZeroconfActivatorTestSuite, SetEndpointListenerInterfaceSpecificEndpointsPropertyFailed) { + void *act{nullptr}; + auto status = celix_bundleActivator_create(ctx.get(), &act); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_ei_expect_celix_properties_set((void*)&celix_bundleActivator_start, 1, CELIX_ENOMEM, 3); + status = celix_bundleActivator_start(act, ctx.get()); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = celix_bundleActivator_destroy(act, ctx.get()); + EXPECT_EQ(CELIX_SUCCESS, status); +} + TEST_F(DiscoveryZeroconfActivatorTestSuite, CreateWatcherDmComponentFailed) { void *act{nullptr}; auto status = celix_bundleActivator_create(ctx.get(), &act); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index 925f46623..af7bc489d 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -195,10 +195,9 @@ static void OnServiceBrowseCallback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType dnsErr = DNSServiceResolve(&dsRef, 0, interfaceIndex, instanceName, regtype, replyDomain, OnServiceResolveCallback, prop); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); - EXPECT_TRUE(celix_properties_getAsLong(prop, DZC_SERVICE_PROPERTIES_SIZE_KEY, 0) > 0); //The txt record should not include ifname and port key - EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_TEST_CONFIG_TYPE".ifname", nullptr)); - EXPECT_EQ(nullptr, celix_properties_get(prop, DZC_TEST_CONFIG_TYPE".port", nullptr)); + EXPECT_EQ(nullptr, celix_properties_get(prop, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, nullptr)); + EXPECT_EQ(nullptr, celix_properties_get(prop, CELIX_RSA_PORT, nullptr)); DNSServiceRefDeallocate(dsRef); celix_properties_destroy(prop); } @@ -208,10 +207,10 @@ static void TestAddEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announ const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); + celix_properties_set(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, "all"); } else if (ifIndex > 0) { char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); + celix_properties_set(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, if_indextoname(ifIndex, ifName)); } celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -223,7 +222,8 @@ static void TestAddEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announ auto status = endpointDescription_create(properties,&endpoint); EXPECT_EQ(status, CELIX_SUCCESS); - discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); int loopbackIfIndex = GetLoopBackIfIndex(); if (loopbackIfIndex != 0 && ifIndex == loopbackIfIndex) { @@ -237,7 +237,8 @@ static void TestAddEndpoint(celix_bundle_context *ctx, discovery_zeroconf_announ DNSServiceProcessResult(dsRef); DNSServiceRefDeallocate(dsRef); - discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); + status = discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); endpointDescription_destroy(endpoint); } @@ -284,6 +285,57 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveEndpointOnSpecificInterf discoveryZeroconfAnnouncer_destroy(announcer); } +TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddAndRemoveSameNameService) { + discovery_zeroconf_announcer_t *announcer{}; + auto status = discoveryZeroconfAnnouncer_create(ctx.get(), logHelper.get(), &announcer); + EXPECT_EQ(status, CELIX_SUCCESS); + + const char *fwUuid = celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); + celix_properties_t *properties1 = celix_properties_create(); + celix_properties_set(properties1, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(properties1, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); + celix_properties_set(properties1, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); + celix_properties_setLong(properties1, CELIX_RSA_ENDPOINT_SERVICE_ID, 100); + celix_properties_set(properties1, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(properties1, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); + endpoint_description_t *endpoint1{}; + status = endpointDescription_create(properties1,&endpoint1); + EXPECT_EQ(status, CELIX_SUCCESS); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint1, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + celix_properties_t *properties2 = celix_properties_copy(properties1); + celix_properties_set(properties2, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d20"); + endpoint_description_t *endpoint2{}; + status = endpointDescription_create(properties2,&endpoint2); + EXPECT_EQ(status, CELIX_SUCCESS); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint2, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + status = discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint2, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint2, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + status = discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint1, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + DNSServiceRef dsRef{nullptr}; + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", [](DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char *, const char *, const char *, void *){}, + nullptr); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + DNSServiceProcessResult(dsRef); + DNSServiceRefDeallocate(dsRef); + + status = discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint2, nullptr); + EXPECT_EQ(status, CELIX_SUCCESS); + + endpointDescription_destroy(endpoint1); + endpointDescription_destroy(endpoint2); + + discoveryZeroconfAnnouncer_destroy(announcer); +} + static void TestAddEndPointForRegisterServiceFailure(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); @@ -380,10 +432,7 @@ static void TestAddJumboEndpoint(celix_bundle_context *ctx, discovery_zeroconf_a const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); if (ifIndex == kDNSServiceInterfaceIndexAny) { - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); - } else if (ifIndex > 0) { - char ifName[IF_NAMESIZE] = {0}; - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", if_indextoname(ifIndex, ifName)); + celix_properties_set(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, "all"); } celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); @@ -402,11 +451,27 @@ static void TestAddJumboEndpoint(celix_bundle_context *ctx, discovery_zeroconf_a discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", OnServiceBrowseCallback, NULL); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - DNSServiceProcessResult(dsRef); - DNSServiceRefDeallocate(dsRef); + bool found = false; + while (!found) { + DNSServiceRef dsRef{}; + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", + [](DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char*, const char*, const char*, void* context){ + auto *found = static_cast(context); + *found = true; + }, &found); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(DNSServiceRefSockFD(dsRef), &readfds); + struct timeval tv{}; + tv.tv_sec = 3; + tv.tv_usec = 0; + int ret = select(DNSServiceRefSockFD(dsRef) + 1, &readfds, nullptr, nullptr, &tv); + if (ret > 0) { + DNSServiceProcessResult(dsRef); + } + DNSServiceRefDeallocate(dsRef); + } discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); @@ -451,24 +516,16 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf //Invalid service type status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + EXPECT_EQ(status, CELIX_ENOMEM); //ifname not exist celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, DZC_TEST_CONFIG_TYPE); - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "if_not_exist"); + celix_properties_set(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, "if_not_exist"); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); //ifname too long - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "ifname__too__long"); - status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); - - //imported config too long - celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"); - status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); - celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.imported_config_too_long_for_ifname-------------------------------------------------------------------------.subtype"); + celix_properties_set(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, "ifname__too__long"); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); @@ -480,8 +537,9 @@ static void TestAddInvalidEndpoint(celix_bundle_context *ctx, discovery_zeroconf offset += snprintf(configTypes + offset, 256 - offset, ",config_type-%d", ++i); } celix_properties_set(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, configTypes); + celix_properties_unset(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE); status = discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - EXPECT_EQ(status, CELIX_ILLEGAL_ARGUMENT); + EXPECT_EQ(status, CELIX_ENOMEM); //lost imported config celix_properties_unset(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS); @@ -508,7 +566,6 @@ TEST_F(DiscoveryZeroconfAnnouncerTestSuite, AddInvalidEndpoint) { static void TestAddEndpointWithENOMEM(celix_bundle_context *ctx, discovery_zeroconf_announcer_t *announcer) { const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); celix_properties_t *properties = celix_properties_create(); - celix_properties_set(properties, DZC_TEST_CONFIG_TYPE".ifname", "all"); celix_properties_set(properties, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_NAME, "dzc_test_service"); celix_properties_set(properties, CELIX_RSA_ENDPOINT_ID, "60f49d89-d105-430c-b12b-93fbb54b1d19"); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index e2e2afe57..8ff532ce8 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -337,6 +337,77 @@ class DiscoveryZeroconfWatcherTestSuite : public ::testing::Test { long rsaSvcId{-1}; }; + +class DiscoveryZeroconfWatcherWatchServiceTestSuite : public DiscoveryZeroconfWatcherTestSuite { +public: + static void SetUpTestCase() { + (void)system(MDNSD); + sleep(3);//wait for mdnsd start + testServiceRef = RegisterTestService(GetTestNetInterfaceIndex()); + EXPECT_TRUE(testServiceRef != nullptr); + bool found = false; + while (!found) { + DNSServiceRef dsRef{}; + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", + [](DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) { + (void)sdRef; + (void)flags; + (void)interfaceIndex; + (void)errorCode; + (void)serviceName; + (void)regtype; + (void)replyDomain; + auto *found = static_cast(context); + *found = true; + }, &found); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(DNSServiceRefSockFD(dsRef), &readfds); + struct timeval tv{}; + tv.tv_sec = 3; + tv.tv_usec = 0; + int ret = select(DNSServiceRefSockFD(dsRef) + 1, &readfds, nullptr, nullptr, &tv); + if (ret > 0) { + DNSServiceProcessResult(dsRef); + } + DNSServiceRefDeallocate(dsRef); + } + } + + static void TearDownTestCase() { + DNSServiceRefDeallocate(testServiceRef); + (void)system("kill -s 9 `ps -aux | grep mdnsd | awk '{print $2}'`"); + } + + DiscoveryZeroconfWatcherWatchServiceTestSuite() { + discovery_zeroconf_watcher_t *watcherPtr{}; + celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcherPtr); + EXPECT_EQ(CELIX_SUCCESS, status); + (void)GetTestNetInterfaceIndex; + watcher = std::shared_ptr{watcherPtr, [](auto w){discoveryZeroconfWatcher_destroy(w);}}; + } + + ~DiscoveryZeroconfWatcherWatchServiceTestSuite() override = default; + + void TestWatchService(void (*beforeWatchServiceAction)(void), void (*afterWatchServiceAction)(void)) { + + beforeWatchServiceAction(); + + auto eplTrkId = TrackEndpointListenerService(watcher.get()); + auto rsaTrkId = TrackRsaService(watcher.get()); + + afterWatchServiceAction(); + + celix_bundleContext_stopTracker(ctx.get(), eplTrkId); + celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); + } + + std::shared_ptr watcher{}; + static DNSServiceRef testServiceRef; +}; +DNSServiceRef DiscoveryZeroconfWatcherWatchServiceTestSuite::testServiceRef{nullptr}; + TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateAndDestroyWatcher) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); @@ -511,6 +582,7 @@ static DNSServiceRef RegisterTestService(int ifIndex, const char *endpointId, co TXTRecordSetValue(&txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, strlen(serviceId), serviceId); TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED, strlen("true"), "true"); TXTRecordSetValue(&txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, sizeof(DZC_TEST_CONFIG_TYPE) - 1, DZC_TEST_CONFIG_TYPE); + TXTRecordSetValue(&txtRecord, CELIX_RSA_IP_ADDRESSES, 0, nullptr); char propSizeStr[16]= {0}; sprintf(propSizeStr, "%d", TXTRecordGetCount(TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord)) + 1); TXTRecordSetValue(&txtRecord, DZC_SERVICE_PROPERTIES_SIZE_KEY, strlen(propSizeStr), propSizeStr); @@ -525,8 +597,10 @@ static DNSServiceRef RegisterTestService(int ifIndex, const char *endpointId, co DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_TEST_SERVICE_PORT), TXTRecordGetLength(&txtRecord), TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - DNSServiceProcessResult(dsRef); + if (dnsErr == kDNSServiceErr_NoError) { + DNSServiceProcessResult(dsRef); + } + return dsRef; } @@ -539,45 +613,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpoint) { }); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, AddMultiEndpoint) { - discovery_zeroconf_watcher_t *watcher; - celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); - EXPECT_EQ(CELIX_SUCCESS, status); - auto rsaTrkId = TrackRsaService(watcher); - auto eplTrkId = TrackEndpointListenerService(watcher); - - ExpectMsgOutPut("Endpoint added: %s."); - - auto dsRef1 = RegisterTestService(kDNSServiceInterfaceIndexAny); - auto dsRef2 = RegisterTestService(kDNSServiceInterfaceIndexAny, "65d17a8c-f31b-478c-b13e-da743c96ab51", "101"); - - //wait for endpoint1 added - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - - //wait for endpoint2 added - timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - - ExpectMsgOutPut("Endpoint removed: %s."); - - DNSServiceRefDeallocate(dsRef1); - - //wait for endpoint1 added - timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - - DNSServiceRefDeallocate(dsRef2); - - //wait for endpoint2 added - timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - - celix_bundleContext_stopTracker(ctx.get(), eplTrkId); - celix_bundleContext_stopTracker(ctx.get(), rsaTrkId); - discoveryZeroconfWatcher_destroy(watcher); -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyEndpointProperties) { TestAddEndpoint([](){ celix_ei_expect_celix_properties_copy(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); @@ -610,17 +645,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToCopyHostNameForEndpointEntry) }); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetHostIpAddressesWhenCreateEndpoint) { - TestAddEndpoint([](){ - celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); - ExpectMsgOutPut("Watcher: Failed to create endpoint for %s. %d."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, GetTestNetInterfaceIndex()); - sleep(2);//wait for mdnsd remove service, avoid affect other test case -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetLocalHostIpAddressesWhenCreateEndpoint) { TestAddEndpoint([](){ celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); @@ -631,16 +655,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToGetLocalHostIpAddressesWhenCre }, kDNSServiceInterfaceIndexLocalOnly); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupImportedConfigsWhenCreateEndpoint) { - TestAddEndpoint([](){ - celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 6); - ExpectMsgOutPut("Watcher: Failed to dup imported configs."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutEndpointToCache) { celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 4); TestAddEndpoint([](){ @@ -666,58 +680,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidEndpoint) { }); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, NoImportedConfigs) { - TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ - TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); - TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); - //NO imported configs - ExpectMsgOutPut("Watcher: No imported configs."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs1) { - TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ - TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); - TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); - const char *invalidImportedConfigs = "celix.imported_config_too_long_for_port-----------------------------------------------------------------------------.subtype"; - TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); - - ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, InvalidImportedConfigs2) { - TestInvalidTxtRecord([](TXTRecordRef *txtRecord){ - TXTRecordSetValue(txtRecord, DZC_TXT_RECORD_VERSION_KEY, sizeof(DZC_CURRENT_TXT_RECORD_VERSION)-1, DZC_CURRENT_TXT_RECORD_VERSION); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, strlen(DZC_TEST_ENDPOINT_FW_UUID), DZC_TEST_ENDPOINT_FW_UUID); - TXTRecordSetValue(txtRecord, CELIX_FRAMEWORK_SERVICE_NAME, sizeof("dzc_test_service")-1, "dzc_test_service"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_ID, sizeof("65d17a8c-f31b-478c-b13e-da743c96ab51")-1, "65d17a8c-f31b-478c-b13e-da743c96ab51"); - TXTRecordSetValue(txtRecord, CELIX_RSA_ENDPOINT_SERVICE_ID, sizeof("100")-1, "100"); - TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED, sizeof("true")-1, "true"); - const char *invalidImportedConfigs = "celix.imported_config_too_long_for_ipaddresses--------------------------------------------------------------------.subtype"; - TXTRecordSetValue(txtRecord, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, strlen(invalidImportedConfigs), invalidImportedConfigs); - - ExpectMsgOutPut("Watcher: The length of imported config type %s is too long."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, CreateDNSServiceConnectionFailedOnce) { discovery_zeroconf_watcher_t *watcher; @@ -1002,66 +964,6 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveSelfFrameworkEndpoint) { discoveryZeroconfWatcher_destroy(watcher); } -TEST_F(DiscoveryZeroconfWatcherTestSuite, DNSServiceGetAddrInfoFailedOnce) { - TestAddEndpoint([](){ - celix_ei_expect_DNSServiceGetAddrInfo(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory); - ExpectMsgOutPut("Watcher: Failed to get address info for %s on %d, %d."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, kDNSServiceInterfaceIndexAny); - sleep(2);//wait for mdnsd remove service, avoid affect other test case -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForHostEntry) { - TestAddEndpoint([](){ - celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 3);//first calloc:service_browser_entry_t; second calloc:watched_service_entry_t - ExpectMsgOutPut("Watcher: Failed to alloc host entry for %s."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, GetTestNetInterfaceIndex()); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToDupHostNameForHostEntry) { - TestAddEndpoint([](){ - celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 3); - ExpectMsgOutPut("Watcher: Failed to dup hostname for %s."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, GetTestNetInterfaceIndex()); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutHostEntryToCache) { - celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 4); - TestAddEndpoint([](){ - ExpectMsgOutPut("Watcher: Failed to add host entry for %s."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }, GetTestNetInterfaceIndex()); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, GetAddrInfo) { - ExpectMsgOutPut("Endpoint added: %s."); - TestGetAddrInfo([](){ - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - -TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToPutIpToHostEntry) { - TestGetAddrInfo([](){ - celix_ei_expect_celix_stringHashMap_putBool(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); - ExpectMsgOutPut("Watcher: Failed to add ip address(%s). %d."); - }, [](){ - auto timeOut = CheckMsgWithTimeOutInS(30); - EXPECT_FALSE(timeOut); - }); -} - TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { discovery_zeroconf_watcher_t *watcher; celix_status_t status = discoveryZeroconfWatcher_create(ctx.get(), logHelper.get(), &watcher); @@ -1087,8 +989,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddTxtRecord) { DNSServiceRef dsRef{}; DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexAny, "dzc_test_service", - DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), - TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), + TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback, nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); TXTRecordDeallocate(&txtRecord); @@ -1139,8 +1041,8 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, AddAndRemoveEndpointListener) { DNSServiceRef dsRef{}; DNSServiceErrorType dnsErr = DNSServiceRegister(&dsRef, 0, kDNSServiceInterfaceIndexLocalOnly, "dzc_test_service", - DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), - TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); + DZC_TEST_SERVICE_TYPE, "local", nullptr, htons(DZC_PORT_DEFAULT), TXTRecordGetLength(&txtRecord), + TXTRecordGetBytesPtr(&txtRecord), OnDNSServiceRegisterCallback,nullptr); EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); DNSServiceProcessResult(dsRef); @@ -1173,4 +1075,98 @@ TEST_F(DiscoveryZeroconfWatcherTestSuite, FailedToAllocMemoryForEPL) { celix_bundleContext_stopTracker(ctx.get(), eplTrkId); discoveryZeroconfWatcher_destroy(watcher); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, FailedToGetHostIpAddressesWhenCreateEndpoint) { + TestWatchService([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 5); + ExpectMsgOutPut("Watcher: Failed to create endpoint for %s. %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30000); + EXPECT_FALSE(timeOut); + }); +} + + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, DNSServiceGetAddrInfoFailedOnce) { + TestWatchService([](){ + celix_ei_expect_DNSServiceGetAddrInfo(CELIX_EI_UNKNOWN_CALLER, 0, kDNSServiceErr_NoMemory); + ExpectMsgOutPut("Watcher: Failed to get address info for %s on %d, %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, FailedToAllocMemoryForHostEntry) { + TestWatchService([](){ + celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 4);//first calloc:watched_epl_entry_t; second calloc:service_browser_entry_t; third calloc:watched_service_entry_t + ExpectMsgOutPut("Watcher: Failed to alloc host entry for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, FailedToDupHostNameForHostEntry) { + TestWatchService([](){ + celix_ei_expect_celix_utils_strdup(CELIX_EI_UNKNOWN_CALLER, 0, nullptr, 3); + ExpectMsgOutPut("Watcher: Failed to dup hostname for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, FailedToPutHostEntryToCache) { + TestWatchService([](){ + celix_ei_expect_celix_stringHashMap_put(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM, 4); + ExpectMsgOutPut("Watcher: Failed to add host entry for %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, GetAddrInfo) { + TestWatchService([](){ + ExpectMsgOutPut("Endpoint added: %s."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, FailedToPutIpToHostEntry) { + TestWatchService([](){ + celix_ei_expect_celix_stringHashMap_putBool(CELIX_EI_UNKNOWN_CALLER, 0, CELIX_ENOMEM); + ExpectMsgOutPut("Watcher: Failed to add ip address(%s). %d."); + }, [](){ + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); +} + +TEST_F(DiscoveryZeroconfWatcherWatchServiceTestSuite, AddMultiEndpoint) { + TestWatchService([](){ + ExpectMsgOutPut("Endpoint added: %s."); + }, [](){ + //wait for endpoint1 added + auto timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + //register service2 + auto dsRef2 = RegisterTestService(kDNSServiceInterfaceIndexAny, "65d17a8c-f31b-478c-b13e-da743c96ab51", "101"); + + //wait for endpoint2 added + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + + ExpectMsgOutPut("Endpoint removed: %s."); + DNSServiceRefDeallocate(dsRef2); + + //wait for endpoint2 added + timeOut = CheckMsgWithTimeOutInS(30); + EXPECT_FALSE(timeOut); + }); } \ No newline at end of file diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c index 9fec2092a..70d0ac9ec 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_activator.c @@ -58,20 +58,27 @@ celix_status_t discoveryZeroconfActivator_start(discovery_zeroconf_activator_t * } celix_dmComponent_setImplementation(announcerCmp, act->announcer); CELIX_DM_COMPONENT_SET_IMPLEMENTATION_DESTROY_FUNCTION(announcerCmp, discovery_zeroconf_announcer_t, discoveryZeroconfAnnouncer_destroy); - celix_properties_t *props = celix_properties_create(); + celix_autoptr(celix_properties_t) props = celix_properties_create(); if (props == NULL) { return CELIX_ENOMEM; } char scope[256] = {0}; (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); - celix_properties_set(props, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); + status = celix_properties_set(props, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); + if (status != CELIX_SUCCESS) { + return status; + } celix_properties_set(props, "DISCOVERY", "true");//Only use to avoid the discovery calls to unnecessary endpoint listener service. Endpoint should be filtered by the scope. + status = celix_properties_set(props, CELIX_RSA_DISCOVERY_INTERFACE_SPECIFIC_ENDPOINTS_SUPPORT, "true"); + if (status != CELIX_SUCCESS) { + return status; + } act->endpointListener.handle = act->announcer; act->endpointListener.endpointAdded = discoveryZeroconfAnnouncer_endpointAdded; act->endpointListener.endpointRemoved = discoveryZeroconfAnnouncer_endpointRemoved; celix_dmComponent_addInterface(announcerCmp, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, NULL, - &act->endpointListener, props); + &act->endpointListener, celix_steal_ptr(props)); //init watcher celix_autoptr(celix_dm_component_t) watcherCmp = celix_dmComponent_create(ctx, "DZC_WATCHER_CMP"); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c index e62468e1f..154687663 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_announcer.c @@ -222,16 +222,71 @@ static int discoveryZeroconfAnnouncer_setServiceSubTypeTo(discovery_zeroconf_ann return CELIX_SUCCESS; } -static int discoveryZeroconfAnnouncer_createEndpointEntry(discovery_zeroconf_announcer_t *announcer, const char *ifName, int port, const celix_string_hash_map_t *svcSubTypes, celix_properties_t *properties, announce_endpoint_entry_t **entryOut) { - celix_autoptr(celix_properties_t) propertiesPtr = properties; +static char* discoveryZeroconfAnnouncer_createServiceTypeAccordingToConfigTypes(discovery_zeroconf_announcer_t* announcer, const char* configTypes) { + celix_string_hash_map_create_options_t opts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; + opts.storeKeysWeakly = true; + celix_autoptr(celix_string_hash_map_t) svcSubTypes = celix_stringHashMap_createWithOptions(&opts); + if (svcSubTypes == NULL) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create svc sub types map."); + return NULL; + } + celix_autofree char *configTypesCopy = celix_utils_strdup(configTypes); + if (configTypesCopy == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to dup config types."); + return NULL; + } + char *savePtr = NULL; + char *token = strtok_r(configTypesCopy, ",", &savePtr); + while (token != NULL) { + token = celix_utils_trimInPlace(token); + int status = discoveryZeroconfAnnouncer_setServiceSubTypeTo(announcer, token, svcSubTypes); + if (status != CELIX_SUCCESS) { + return NULL; + } + token = strtok_r(NULL, ",", &savePtr); + } + + char serviceType[DZC_MAX_SERVICE_TYPE_LEN] = {0}; + CELIX_BUILD_ASSERT(sizeof(serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); + strcpy(serviceType, DZC_SERVICE_PRIMARY_TYPE); + size_t offset = strlen(serviceType); + CELIX_STRING_HASH_MAP_ITERATE(svcSubTypes, iter) { + offset += snprintf(serviceType + offset, sizeof(serviceType) - offset, ",%s", iter.key); + if (offset >= sizeof(serviceType)) { + celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of imported configs for %s.", serviceType); + return NULL; + } + } + return celix_utils_strdup(serviceType); +} + +static int discoveryZeroconfAnnouncer_createEndpointEntry(discovery_zeroconf_announcer_t *announcer, endpoint_description_t *endpoint, announce_endpoint_entry_t **entryOut) { + celix_autoptr(celix_properties_t) properties = celix_properties_copy(endpoint->properties); + if (properties == NULL) { + celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy endpoint properties for %s.", endpoint->serviceName); + return CELIX_ENOMEM; + } + const char* serviceName = celix_properties_get(properties, CELIX_FRAMEWORK_SERVICE_NAME, NULL); + if (serviceName == NULL) { + celix_logHelper_error(announcer->logHelper,"Announcer: Invalid service."); + return CELIX_ILLEGAL_ARGUMENT; + } + const char *importedConfigs = celix_properties_get(properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + if (importedConfigs == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: No imported configs for %s.", serviceName); + return CELIX_ILLEGAL_ARGUMENT; + } celix_autofree announce_endpoint_entry_t *entry = (announce_endpoint_entry_t *)calloc(1, sizeof(*entry)); if (entry == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to alloc endpoint entry."); + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to alloc endpoint entry for %s.", serviceName); return CELIX_ENOMEM; } entry->registerRef = NULL; entry->announced = false; entry->conflictCnt = 0; + const char *ifName = celix_properties_get(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, NULL); if (ifName != NULL) { if (strcmp(ifName, "all") == 0) { entry->ifIndex = kDNSServiceInterfaceIndexAny; @@ -249,31 +304,17 @@ static int discoveryZeroconfAnnouncer_createEndpointEntry(discovery_zeroconf_ann } else { entry->ifIndex = DZC_SERVICE_ANNOUNCED_IF_INDEX_DEFAULT; } - entry->port = port; + entry->port = celix_properties_getAsLong(properties, CELIX_RSA_PORT, DZC_PORT_DEFAULT); - char serviceType[DZC_MAX_SERVICE_TYPE_LEN] = {0}; - CELIX_BUILD_ASSERT(sizeof(serviceType) >= sizeof(DZC_SERVICE_PRIMARY_TYPE)); - strcpy(serviceType, DZC_SERVICE_PRIMARY_TYPE); - size_t offset = strlen(serviceType); - CELIX_STRING_HASH_MAP_ITERATE(svcSubTypes, iter) { - offset += snprintf(serviceType + offset, sizeof(serviceType) - offset, ",%s", iter.key); - if (offset >= sizeof(serviceType)) { - celix_logHelper_error(announcer->logHelper, "Announcer: Please reduce the length of imported configs for %s.", serviceType); - return CELIX_ILLEGAL_ARGUMENT; - } - } - celix_autofree char *serviceTypePtr = entry->serviceType = celix_utils_strdup(serviceType); - if (serviceTypePtr == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy service type."); + entry->serviceType = discoveryZeroconfAnnouncer_createServiceTypeAccordingToConfigTypes(announcer, importedConfigs); + if (entry->serviceType == NULL) { + celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create service type for %s.", serviceName); return CELIX_ENOMEM; } - entry->serviceName = celix_properties_get(propertiesPtr, CELIX_FRAMEWORK_SERVICE_NAME, NULL); - if (entry->serviceName == NULL) { - celix_logHelper_error(announcer->logHelper,"Announcer: Invalid service."); - return CELIX_ILLEGAL_ARGUMENT; - } - entry->properties = celix_steal_ptr(propertiesPtr); - celix_steal_ptr(serviceTypePtr); + entry->serviceName = serviceName; + celix_properties_unset(properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE);//ifname should not set to mDNS TXT record, because service consumer will not use it. + celix_properties_unset(properties, CELIX_RSA_PORT);//port should not set to mDNS TXT record, because it will be set to SRV record. see https://www.rfc-editor.org/rfc/rfc6763.html#section-6.3 + entry->properties = celix_steal_ptr(properties); *entryOut = celix_steal_ptr(entry); return CELIX_SUCCESS; } @@ -323,63 +364,8 @@ celix_status_t discoveryZeroconfAnnouncer_endpointAdded(void *handle, endpoint_d celix_logHelper_info(announcer->logHelper, "Announcer: Add endpoint for %s(%s).", endpoint->serviceName, endpoint->id); - const char *importedConfigs = celix_properties_get(endpoint->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); - if (importedConfigs == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: No imported configs for %s.", endpoint->serviceName); - return CELIX_ILLEGAL_ARGUMENT; - } - - celix_autoptr(celix_properties_t) properties = celix_properties_copy(endpoint->properties); - if (properties == NULL) { - celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to copy endpoint properties."); - return CELIX_ENOMEM; - } - celix_string_hash_map_create_options_t opts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; - opts.storeKeysWeakly = true; - celix_autoptr(celix_string_hash_map_t) svcSubTypes = celix_stringHashMap_createWithOptions(&opts); - if (svcSubTypes == NULL) { - celix_logHelper_logTssErrors(announcer->logHelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to create svc sub types map."); - return CELIX_ENOMEM; - } - celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); - if (importedConfigsCopy == NULL) { - celix_logHelper_error(announcer->logHelper, "Announcer: Failed to dup imported configs."); - return CELIX_ENOMEM; - } - const char *ifName = NULL; - int port = DZC_PORT_DEFAULT; - char *savePtr = NULL; - char *token = strtok_r(importedConfigsCopy, ",", &savePtr); - while (token != NULL) { - token = celix_utils_trimInPlace(token); - char key[128] = {0}; - if(snprintf(key, sizeof(key), "%s.port", token) >= sizeof(key)) { - celix_logHelper_error(announcer->logHelper, "Announcer: The length of imported config type %s is too long.", token); - return CELIX_ILLEGAL_ARGUMENT; - } - //We only need to get one imported config port/ifname property, because all imported configs listed in this property must be synonymous(see https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1710847). - port = (int)celix_properties_getAsLong(endpoint->properties, key, port); - celix_properties_unset(properties, key);//port should not set to mDNS TXT record, because it will be set to SRV record. see https://www.rfc-editor.org/rfc/rfc6763.html#section-6.3 - - if(snprintf(key, sizeof(key), "%s.ifname", token) >= sizeof(key)) { - celix_logHelper_error(announcer->logHelper, "Announcer: The length of imported config type %s is too long.", token); - return CELIX_ILLEGAL_ARGUMENT; - } - ifName = celix_properties_get(endpoint->properties, key, ifName); - celix_properties_unset(properties, key);//ifname should not set to mDNS TXT record, because service consumer will not use it. - - status = discoveryZeroconfAnnouncer_setServiceSubTypeTo(announcer, token, svcSubTypes); - if (status != CELIX_SUCCESS) { - return status; - } - - token = strtok_r(NULL, ",", &savePtr); - } - celix_autoptr(announce_endpoint_entry_t) entry = NULL; - status = discoveryZeroconfAnnouncer_createEndpointEntry(announcer, ifName, port, svcSubTypes, celix_steal_ptr(properties), &entry); + status = discoveryZeroconfAnnouncer_createEndpointEntry(announcer, endpoint, &entry); if (status != CELIX_SUCCESS) { return status; } @@ -446,6 +432,7 @@ static void discoveryZeroconfAnnouncer_revokeEndpoints(discovery_zeroconf_announ for (int i = 0; i < size; ++i) { entry = celix_arrayList_get(endpoints, i); if (entry->registerRef != NULL) { + celix_logHelper_info(announcer->logHelper, "Announcer: Deregister service %s on interface %d.", entry->serviceName, entry->ifIndex); DNSServiceRefDeallocate(entry->registerRef); } endpointEntry_destroy(entry); diff --git a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c index 4e5bfd21c..203cca0f8 100644 --- a/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c +++ b/bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c @@ -448,7 +448,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, const char *version = celix_properties_get(properties, DZC_TXT_RECORD_VERSION_KEY, ""); if (propSize == celix_properties_size(properties) && strcmp(DZC_CURRENT_TXT_RECORD_VERSION, version) == 0) { svcEntry->port = ntohs(port); - if (svcEntry->ifIndex != kDNSServiceInterfaceIndexLocalOnly || svcEntry->port != DZC_PORT_DEFAULT) {//if it is not network service, no need to resolve ip address + if (celix_properties_get(properties, CELIX_RSA_IP_ADDRESSES, NULL) != NULL) {//If no need fill in dynamic ip address, no need to resolve ip address free(svcEntry->hostname);//free old hostname svcEntry->hostname = celix_utils_strdup(host); if (svcEntry->hostname == NULL) { @@ -461,6 +461,7 @@ static void OnServiceResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, celix_properties_unset(properties, DZC_SERVICE_PROPERTIES_SIZE_KEY);//Service endpoint do not need it celix_properties_unset(properties, DZC_TXT_RECORD_VERSION_KEY);//Service endpoint do not need it svcEntry->resolved = true; + celix_logHelper_trace(svcEntry->logHelper, "Watcher: Resolved service %s on %u.", svcEntry->instanceName, interfaceIndex); } return; } @@ -533,6 +534,7 @@ static void discoveryZeroconfWatcher_pickUpdatedServiceBrowsers(discovery_zeroco while (!celix_stringHashMapIterator_isEnd(&iter2)) { service_browser_entry_t *browserEntry = (service_browser_entry_t *)iter2.value.ptrValue; if (browserEntry->markDeleted) { + celix_logHelper_trace(watcher->logHelper, "Watcher: Stop to browse service type %s,%s.", DZC_SERVICE_PRIMARY_TYPE, iter2.key); celix_stringHashMapIterator_remove(&iter2); if (browserEntry->browseRef) { DNSServiceRefDeallocate(browserEntry->browseRef); @@ -556,6 +558,7 @@ static void discoveryZeroconfWatcher_browseServices(discovery_zeroconf_watcher_t browserEntry->browseRef = watcher->sharedRef; char serviceType[128] = {0};//primary type(15bytes) + subtype(63bytes) (void)snprintf(serviceType, sizeof(serviceType), "%s,%s", DZC_SERVICE_PRIMARY_TYPE, iter.key); + celix_logHelper_trace(watcher->logHelper, "Watcher: Start to browse service type %s.", serviceType); DNSServiceErrorType dnsErr = DNSServiceBrowse(&browserEntry->browseRef, kDNSServiceFlagsShareConnection, 0, serviceType, "local", OnServiceBrowseCallback, browserEntry); if (dnsErr != kDNSServiceErr_NoError) { celix_logHelper_error(watcher->logHelper, "Watcher: Failed to browse DNS service, %d.", dnsErr); @@ -575,6 +578,7 @@ static void discoveryZeroconfWatcher_resolveServices(discovery_zeroconf_watcher_ CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; if (watcher->sharedRef && svcEntry->resolveRef == NULL && svcEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { + celix_logHelper_trace(watcher->logHelper, "Watcher: Start to resolve service %s on %d.", svcEntry->instanceName, svcEntry->ifIndex); svcEntry->resolveRef = watcher->sharedRef; DNSServiceErrorType dnsErr = DNSServiceResolve(&svcEntry->resolveRef, kDNSServiceFlagsShareConnection , svcEntry->ifIndex, svcEntry->instanceName, DZC_SERVICE_PRIMARY_TYPE, "local", OnServiceResolveCallback, svcEntry); if (dnsErr != kDNSServiceErr_NoError) { @@ -668,6 +672,7 @@ static void discoveryZeroconfWatcher_refreshWatchedServices(discovery_zeroconf_w while (!celix_stringHashMapIterator_isEnd(&iter)) { watched_service_entry_t *svcEntry = (watched_service_entry_t *)iter.value.ptrValue; if (svcEntry->markDeleted) { + celix_logHelper_trace(watcher->logHelper, "Watcher: Stop to resolve service %s on %d.", svcEntry->instanceName, svcEntry->ifIndex); celix_stringHashMapIterator_remove(&iter); if (svcEntry->resolveRef) { DNSServiceRefDeallocate(svcEntry->resolveRef); @@ -719,6 +724,8 @@ static void onGetAddrInfoCb (DNSServiceRef sdRef, DNSServiceFlags flags, uint32_ celix_stringHashMap_remove(hostEntry->ipAddresses, ip); } + celix_logHelper_trace(hostEntry->logHelper, "Watcher: %s ip %s for host %s on %d.", (flags & kDNSServiceFlagsAdd) ? "Add" : "Remove", ip, hostEntry->hostname, hostEntry->ifIndex); + hostEntry->resolved = !(flags & kDNSServiceFlagsMoreComing); return; @@ -791,6 +798,7 @@ static void discoveryZeroconfWatcher_updateWatchedHosts(discovery_zeroconf_watch while (!celix_stringHashMapIterator_isEnd(&iter)) { watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue; if (hostEntry->markDeleted) { + celix_logHelper_trace(watcher->logHelper, "Watcher: Stop to resolve host %s on %d.", hostEntry->hostname, hostEntry->ifIndex); celix_stringHashMapIterator_remove(&iter); if (hostEntry->sdRef) { DNSServiceRefDeallocate(hostEntry->sdRef); @@ -816,6 +824,7 @@ static void discoveryZeroconfWatcher_refreshHostsInfo(discovery_zeroconf_watcher CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter1) { watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter1.value.ptrValue; if (watcher->sharedRef && hostEntry->sdRef == NULL && hostEntry->resolvedCnt < DZC_MAX_RESOLVED_CNT) { + celix_logHelper_trace(watcher->logHelper, "Watcher: Start to resolve host %s on %d.", hostEntry->hostname, hostEntry->ifIndex); hostEntry->sdRef = watcher->sharedRef; DNSServiceErrorType dnsErr = DNSServiceGetAddrInfo(&hostEntry->sdRef, kDNSServiceFlagsShareConnection, hostEntry->ifIndex, kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6, hostEntry->hostname, onGetAddrInfoCb, hostEntry); if (dnsErr != kDNSServiceErr_NoError) { @@ -916,46 +925,21 @@ static int discoveryZeroConfWatcher_createEndpointEntryForService(discovery_zero celix_autofree char *ipAddressesStr = NULL; status = discoveryZeroConfWatcher_getHostIpAddresses(watcher, hostname, svcEntry->ifIndex, &ipAddressesStr); if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to get ip addresses for endpoint %s.", svcEntry->instanceName); return status; } - const char *importedConfigs = celix_properties_get(ep->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); - if (importedConfigs == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: No imported configs."); - return CELIX_ILLEGAL_ARGUMENT; - } - celix_autofree char *importedConfigsCopy = celix_utils_strdup(importedConfigs); - if (importedConfigsCopy == NULL) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup imported configs."); - return CELIX_ENOMEM; + status = celix_properties_setLong(ep->properties, CELIX_RSA_PORT, svcEntry->port); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config port."); + return status; } - char *savePtr = NULL; - char *token = strtok_r(importedConfigsCopy, ",", &savePtr); - while (token != NULL) { - char *configType = celix_utils_trimInPlace(token); - char key[128] = {0}; - if(snprintf(key, sizeof(key), "%s.port", configType) >= sizeof(key)) { - celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); - return CELIX_ILLEGAL_ARGUMENT; - } - status = celix_properties_setLong(ep->properties, key, svcEntry->port); - if (status != CELIX_SUCCESS) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config port."); - return status; - } - if(snprintf(key, sizeof(key), "%s.ipaddresses", configType) >= sizeof(key)) { - celix_logHelper_error(watcher->logHelper, "Watcher: The length of imported config type %s is too long.", configType); - return CELIX_ILLEGAL_ARGUMENT; - } - status = celix_properties_set(ep->properties, key, ipAddressesStr); - if (status != CELIX_SUCCESS) { - celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); - return status; - } - epEntry->ipAddressesStr = celix_properties_get(ep->properties, key, ""); - - token = strtok_r(NULL, ",", &savePtr); + status = celix_properties_set(ep->properties, CELIX_RSA_IP_ADDRESSES, ipAddressesStr); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(watcher->logHelper, "Watcher: Failed to set imported config ip address list."); + return status; } + epEntry->ipAddressesStr = celix_properties_get(ep->properties, CELIX_RSA_IP_ADDRESSES, ""); celix_steal_ptr(hostname); celix_steal_ptr(ep); @@ -1023,7 +1007,7 @@ static void discoveryZeroconfWatcher_filterSameFrameWorkServices(discovery_zeroc } static bool discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(discovery_zeroconf_watcher_t *watcher, watched_endpoint_entry_t *endpointEntry) { - if (endpointEntry->hostname == NULL) { + if (endpointEntry->hostname == NULL || endpointEntry->ifIndex == kDNSServiceInterfaceIndexLocalOnly) { return false; } watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, endpointEntry->hostname, endpointEntry->ifIndex); diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt b/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt index b291dea8e..9d023c128 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt @@ -70,6 +70,10 @@ configure_file(server.properties.in server.properties) #add exception service interface descriptor configure_file(exception_test_service.descriptor exception_test_service.descriptor) +target_compile_options(test_rsa_dfi PRIVATE -DRSA_DFI_BUNDLE_FILE="${rsa_bundle_file}") +target_compile_options(test_rsa_dfi PRIVATE -DCALC_BUNDLE_FILE="${calc_bundle_file}") +target_compile_options(test_rsa_dfi PRIVATE -DTST_BUNDLE_FILE="${tst_bundle_file}") + add_celix_bundle_dependencies(test_rsa_dfi rsa_dfi #note depend on the target creating the bundle zip not the lib target calculator diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc index 28c84013d..47f2d5296 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc @@ -36,6 +36,7 @@ extern "C" { #include "framework.h" #include "remote_service_admin.h" #include "remote_interceptor.h" +#include "calculator_service.h" #define RSA_DIF_EXCEPTION_TEST_SERVICE "exception_test_service" typedef struct rsa_dfi_exception_test_service { @@ -402,3 +403,144 @@ TEST_F(RsaDfiClientServerInterceptorTests,TestInterceptorPreProxyCallReturnFalse TEST_F(RsaDfiClientServerExceptionTests,TestExceptionService) { testExceptionService(); } + + +class RsaDfiDynamicIpServerTestSuite : public ::testing::Test { +public: + RsaDfiDynamicIpServerTestSuite() { + { + auto* props = celix_properties_create(); + celix_properties_setBool(props, "CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT", true); + celix_properties_setBool(props, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, true); + celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".rsa_dfi_server_cache"); + serverFw = std::shared_ptr{celix_frameworkFactory_createFramework(props), [](auto f) {celix_frameworkFactory_destroyFramework(f);}}; + serverCtx = std::shared_ptr{celix_framework_getFrameworkContext(serverFw.get()), [](auto*){/*nop*/}}; + + auto bundleId = celix_bundleContext_installBundle(serverCtx.get(), RSA_DFI_BUNDLE_FILE, true); + EXPECT_TRUE(bundleId >= 0); + + bundleId = celix_bundleContext_installBundle(serverCtx.get(), CALC_BUNDLE_FILE, true); + EXPECT_TRUE(bundleId >= 0); + + celix_bundleContext_waitForEvents(serverCtx.get()); + } + + { + auto* props = celix_properties_create(); + celix_properties_setBool(props, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, true); + celix_properties_set(props, CELIX_FRAMEWORK_CACHE_DIR, ".rsa_dfi_client_cache"); + clientFw = std::shared_ptr{celix_frameworkFactory_createFramework(props), [](auto f) {celix_frameworkFactory_destroyFramework(f);}}; + clientCtx = std::shared_ptr{celix_framework_getFrameworkContext(clientFw.get()), [](auto*){/*nop*/}}; + + auto bundleId = celix_bundleContext_installBundle(clientCtx.get(), RSA_DFI_BUNDLE_FILE, true); + EXPECT_TRUE(bundleId >= 0); + + bundleId = celix_bundleContext_installBundle(clientCtx.get(), TST_BUNDLE_FILE, true); + EXPECT_TRUE(bundleId >= 0); + + celix_bundleContext_waitForEvents(clientCtx.get()); + } + } + ~RsaDfiDynamicIpServerTestSuite() override = default; + + void TestRemoteCalculator(void (*testBody)(tst_service_t* testSvc), const char* serverIp = "127.0.0.1") { + remote_service_admin_service_t* serverRsaSvc{nullptr}; + remote_service_admin_service_t* clientRsaSvc{nullptr}; + serverRsaTrkId = celix_bundleContext_trackService(serverCtx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN, + &serverRsaSvc, [](void* handle, void* svc){ + auto rsaSvc = static_cast(handle); + *rsaSvc = static_cast(svc); + }); + EXPECT_GE(serverRsaTrkId, 0); + clientRsaTrkId = celix_bundleContext_trackService(clientCtx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN, + &clientRsaSvc, [](void* handle, void* svc){ + auto rsaSvc = static_cast(handle); + *rsaSvc = static_cast(svc); + }); + EXPECT_GE(clientRsaTrkId, 0); + long calcId = celix_bundleContext_findService(serverCtx.get(), CALCULATOR_SERVICE); + ASSERT_TRUE(calcId >= 0L); + ASSERT_TRUE(clientRsaSvc != nullptr); + ASSERT_TRUE(serverRsaSvc != nullptr); + + char calcIdStr[32] = {0}; + snprintf(calcIdStr, 32, "%li", calcId); + celix_array_list_t *svcRegistrations = NULL; + auto status = serverRsaSvc->exportService(serverRsaSvc->admin, calcIdStr, NULL, &svcRegistrations); + ASSERT_EQ(CELIX_SUCCESS, status); + ASSERT_EQ(1, celix_arrayList_size(svcRegistrations)); + export_registration_t *exportedReg = static_cast(celix_arrayList_get(svcRegistrations, 0)); + export_reference_t *exportedRef = nullptr; + status = serverRsaSvc->exportRegistration_getExportReference(exportedReg, &exportedRef); + ASSERT_EQ(CELIX_SUCCESS, status); + endpoint_description_t *exportedEndpoint = nullptr; + status = serverRsaSvc->exportReference_getExportedEndpoint(exportedRef, &exportedEndpoint); + ASSERT_EQ(CELIX_SUCCESS, status); + free(exportedRef); + celix_arrayList_destroy(svcRegistrations); + + celix_properties_t *importProps = celix_properties_copy(exportedEndpoint->properties); + ASSERT_TRUE(importProps != nullptr); + celix_properties_set(importProps, CELIX_RSA_IP_ADDRESSES, serverIp); + endpoint_description_t *importedEndpoint = nullptr; + status = endpointDescription_create(importProps, &importedEndpoint); + ASSERT_EQ(CELIX_SUCCESS, status); + + import_registration_t* reg = nullptr; + status = clientRsaSvc->importService(clientRsaSvc->admin, importedEndpoint, ®); + ASSERT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_waitForEvents(clientCtx.get()); + + celix_service_use_options_t opts{}; + opts.filter.serviceName = TST_SERVICE_NAME; + opts.callbackHandle = (void*)testBody; + opts.use = [](void *handle , void *svc) { + auto* testBody = (void (*)(tst_service_t*))handle; + testBody(static_cast(svc)); + }; + opts.waitTimeoutInSeconds = 5; + auto called = celix_bundleContext_useServiceWithOptions(clientCtx.get(), &opts); + ASSERT_TRUE(called); + + status = clientRsaSvc->importRegistration_close(clientRsaSvc->admin, reg); + ASSERT_EQ(CELIX_SUCCESS, status); + endpointDescription_destroy(importedEndpoint); + + status = serverRsaSvc->exportRegistration_close(serverRsaSvc->admin, exportedReg); + ASSERT_EQ(CELIX_SUCCESS, status); + + celix_bundleContext_stopTracker(clientCtx.get(), clientRsaTrkId); + celix_bundleContext_stopTracker(serverCtx.get(), serverRsaTrkId); + } + + std::shared_ptr serverFw{}; + std::shared_ptr serverCtx{}; + long serverRsaTrkId{-1}; + std::shared_ptr clientFw{}; + std::shared_ptr clientCtx{}; + long clientRsaTrkId{-1}; +}; + +TEST_F(RsaDfiDynamicIpServerTestSuite, RemoteCalculatorTest) { + TestRemoteCalculator([](tst_service_t* testSvc) { + auto ok = testSvc->testCalculator(testSvc->handle); + ASSERT_TRUE(ok); + }); +} + +TEST_F(RsaDfiDynamicIpServerTestSuite, CallingMultiTimesRemoteCalculatorTest) { + TestRemoteCalculator([](tst_service_t* testSvc) { + auto ok = testSvc->testCalculator(testSvc->handle); + ASSERT_TRUE(ok); + + ok = testSvc->testCalculator(testSvc->handle); + ASSERT_TRUE(ok); + }); +} + +TEST_F(RsaDfiDynamicIpServerTestSuite, IPV6RemoteCalculatorTest) { + TestRemoteCalculator([](tst_service_t* testSvc) { + auto ok = testSvc->testCalculator(testSvc->handle); + ASSERT_TRUE(ok); + }, "::1"); +} diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc index bc5887f13..5c4a6c852 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc @@ -118,7 +118,6 @@ extern "C" { celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); - celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8888/service/42/org.apache.celix.Example"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.Example"); int rc = endpointDescription_create(props, &endpoint); @@ -155,55 +154,6 @@ extern "C" { ASSERT_TRUE(called); } - static void testImportServiceCallbackForZeroconfConfigType(void *handle CELIX_UNUSED, void *svc) { - thread_local bool init = true; - thread_local endpoint_description_t *endpoint = nullptr; - if (init) { - auto *rsa = static_cast(svc); - celix_properties_t *props = celix_properties_create(); - celix_properties_set(props, CELIX_RSA_ENDPOINT_SERVICE_ID, "42"); - celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); - celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); - celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "celix.remote.admin.dfi.zeroconf.http"); - celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.port", "8888"); - celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.ipaddresses", "127.0.0.1"); - celix_properties_set(props, "celix.remote.admin.dfi.zeroconf.http.path", "/service/42/org.apache.celix.Example"); - celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.Example"); - - int rc = endpointDescription_create(props, &endpoint); - ASSERT_EQ(CELIX_SUCCESS, rc); - - import_registration_t* reg = nullptr; - rc = rsa->importService(rsa->admin, endpoint, ®); - ASSERT_EQ(CELIX_SUCCESS, rc); - ASSERT_TRUE(reg != nullptr); - - init = false; - } else { - int rc = endpointDescription_destroy(endpoint); - ASSERT_EQ(CELIX_SUCCESS, rc); - } - } - - static void testImportServiceForZeroconfConfigType(void) { - celix_service_use_options_t opts{}; - opts.filter.serviceName = CELIX_RSA_REMOTE_SERVICE_ADMIN; - opts.use = testImportServiceCallbackForZeroconfConfigType; - opts.waitTimeoutInSeconds = 0.25; - - //first call -> init - bool called = celix_bundleContext_useServiceWithOptions(context, &opts); - ASSERT_TRUE(called); - - celix_framework_waitForEmptyEventQueue(celix_bundleContext_getFramework(context)); - long svcId = celix_bundleContext_findService(context, "org.apache.celix.Example"); - EXPECT_GE(svcId, 0); - - //second call -> deinit - called = celix_bundleContext_useServiceWithOptions(context, &opts); - ASSERT_TRUE(called); - } - static void testBundles(void) { array_list_pt bundles = NULL; @@ -254,10 +204,6 @@ TEST_F(RsaDfiTests, ImportService) { testImportService(); } -TEST_F(RsaDfiTests, ImportServiceForZeroconfConfigType) { - testImportServiceForZeroconfConfigType(); -} - TEST_F(RsaDfiTests, TestBundles) { testBundles(); } diff --git a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c index 5cc0327e7..25697b735 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c @@ -321,15 +321,14 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret if (status == CELIX_SUCCESS) { char *reply = NULL; - int rc = 0; //printf("sending request\n"); celix_properties_t *metadata = NULL; bool cont = remoteInterceptorHandler_invokePreProxyCall(import->interceptorsHandler, import->endpoint->properties, entry->name, &metadata); if (cont) { - status = import->send(import->sendHandle, import->endpoint, invokeRequest, metadata, &reply, &rc); + status = import->send(import->sendHandle, import->endpoint, invokeRequest, metadata, &reply); //printf("request sended. got reply '%s' with status %i\n", reply, rc); - if (status == CELIX_SUCCESS && rc == CELIX_SUCCESS && dynFunction_hasReturn(entry->dynFunc)) { + if (status == CELIX_SUCCESS && dynFunction_hasReturn(entry->dynFunc)) { //fjprintf("Handling reply '%s'\n", reply); int rsErrno = CELIX_SUCCESS; int retVal = jsonRpc_handleReply(entry->dynFunc, reply, args, &rsErrno); @@ -339,8 +338,6 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret //return the invocation error of remote service function *(int *) returnVal = rsErrno; } - } else if (rc != CELIX_SUCCESS) { - *(int *) returnVal = rc; } remoteInterceptorHandler_invokePostProxyCall(import->interceptorsHandler, import->endpoint->properties, entry->name, metadata); @@ -358,7 +355,7 @@ static void importRegistration_proxyFunc(void *userData, void *args[], void *ret const char *url = importRegistration_getUrl(import); const char *svcName = importRegistration_getServiceName(import); fprintf(import->logFile, "REMOTE CALL NR %i\n\turl=%s\n\tservice=%s\n\tpayload=%s\n\treturn_code=%i\n\treply=%s\n", - callCount, url, svcName, invokeRequest, rc, reply); + callCount, url, svcName, invokeRequest, status, reply == NULL ? "null" : reply); fflush(import->logFile); callCount += 1; } @@ -396,6 +393,10 @@ celix_status_t importRegistration_getImportReference(import_registration_t *regi return status; } +endpoint_description_t* importRegistration_getEndpointDescription(import_registration_t *registration) { + return registration->endpoint; +} + celix_status_t importReference_getImportedEndpoint(import_reference_t *reference) { celix_status_t status = CELIX_SUCCESS; return status; diff --git a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h index 13353204f..26c7e52c9 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h +++ b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h @@ -22,10 +22,11 @@ #include "import_registration.h" #include "dfi_utils.h" +#include "endpoint_description.h" #include -typedef celix_status_t (*send_func_type)(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply, int* replyStatus); +typedef celix_status_t (*send_func_type)(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply); celix_status_t importRegistration_create( celix_bundle_context_t *context, @@ -40,4 +41,6 @@ void importRegistration_destroy(import_registration_t *import); celix_status_t importRegistration_start(import_registration_t *import); +endpoint_description_t* importRegistration_getEndpointDescription(import_registration_t *registration); + #endif //CELIX_IMPORT_REGISTRATION_DFI_H diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c index 6102fa6b5..75b711bca 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c @@ -38,10 +38,17 @@ static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* ac if (props == NULL) { return CELIX_ENOMEM; } - status = celix_properties_set(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); + status = celix_properties_set(props, CELIX_RSA_REMOTE_CONFIGS_SUPPORTED, RSA_DFI_CONFIGURATION_TYPE); if (status != CELIX_SUCCESS) { return status; } + bool dynamicIpSupport = celix_bundleContext_getPropertyAsBool(ctx, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT_DEFAULT); + if (dynamicIpSupport) { + status = celix_properties_setBool(props, CELIX_RSA_DYNAMIC_IP_SUPPORT, true); + if (status != CELIX_SUCCESS) { + return status; + } + } status = remoteServiceAdmin_create(ctx, &activator->admin); if (status == CELIX_SUCCESS) { activator->adminService.admin = activator->admin; 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 index e94c9f4fd..af0829c19 100644 --- 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 @@ -34,6 +34,7 @@ #include "json_serializer.h" #include "utils.h" #include "celix_utils.h" +#include "celix_ref.h" #include "import_registration_dfi.h" #include "export_registration_dfi.h" @@ -73,6 +74,11 @@ #define CELIX_RSA_USE_STOP_EXPORT_THREAD true +typedef struct celix_imported_endpoint_url_ref { + struct celix_ref ref;//It must be first + char url[0]; +}celix_imported_endpoint_url_ref_t; + struct remote_service_admin { celix_bundle_context_t *context; celix_log_helper_t *loghelper; @@ -89,10 +95,12 @@ struct remote_service_admin { celix_thread_mutex_t importedServicesLock; array_list_pt importedServices; + celix_string_hash_map_t* importedEndpointUrls;//key: endpointId, value: celix_imported_endpoint_url_ref_t* char *port; char *ip; char *discoveryInterface; + bool dynamicIpSupport; struct mg_context *ctx; @@ -133,7 +141,7 @@ static const unsigned int DEFAULT_TIMEOUT = 0; static int remoteServiceAdmin_callback(struct mg_connection *conn); static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_service_admin_t *admin, service_reference_pt reference, celix_properties_t *props, char *interface, endpoint_description_t **description); -static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply, int* replyStatus); +static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply); static celix_status_t remoteServiceAdmin_getIpAddress(char* interface, char** ip); static char* remoteServiceAdmin_getIFNameForIP(const char *ip); static size_t remoteServiceAdmin_readCallback(void *ptr, size_t size, size_t nmemb, void *userp); @@ -197,6 +205,8 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote celixThreadRwlock_create(&(*admin)->exportedServicesLock, NULL); celixThreadMutex_create(&(*admin)->importedServicesLock, NULL); + (*admin)->importedEndpointUrls = celix_stringHashMap_create();//Ignore ENOMEM for now and deal with it on other PRs in the future + (*admin)->loghelper = celix_logHelper_create(context, "celix_rsa_admin"); long port = celix_bundleContext_getPropertyAsLong(context, RSA_PORT_KEY, RSA_PORT_DEFAULT); @@ -204,16 +214,17 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote const char *interface = celix_bundleContext_getProperty(context, RSA_INTERFACE_KEY, NULL); (*admin)->curlShareEnabled = celix_bundleContext_getPropertyAsBool(context, RSA_DFI_USE_CURL_SHARE_HANDLE, RSA_DFI_USE_CURL_SHARE_HANDLE_DEFAULT); - char *discoveryInterface = NULL; + (*admin)->dynamicIpSupport = celix_bundleContext_getPropertyAsBool(context, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT, CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT_DEFAULT); + char *detectedIp = NULL; if ((interface != NULL) && (remoteServiceAdmin_getIpAddress((char*)interface, &detectedIp) != CELIX_SUCCESS)) { celix_logHelper_log((*admin)->loghelper, CELIX_LOG_LEVEL_WARNING, "RSA: Could not retrieve IP address for interface %s", interface); } if (detectedIp != NULL) { ip = detectedIp; - discoveryInterface = celix_utils_strdup(interface); + (*admin)->discoveryInterface = celix_utils_strdup(interface); } else { - discoveryInterface = remoteServiceAdmin_getIFNameForIP(ip); + (*admin)->discoveryInterface = remoteServiceAdmin_getIFNameForIP(ip); } if (ip != NULL) { @@ -263,8 +274,8 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote bool bindToAllInterfaces = celix_bundleContext_getPropertyAsBool(context, CELIX_RSA_BIND_ON_ALL_INTERFACES, CELIX_RSA_BIND_ON_ALL_INTERFACES_DEFAULT); do { char *listeningPorts = NULL; - if (bindToAllInterfaces) { - asprintf(&listeningPorts,"0.0.0.0:%s", newPort); + if (bindToAllInterfaces || (*admin)->dynamicIpSupport) { + asprintf(&listeningPorts,"0.0.0.0:%s,[::]:%s", newPort,newPort); } else { asprintf(&listeningPorts,"%s:%s", (*admin)->ip, newPort); } @@ -285,13 +296,6 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote free(listeningPorts); } while (((*admin)->ctx == NULL) && (port_counter < MAX_NUMBER_OF_RESTARTS)); - - if (bindToAllInterfaces) { - free(discoveryInterface); - (*admin)->discoveryInterface = celix_utils_strdup("all");//announce service to all network interface - } else { - (*admin)->discoveryInterface = discoveryInterface; - } } bool logCalls = celix_bundleContext_getPropertyAsBool(context, RSA_LOG_CALLS_KEY, RSA_LOG_CALLS_DEFAULT); @@ -326,6 +330,13 @@ celix_status_t remoteServiceAdmin_destroy(remote_service_admin_t **admin) { pthread_mutex_destroy(&(*admin)->curlMutexConnect); pthread_mutex_destroy(&(*admin)->curlMutexCookie); pthread_mutex_destroy(&(*admin)->curlMutexDns); + CELIX_STRING_HASH_MAP_ITERATE((*admin)->importedEndpointUrls, iter) { + celix_imported_endpoint_url_ref_t* urlRef = iter.value.ptrValue; + celix_ref_put(&urlRef->ref, (void*)free); + } + celix_stringHashMap_destroy((*admin)->importedEndpointUrls); + celixThreadRwlock_destroy(&(*admin)->exportedServicesLock); + celixThreadMutex_destroy(&(*admin)->importedServicesLock); free(*admin); *admin = NULL; @@ -753,13 +764,15 @@ static celix_status_t remoteServiceAdmin_createEndpointDescription(remote_servic celix_properties_set(endpointProperties, CELIX_RSA_ENDPOINT_SERVICE_ID, serviceId); celix_properties_set(endpointProperties, CELIX_RSA_ENDPOINT_ID, endpoint_uuid); celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED, "true"); - celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, (char*) RSA_DFI_CONFIGURATION_TYPE","CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE); + celix_properties_set(endpointProperties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, RSA_DFI_CONFIGURATION_TYPE); celix_properties_set(endpointProperties, RSA_DFI_ENDPOINT_URL, url); if (admin->discoveryInterface != NULL) { - celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IFNAME, admin->discoveryInterface); + celix_properties_set(endpointProperties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, admin->discoveryInterface); + } + if (admin->dynamicIpSupport) { + celix_properties_set(endpointProperties, RSA_DFI_ENDPOINT_URL, buf); + celix_properties_set(endpointProperties, CELIX_RSA_PORT, admin->port); } - celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, admin->port); - celix_properties_set(endpointProperties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, buf); if (props != NULL) { CELIX_PROPERTIES_ITERATE(props, iter) { @@ -860,43 +873,6 @@ celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_admin_t *a return status; } -static bool checkConfigurationType(endpoint_description_t *endpoint, const char *configType) { - bool result = true; - if (strncmp(configType, RSA_DFI_CONFIGURATION_TYPE, 1024) == 0) { - const char *url = celix_properties_get(endpoint->properties, RSA_DFI_ENDPOINT_URL, NULL); - if (url == NULL) { - result = false; - } - } else if (strncmp(configType, CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE, 1024) == 0) { - const char *ip = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES, NULL);//the property is set by the discovery_zeroconf - const char *port = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, NULL); - const char *path = celix_properties_get(endpoint->properties, CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, NULL); - if (ip == NULL || port == NULL || path == NULL) { - return false; - } - celix_autofree char *ipCopy = celix_utils_strdup(ip); - if (ipCopy == NULL) { - return false; - } - char *savePtr = NULL; - char *token = strtok_r(ipCopy, ",", &savePtr); - result = (token != NULL); - while (token != NULL) { - struct sockaddr_in sa; - struct sockaddr_in6 sa6; - if (inet_pton(AF_INET, token, &sa.sin_addr) != 1 && inet_pton(AF_INET6, token, &sa6.sin6_addr) != 1) { - result = false; - break; - } - token = strtok_r(NULL, ",", &savePtr); - } - } else { - result = false; - } - - return result; -} - celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, endpoint_description_t *endpointDescription, import_registration_t **out) { celix_status_t status = CELIX_SUCCESS; @@ -910,7 +886,7 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, e token = strtok_r(ecCopy, delimiter, &savePtr); while (token != NULL) { - if (checkConfigurationType(endpointDescription, celix_utils_trimInPlace(token))) { + if (strncmp(celix_utils_trimInPlace(token), RSA_DFI_CONFIGURATION_TYPE, 1024) == 0) { importService = true; break; } @@ -957,6 +933,16 @@ celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, e return status; } +static void remoteServiceAdmin_removeDynamicIpUrlOfImportedRegistration(remote_service_admin_t* admin, import_registration_t *registration) { + endpoint_description_t* endpoint = importRegistration_getEndpointDescription(registration); + assert(endpoint != NULL); + celix_imported_endpoint_url_ref_t* urlRef = celix_stringHashMap_get(admin->importedEndpointUrls, endpoint->id); + if (urlRef != NULL) { + celix_ref_put(&urlRef->ref, (void*)free); + celix_stringHashMap_remove(admin->importedEndpointUrls, endpoint->id); + } + return; +} celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_t *admin, import_registration_t *registration) { celix_status_t status = CELIX_SUCCESS; @@ -970,6 +956,7 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_t * current = arrayList_get(admin->importedServices, i); if (current == registration) { arrayList_remove(admin->importedServices, i); + remoteServiceAdmin_removeDynamicIpUrlOfImportedRegistration(admin, registration); importRegistration_destroy(current); break; } @@ -979,43 +966,81 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_t * return status; } -static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply, int* replyStatus) { - remote_service_admin_t * rsa = handle; - celix_autoptr(celix_string_hash_map_t) ipAddressMap = NULL; +static celix_status_t remoteServiceAdmin_useDynamicIpUrlsForEndpoint(remote_service_admin_t* rsa, endpoint_description_t* endpointDescription, +celix_status_t (*useUrl)(void* handle, const char* url), void* handle) { + celix_status_t status = CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT); + celixThreadMutex_lock(&rsa->importedServicesLock); + celix_imported_endpoint_url_ref_t* urlRef = celix_stringHashMap_get(rsa->importedEndpointUrls, endpointDescription->id); + if (urlRef != NULL) { + celix_ref_get(&urlRef->ref); + celixThreadMutex_unlock(&rsa->importedServicesLock); + status = useUrl(handle, urlRef->url); + celix_ref_put(&urlRef->ref, (void*)free); + } else { + celixThreadMutex_unlock(&rsa->importedServicesLock); + } + if (status != CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT)) { + return status; + } + + const char *serviceUrl = celix_properties_get(endpointDescription->properties, (char*) RSA_DFI_ENDPOINT_URL, ""); + const char *ipaddresses = celix_properties_get(endpointDescription->properties, CELIX_RSA_IP_ADDRESSES, NULL); + int port = (int)celix_properties_getAsLong(endpointDescription->properties, CELIX_RSA_PORT, RSA_PORT_DEFAULT); celix_autofree char *ipStrListCopy = NULL; - const char *ipaddresses = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES, NULL); - if (ipaddresses != NULL) { - celix_string_hash_map_create_options_t opts = CELIX_EMPTY_STRING_HASH_MAP_CREATE_OPTIONS; - opts.storeKeysWeakly = true; - ipAddressMap = celix_stringHashMap_createWithOptions(&opts); - if (ipAddressMap == NULL) { - celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_ERROR); - celix_logHelper_error(rsa->loghelper, "Error creating ip address map"); - return CELIX_ENOMEM; - } - ipStrListCopy = celix_utils_strdup(ipaddresses); - if (ipStrListCopy == NULL) { - return CELIX_ENOMEM; + ipStrListCopy = celix_utils_strdup(ipaddresses); + if (ipStrListCopy == NULL) { + celix_logHelper_error(rsa->loghelper, "Error duplicating ip addresses"); + return CELIX_ENOMEM; + } + char url[256] = {0}; + char *savePtr = NULL; + char *token = strtok_r(ipStrListCopy, ",", &savePtr); + while (token != NULL) { + char *ip = celix_utils_trimInPlace(token); + struct sockaddr_in sa; + if (inet_pton(AF_INET, ip, &(sa.sin_addr)) == 1) { + snprintf(url, sizeof(url), "http://%s:%d%s", ip, port, serviceUrl); + } else { + snprintf(url, sizeof(url), "http://[%s]:%d%s", ip, port, serviceUrl); } - char *savePtr = NULL; - char *token = strtok_r(ipStrListCopy, ",", &savePtr); - while (token != NULL) { - char *ip = celix_utils_trimInPlace(token); - struct sockaddr_in sa; - if (inet_pton(AF_INET, ip, &(sa.sin_addr)) == 1) { - if (celix_stringHashMap_putBool(ipAddressMap, ip, true) != CELIX_SUCCESS) {//IPV4 - celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_WARNING); - celix_logHelper_warning(rsa->loghelper, "Error putting ip address in map"); - } - } else { - if (celix_stringHashMap_putBool(ipAddressMap, ip, false) != CELIX_SUCCESS) {//IPV6 - celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_WARNING); - celix_logHelper_warning(rsa->loghelper, "Error putting ip address in map"); - } + status = useUrl(handle, url); + if (status != CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT)) { + celix_imported_endpoint_url_ref_t* urlRefNew = calloc(1, sizeof(*urlRefNew) + strlen(url) + 1); + if (urlRefNew == NULL) { + celix_logHelper_error(rsa->loghelper, "Error allocating memory for imported endpoint url reference"); + return CELIX_ENOMEM; } - token = strtok_r(NULL, ",", &savePtr); + celix_ref_init(&urlRefNew->ref); + strcpy(urlRefNew->url, url); + + celixThreadMutex_lock(&rsa->importedServicesLock); + if (celix_stringHashMap_put(rsa->importedEndpointUrls, endpointDescription->id, urlRefNew) != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(rsa->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(rsa->loghelper, "Error storing imported endpoint url reference for endpoint %s", endpointDescription->id); + celix_ref_put(&urlRefNew->ref, (void*)free); + }else if (urlRef != NULL) { + celix_ref_put(&urlRef->ref, (void*)free); + } + celixThreadMutex_unlock(&rsa->importedServicesLock); + break; } + token = strtok_r(NULL, ",", &savePtr); + } + return status; +} + +static celix_status_t onUseUrlCallback(void* handle, const char* url) { + CURL *curl = handle; + curl_easy_setopt(curl, CURLOPT_URL, url); + CURLcode ret = curl_easy_perform(curl); + if (ret != CURLE_OK) { + return CELIX_ERROR_MAKE(CELIX_FACILITY_CURL, ret); } + return CELIX_SUCCESS; +} + +static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply) { + remote_service_admin_t * rsa = handle; struct celix_post_data post; post.readptr = request; @@ -1080,32 +1105,24 @@ static celix_status_t remoteServiceAdmin_send(void *handle, endpoint_description if (rsa->curlShareEnabled) { curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare); } - if (ipAddressMap == NULL || celix_stringHashMap_size(ipAddressMap) == 0) {//no zeroconf addresses found, use org.amdatu.remote.admin.http.url + + const char *ipaddresses = celix_properties_get(endpointDescription->properties, CELIX_RSA_IP_ADDRESSES, NULL); + if (ipaddresses == NULL) { curl_easy_setopt(curl, CURLOPT_URL, url); res = curl_easy_perform(curl); + status = (res == CURLE_OK) ? CELIX_SUCCESS:CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,res); } else { - const char *port = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT, ""); - const char *path = celix_properties_get(endpointDescription->properties, (char*) CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH, ""); - CELIX_STRING_HASH_MAP_ITERATE(ipAddressMap, iter) { - const char *ip = iter.key; - bool ipv4 = iter.value.boolValue; - if (ipv4) { - snprintf(url, sizeof(url), "http://%s:%s%s", ip, port, path); - } else { - snprintf(url, sizeof(url), "http://[%s]:%s%s", ip, port, path); - } - curl_easy_setopt(curl, CURLOPT_URL, url); - res = curl_easy_perform(curl); - if (res != CURLE_COULDNT_CONNECT) {//TODO cache the ip address and use it for the next call - break; - } - } + status = remoteServiceAdmin_useDynamicIpUrlsForEndpoint(rsa, endpointDescription, onUseUrlCallback, curl); } fputc('\0', get.stream); fclose(get.stream); *reply = get.buf; - *replyStatus = (res == CURLE_OK) ? CELIX_SUCCESS:CELIX_ERROR_MAKE(CELIX_FACILITY_HTTP,res); + if (status == CELIX_SUCCESS) { + long httpCode = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); + status = (httpCode == 200/*HTTP OK*/) ? CELIX_SUCCESS : CELIX_ERROR_MAKE(CELIX_FACILITY_HTTP,httpCode); + } curl_easy_cleanup(curl); curl_slist_free_all(metadataHeader); diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h index 6cc92529f..1adcfaa57 100644 --- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h +++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h @@ -36,15 +36,6 @@ #define RSA_DFI_CONFIGURATION_TYPE "org.amdatu.remote.admin.http" #define RSA_DFI_ENDPOINT_URL "org.amdatu.remote.admin.http.url" -/** - * @brief RSA Configuration type for zeroconf http, it is synonymous(https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1698916) with RSA_DFI_CONFIGURATION_TYPE, they refer to the same endpoint. - */ -#define CELIX_RSA_DFI_ZEROCONF_CONFIGURATION_TYPE "celix.remote.admin.dfi.zeroconf.http" -#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IFNAME "celix.remote.admin.dfi.zeroconf.http.ifname" -#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PORT "celix.remote.admin.dfi.zeroconf.http.port" -#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_IPADDRESSES "celix.remote.admin.dfi.zeroconf.http.ipaddresses" -#define CELIX_RSA_DFI_ZEROCONF_ENDPOINT_PATH "celix.remote.admin.dfi.zeroconf.http.path" - /** * @brief Remote Service Admin DFI environment property (named "RSA_DFI_USE_CURL_SHARE_HANDLE") which specified * whether the RSA DFI should use curl's share handle. @@ -76,5 +67,17 @@ */ #define CELIX_RSA_BIND_ON_ALL_INTERFACES_DEFAULT true +/** + * @brief Remote Service Admin DFI environment property, it indicates whether the RSA_DFI implementation supports dynamic IP address fill-in for service exports. + * Its type is boolean.If this property is not specified, it defaults to false. + * + */ +#define CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT "CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT" + +/** + * @brief Default value for the property CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT + */ +#define CELIX_RSA_DFI_DYNAMIC_IP_SUPPORT_DEFAULT false + #endif //CELIX_REMOTE_SERVICE_ADMIN_DFI_CONSTANTS_H diff --git a/bundles/remote_services/rsa_spi/include/remote_constants.h b/bundles/remote_services/rsa_spi/include/remote_constants.h index a85eaffb6..383eb9001 100644 --- a/bundles/remote_services/rsa_spi/include/remote_constants.h +++ b/bundles/remote_services/rsa_spi/include/remote_constants.h @@ -37,9 +37,40 @@ #define CELIX_RSA_SERVICE_LOCATION "service.location" /** - * It identify which types of remote service configurations are supported by a distribution provider. + * @brief It identify which types of remote service configurations are supported by a distribution provider. * @ref https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.remoteservices.html#i1708968 */ #define CELIX_RSA_REMOTE_CONFIGS_SUPPORTED "remote.configs.supported" +/** + * @breif It is a property of remote service admin service. It indicates whether the RSA implementation supports dynamic IP address fill-in for service exports. + * Its type is boolean.If this property is not specified, it defaults to false. + * @details If dynamic IP fill-in is supported, the RSA implementation should bind to ANY address (0.0.0.0). And the topology manager will create multiple endpoints for a single export registration based on the available network interfaces and an optional network selection configuration. + */ +#define CELIX_RSA_DYNAMIC_IP_SUPPORT "celix.rsa.dynamic.ip.support" + +/** + * @brief It is a replaceable property of endpoint. It indicates the dynamically determined IP address for the endpoint. Its type is string with comma-separated list of IP addresses. + * @todo Use string array instead of comma-separated list.(depends on https://github.com/apache/celix/issues/674) + */ +#define CELIX_RSA_IP_ADDRESSES "celix.rsa.ip.addresses" + +/** + * @brief It is a property of endpoint. It indicates the port number of the endpoint for which a dynamic IP address is required. Its type is integer. + */ +#define CELIX_RSA_PORT "celix.rsa.port" + +/** + * @brief It is a replaceable property of endpoint. It indicates which network interface is used for exported endpoint exposure. + * Its type is string. If this property is not specified, discovery implementation should select a proper exposure policy. + */ +#define CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE "celix.rsa.ifname" + +/** + * @brief It is a property of discovery endpoint listener service. It indicates whether the discovery implementation supports handling of interface-specific endpoints. + * Its type is boolean. If this property is not specified, it defaults to false. + * @details If handling interface-specific endpoints are supported, the discovery implementation will fill in the dynamic IP address to the property `CELIX_RSA_IP_ADDRESSES` of endpoint. + */ +#define CELIX_RSA_DISCOVERY_INTERFACE_SPECIFIC_ENDPOINTS_SUPPORT "celix.rsa.discovery.interface.specific.endpoints.support" + #endif /* REMOTE_CONSTANTS_H_ */ diff --git a/bundles/remote_services/topology_manager/CMakeLists.txt b/bundles/remote_services/topology_manager/CMakeLists.txt index ea6ccf702..ca742341e 100644 --- a/bundles/remote_services/topology_manager/CMakeLists.txt +++ b/bundles/remote_services/topology_manager/CMakeLists.txt @@ -15,6 +15,8 @@ # specific language governing permissions and limitations # under the License. +find_package(libuuid REQUIRED) + add_celix_bundle(rsa_topology_manager SOURCES src/topology_manager.c @@ -28,7 +30,7 @@ add_celix_bundle(rsa_topology_manager ) target_include_directories(rsa_topology_manager PRIVATE src) target_include_directories(rsa_topology_manager PRIVATE include) -target_link_libraries(rsa_topology_manager PRIVATE Celix::log_helper Celix::c_rsa_spi) +target_link_libraries(rsa_topology_manager PRIVATE Celix::rsa_common Celix::log_helper Celix::c_rsa_spi libuuid::libuuid) celix_deprecated_utils_headers(rsa_topology_manager) celix_deprecated_framework_headers(rsa_topology_manager) @@ -41,3 +43,11 @@ if (ENABLE_TESTING AND BUILD_RSA_REMOTE_SERVICE_ADMIN_DFI AND BUILD_RSA_DISCOVER add_subdirectory(tms_tst) endif () +if (ENABLE_TESTING) + add_library(rsa_topology_manager_cut STATIC src/topology_manager.c src/scope.c) + celix_deprecated_utils_headers(rsa_topology_manager_cut) + celix_deprecated_framework_headers(rsa_topology_manager_cut) + target_include_directories(rsa_topology_manager_cut PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include ${CMAKE_CURRENT_LIST_DIR}/src) + target_link_libraries(rsa_topology_manager_cut PUBLIC Celix::rsa_common Celix::log_helper Celix::c_rsa_spi libuuid::libuuid) + add_subdirectory(gtest) +endif () \ No newline at end of file diff --git a/bundles/remote_services/topology_manager/gtest/CMakeLists.txt b/bundles/remote_services/topology_manager/gtest/CMakeLists.txt new file mode 100644 index 000000000..f063854e6 --- /dev/null +++ b/bundles/remote_services/topology_manager/gtest/CMakeLists.txt @@ -0,0 +1,64 @@ +# 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. + + +add_executable(unit_test_tm + src/TopologyManagerTestSuite.cc +) + +celix_deprecated_utils_headers(unit_test_tm) +celix_deprecated_framework_headers(unit_test_tm) + +target_link_libraries(unit_test_tm PRIVATE + rsa_topology_manager_cut + Celix::c_rsa_spi + Celix::framework + GTest::gtest + GTest::gtest_main +) + +add_test(NAME run_unit_test_tm COMMAND unit_test_tm) +setup_target_for_coverage(unit_test_tm SCAN_DIR ..) + +if (EI_TESTS) + ####unit test with error injection + add_executable(unit_test_tm_with_error_injection + src/TopologyManagerErrorInjectionTestSuite.cc + ) + + celix_deprecated_utils_headers(unit_test_tm_with_error_injection) + celix_deprecated_framework_headers(unit_test_tm_with_error_injection) + + target_link_libraries(unit_test_tm_with_error_injection PRIVATE + rsa_topology_manager_cut + Celix::c_rsa_spi + Celix::framework + Celix::threads_ei +# Celix::bundle_ctx_ei +# Celix::string_hash_map_ei + Celix::long_hash_map_ei + Celix::array_list_ei + Celix::properties_ei + Celix::utils_ei + Celix::malloc_ei + GTest::gtest + GTest::gtest_main + ) + + add_test(NAME run_unit_test_tm_with_error_injection COMMAND unit_test_tm_with_error_injection) + setup_target_for_coverage(unit_test_tm_with_error_injection SCAN_DIR ..) +endif () \ No newline at end of file diff --git a/bundles/remote_services/topology_manager/gtest/src/TopologyManagerErrorInjectionTestSuite.cc b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerErrorInjectionTestSuite.cc new file mode 100644 index 000000000..1faddaec2 --- /dev/null +++ b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerErrorInjectionTestSuite.cc @@ -0,0 +1,267 @@ +/* + * 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 +#include "TopologyManagerTestSuiteBaseClass.h" +#include "celix_compiler.h" +#include "celix_errno.h" +#include "malloc_ei.h" +#include "celix_long_hash_map_ei.h" +#include "celix_array_list_ei.h" +#include "celix_properties_ei.h" +#include "celix_utils_ei.h" +#include "celix_threads_ei.h" + +class TopologyManagerCreatingErrorInjectionTestSuite : public ::testing::Test { +public: + TopologyManagerCreatingErrorInjectionTestSuite() { + auto config = celix_properties_create(); + celix_properties_set(config, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, "true"); + celix_properties_set(config, CELIX_FRAMEWORK_CACHE_DIR, ".tm_unit_test_cache"); + fw = std::shared_ptr{celix_frameworkFactory_createFramework(config), + [](auto f) { celix_frameworkFactory_destroyFramework(f); }}; + ctx = std::shared_ptr{celix_framework_getFrameworkContext(fw.get()), + [](auto) {/*nop*/}}; + logHelper = std::shared_ptr{celix_logHelper_create(ctx.get(), "tm_unit_test"), + [](auto l) { celix_logHelper_destroy(l); }}; + } + + ~TopologyManagerCreatingErrorInjectionTestSuite() override { + celix_ei_expect_calloc(nullptr, 0, nullptr); + celix_ei_expect_celixThreadMutex_create(nullptr, 0, 0); + celix_ei_expect_celix_longHashMap_create(nullptr, 0, nullptr); + } + + std::shared_ptr fw{}; + std::shared_ptr ctx{}; + std::shared_ptr logHelper{}; +}; + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, AllocingMemoryErrorTest) { + celix_ei_expect_calloc((void*)topologyManager_create, 0, nullptr); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingMutexErrorTest) { + celix_ei_expect_celixThreadMutex_create((void*)topologyManager_create, 0, CELIX_ENOMEM); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingRsaMapErrorTest) { + celix_ei_expect_celix_longHashMap_create((void*)topologyManager_create, 0, nullptr); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingDynamicIPEndpointMapErrorTest) { + celix_ei_expect_celix_longHashMap_create((void*)topologyManager_create, 0, nullptr, 2); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingRsaIfNameMapErrorTest) { + celix_ei_expect_celix_longHashMap_create((void*)topologyManager_create, 0, nullptr, 3); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingScopeErrorTest) { + celix_ei_expect_calloc((void*)scope_scopeCreate, 0, nullptr); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +TEST_F(TopologyManagerCreatingErrorInjectionTestSuite, CreatingExportedServiceMapErrorTest) { + celix_ei_expect_celix_longHashMap_create((void*)topologyManager_create, 0, nullptr, 4); + void *scope{}; + topology_manager_t *tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(CELIX_ENOMEM, status); +} + +class TopologyManagerErrorInjectionTestSuite : public TopologyManagerTestSuiteBaseClass { +public: + TopologyManagerErrorInjectionTestSuite() = default; + + ~TopologyManagerErrorInjectionTestSuite() override { + celix_ei_expect_calloc(nullptr, 0, nullptr); + celix_ei_expect_celix_longHashMap_put(nullptr, 0, 0); + celix_ei_expect_celix_longHashMap_create(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_create(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_copy(nullptr, 0, nullptr); + celix_ei_expect_celix_properties_set(nullptr, 0, 0); + celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr); + celix_ei_expect_celix_arrayList_add(nullptr, 0, 0); + } + + void TestExportServiceFailure(void (*errorInject)(void)) { + errorInject(); + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, + void* exportedSvc, service_reference_pt eplSvcRef CELIX_UNUSED, void* eplSvc CELIX_UNUSED, celix_bundle_context_t* ctx CELIX_UNUSED) { + //first add the exported service, then the rsa + auto status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true, nullptr, + [](void *handle CELIX_UNUSED, endpoint_description_t *endpoint CELIX_UNUSED, char *matchedFilter CELIX_UNUSED) -> celix_status_t { + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); + } +}; + +TEST_F(TopologyManagerErrorInjectionTestSuite, AllocingRsaSvcEntryMemoryErrorTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef CELIX_UNUSED, + void* exportedSvc CELIX_UNUSED, service_reference_pt eplSvcRef CELIX_UNUSED, void* eplSvc CELIX_UNUSED, celix_bundle_context_t* ctx CELIX_UNUSED) { + celix_ei_expect_calloc((void*)&topologyManager_rsaAdded, 0, nullptr); + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, PutingRsaSvcEntryToMapErrorTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef CELIX_UNUSED, + void* exportedSvc CELIX_UNUSED, service_reference_pt eplSvcRef CELIX_UNUSED, void* eplSvc CELIX_UNUSED, celix_bundle_context_t* ctx CELIX_UNUSED) { + celix_ei_expect_celix_longHashMap_put((void*)&topologyManager_rsaAdded, 0, CELIX_ENOMEM); + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_ENOMEM, status); + + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, PutingExportedRegistrationToMapErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_longHashMap_put((void*)&topologyManager_rsaAdded, 0, CELIX_ENOMEM, 2); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CreatingDynamicIpEndpointMapErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_longHashMap_create((void*)&topologyManager_rsaAdded, 2, nullptr); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, PutingDynamicIpEndpointToRsaMapErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_longHashMap_put((void*)&topologyManager_rsaAdded, 2, CELIX_ENOMEM); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CreateDynamicIpEndpointListErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_arrayList_create((void*)&topologyManager_rsaAdded, 1, nullptr); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, PutingDynamicIpEndpointListToMapErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_longHashMap_put((void*)&topologyManager_rsaAdded, 1, CELIX_ENOMEM); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CreatingRsaIfNameListErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_arrayList_create((void*)&topologyManager_rsaAdded, 3, nullptr); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CopyRsaIfNamesStringErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_utils_strdup((void*)&topologyManager_rsaAdded, 3, nullptr, 2); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CopyRsaIfNameErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_utils_strdup((void*)&topologyManager_rsaAdded, 3, nullptr, 3); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, AddingIfNameToListErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_arrayList_add((void*)&topologyManager_rsaAdded, 3, CELIX_ENOMEM); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, PutingIfNameListToMapErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_longHashMap_put((void*)&topologyManager_rsaAdded, 3, CELIX_ENOMEM); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, CreatingDynamicIpEndpointErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_properties_copy(CELIX_EI_UNKNOWN_CALLER, 0, nullptr); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, SettingDynamicIpEndpointIfNamePropertyErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_properties_set((void*)&topologyManager_rsaAdded, 3, CELIX_ENOMEM); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, SettingDynamicIpEndpointEpUuidPropertyErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_properties_set((void*)&topologyManager_rsaAdded, 3, CELIX_ENOMEM, 2); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, SettingDynamicIpEndpointIPAddressPropertyErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_properties_set((void*)&topologyManager_rsaAdded, 3, CELIX_ENOMEM, 3); + }); +} + +TEST_F(TopologyManagerErrorInjectionTestSuite, AddDynamicIpEndpointToListErrorTest) { + TestExportServiceFailure([]() { + celix_ei_expect_celix_arrayList_add((void*)&topologyManager_rsaAdded, 2, CELIX_ENOMEM, 2); + }); +} + + + diff --git a/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuite.cc b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuite.cc new file mode 100644 index 000000000..6f3d028a1 --- /dev/null +++ b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuite.cc @@ -0,0 +1,472 @@ +/* + * 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 +#include "TopologyManagerTestSuiteBaseClass.h" + +class TopologyManagerTestSuite : public TopologyManagerTestSuiteBaseClass { +public: + TopologyManagerTestSuite() = default; + + ~TopologyManagerTestSuite() = default; +}; + +TEST_F(TopologyManagerTestSuite, ExportService1Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the epl and then the exported service + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerTestSuite, ExportService2Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerTestSuite, ExportService3Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the exported service, then the rsa and then the epl + auto status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerTestSuite, ExportServiceWithDynamicIP1Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the epl and then the exported service + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true); +} + +TEST_F(TopologyManagerTestSuite, ExportServiceWithDynamicIP2Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true); +} + +TEST_F(TopologyManagerTestSuite, ExportServiceWithDynamicIP3Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the exported service, then the rsa and then the epl + auto status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true); +} + +TEST_F(TopologyManagerTestSuite, ExportMutilServiceWithDynamicIPTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + struct TmTestService { + void* handle; + } exportedSvc2{}; + auto exportedSvcProps = celix_properties_create(); + celix_properties_set(exportedSvcProps, "service.exported.interfaces", "*"); + auto exportedSvcId = celix_bundleContext_registerService(ctx, &exportedSvc2, "tmTestService2", exportedSvcProps); + EXPECT_TRUE(exportedSvcId > 0); + service_reference_pt svc2Ref{}; + status = bundleContext_getServiceReference(ctx, "tmTestService2", &svc2Ref); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, svc2Ref, &exportedSvc2); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, svc2Ref, &exportedSvc2); + EXPECT_EQ(CELIX_SUCCESS, status); + status = bundleContext_ungetServiceReference(ctx, svc2Ref); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_bundleContext_unregisterService(ctx, exportedSvcId); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true); +} + +TEST_F(TopologyManagerTestSuite, ExportServiceFailed1Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_BUNDLE_EXCEPTION, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, false, + [](remote_service_admin_t* admin, char* serviceId, celix_properties_t* properties, celix_array_list_t** registrations) -> celix_status_t { + (void)admin; + (void)properties; + (void)serviceId; + (void)registrations; + return CELIX_BUNDLE_EXCEPTION; + }, + [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); +} + +TEST_F(TopologyManagerTestSuite, ExportServiceFailed2Test) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the exported service, then the rsa and then the epl + auto status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, false, + [](remote_service_admin_t* admin, char* serviceId, celix_properties_t* properties, celix_array_list_t** registrations) -> celix_status_t { + (void)admin; + (void)properties; + (void)serviceId; + (void)registrations; + return CELIX_BUNDLE_EXCEPTION; + }, + [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); +} + +TEST_F(TopologyManagerTestSuite, ExportEmptyRegistrationListTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true, + [](remote_service_admin_t* admin, char* serviceId, celix_properties_t* properties, celix_array_list_t** registrations) -> celix_status_t { + (void)admin; + (void)properties; + (void)serviceId; + *registrations = celix_arrayList_create(); + return CELIX_SUCCESS; + }, + [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); +} + +TEST_F(TopologyManagerTestSuite, DynamicIpEndpointRsaPortNotSpecifiedTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true, + [](remote_service_admin_t* admin, char* serviceId, celix_properties_t* properties, celix_array_list_t** registrations) -> celix_status_t { + (void)properties; + celix_array_list_t* references{}; + service_reference_pt reference{}; + char filter[256]; + snprintf(filter, 256, "(%s=%s)", (char *) CELIX_FRAMEWORK_SERVICE_ID, serviceId); + auto status = bundleContext_getServiceReferences(admin->ctx, nullptr, filter, &references); + EXPECT_EQ(CELIX_SUCCESS, status); + reference = (service_reference_pt)celix_arrayList_get(references, 0); + EXPECT_TRUE(reference != nullptr); + auto exportReg = (export_registration_t*)malloc(sizeof(export_registration_t)); + auto endpointProps = celix_properties_create(); + unsigned int size = 0; + char **keys; + serviceReference_getPropertyKeys(reference, &keys, &size); + for (unsigned int i = 0; i < size; i++) { + char *key = keys[i]; + const char *value{}; + if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_INTERFACES) != 0 + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_CONFIGS) != 0) { + celix_properties_set(endpointProps, key, value); + } + } + const char *fwUuid = celix_bundleContext_getProperty(admin->ctx, CELIX_FRAMEWORK_UUID, nullptr); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_SERVICE_ID, serviceId); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_ID, "319bddfa-0252-4654-a3bd-298354d30207"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "tm_test_config_type"); + status = endpointDescription_create(endpointProps, &exportReg->exportReference.endpoint); + EXPECT_EQ(CELIX_SUCCESS, status); + exportReg->exportReference.reference = reference; + *registrations = celix_arrayList_create(); + celix_arrayList_add(*registrations, exportReg); + + bundleContext_ungetServiceReference(admin->ctx, reference); + free(keys); + celix_arrayList_destroy(references); + return CELIX_SUCCESS; + }, + [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); +} + +TEST_F(TopologyManagerTestSuite, DynamicIpRsaNetworkInterfaceNotSpecifiedTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + unsetenv("CELIX_RSA_INTERFACES_OF_PORT_" TEST_RSA_PORT); + //first add the rsa, then the exported service and then the epl + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerAdded(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_endpointListenerRemoved(tm, eplSvcRef, eplSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }, true,nullptr, + [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }); +} + +TEST_F(TopologyManagerTestSuite, EndpointListenerNotSupportInterfaceSpecificEndpointsTest) { + TestExportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx) { + (void)ctx; + (void)eplSvc; + (void)eplSvcRef; + //first add the rsa, then the epl and then the exported service + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + endpoint_listener_t epl{}; + epl.handle = nullptr; + epl.endpointAdded = [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + ADD_FAILURE() << "Should not be called"; + return CELIX_SUCCESS; + }; + epl.endpointRemoved = [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + return CELIX_SUCCESS; + }; + const char *fwUuid = celix_bundleContext_getProperty(ctx, CELIX_FRAMEWORK_UUID, nullptr); + char scope[256] = {0}; + (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, + CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + auto elpProps = celix_properties_create(); + celix_properties_set(elpProps, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); + auto eplId = celix_bundleContext_registerService(ctx, &epl, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, elpProps); + EXPECT_TRUE(eplId > 0); + char filter[256]; + snprintf(filter, 256, "(%s=%ld)", (char *) CELIX_FRAMEWORK_SERVICE_ID, eplId); + celix_array_list_t* references{}; + status = bundleContext_getServiceReferences(ctx, nullptr, filter, &references); + EXPECT_EQ(CELIX_SUCCESS, status); + auto eplRef = (service_reference_pt)celix_arrayList_get(references, 0); + EXPECT_TRUE(eplRef != nullptr); + status = topologyManager_endpointListenerAdded(tm, eplRef, &epl); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_addExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeExportedService(tm, exportedSvcRef, exportedSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_endpointListenerRemoved(tm, eplRef, &epl); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = bundleContext_ungetServiceReference(ctx, eplRef); + EXPECT_EQ(CELIX_SUCCESS, status); + celix_arrayList_destroy(references); + celix_bundleContext_unregisterService(ctx, eplId); + }, true); +} + +TEST_F(TopologyManagerTestSuite, ImportService1Test) { + TestImportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, endpoint_description_t *importEndpoint) { + //first add the rsa and then the import endpoint + auto status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_addImportedService(tm, importEndpoint, nullptr); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_removeImportedService(tm, importEndpoint, nullptr); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} + +TEST_F(TopologyManagerTestSuite, ImportService2Test) { + TestImportService([](topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, endpoint_description_t *importEndpoint) { + //first add the import endpoint and then the rsa + auto status = topologyManager_addImportedService(tm, importEndpoint, nullptr); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_rsaAdded(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + + status = topologyManager_rsaRemoved(tm, rsaSvcRef, rsaSvc); + EXPECT_EQ(CELIX_SUCCESS, status); + status = topologyManager_removeImportedService(tm, importEndpoint, nullptr); + EXPECT_EQ(CELIX_SUCCESS, status); + }); +} \ No newline at end of file diff --git a/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuiteBaseClass.h b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuiteBaseClass.h new file mode 100644 index 000000000..27540175e --- /dev/null +++ b/bundles/remote_services/topology_manager/gtest/src/TopologyManagerTestSuiteBaseClass.h @@ -0,0 +1,274 @@ +/* + * 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_TOPOLOGYMANAGERTESTSUITEBASECLASS_H +#define CELIX_TOPOLOGYMANAGERTESTSUITEBASECLASS_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "celix_errno.h" +#include "celix_constants.h" +#include "celix_bundle_context.h" +#include "celix_framework_factory.h" +#include "celix_log_helper.h" + +extern "C" { +#include "remote_constants.h" +#include "remote_service_admin.h" +#include "topology_manager.h" + +struct import_registration { + endpoint_description_t *endpoint; +}; + +struct export_reference { + endpoint_description_t *endpoint; + service_reference_pt reference; +}; +struct export_registration { + export_reference_t exportReference; +}; + +struct remote_service_admin { + celix_bundle_context_t* ctx; + bool dynamicIpSupport; +}; +} + +#define TEST_RSA_PORT "8080" + +class TopologyManagerTestSuiteBaseClass : public ::testing::Test { +public: + TopologyManagerTestSuiteBaseClass() { + auto config = celix_properties_create(); + celix_properties_set(config, CELIX_FRAMEWORK_CLEAN_CACHE_DIR_ON_CREATE, "true"); + celix_properties_set(config, CELIX_FRAMEWORK_CACHE_DIR, ".tm_unit_test_cache"); + fw = std::shared_ptr{celix_frameworkFactory_createFramework(config), [](auto f) {celix_frameworkFactory_destroyFramework(f);}}; + ctx = std::shared_ptr{celix_framework_getFrameworkContext(fw.get()), [](auto){/*nop*/}}; + logHelper = std::shared_ptr{celix_logHelper_create(ctx.get(), "tm_unit_test"), [](auto l) {celix_logHelper_destroy(l);}}; + + void* scope = nullptr; + topology_manager_t* tmPtr{}; + auto status = topologyManager_create(ctx.get(), logHelper.get(), &tmPtr, &scope); + EXPECT_EQ(status, CELIX_SUCCESS); + tm = std::shared_ptr{tmPtr, [](auto t) {topologyManager_destroy(t);}}; + } + + ~TopologyManagerTestSuiteBaseClass() = default; + + void TestExportService(void (*testBody)(topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, service_reference_pt exportedSvcRef, + void* exportedSvc, service_reference_pt eplSvcRef, void* eplSvc, celix_bundle_context_t* ctx), bool testDynamicIp = false, + celix_status_t (*exportService)(remote_service_admin_t* admin, char* serviceId, celix_properties_t* properties, celix_array_list_t** registrations) = nullptr, + celix_status_t (*endpointAdded)(void *handle, endpoint_description_t *endpoint, char *matchedFilter) = nullptr) { + if (testDynamicIp) { + setenv("CELIX_RSA_INTERFACES_OF_PORT_" TEST_RSA_PORT, "eth0", true); + } + remote_service_admin_t rsa{}; + rsa.ctx = ctx.get(); + rsa.dynamicIpSupport = testDynamicIp; + remote_service_admin_service_t rsaSvc{}; + rsaSvc.admin = &rsa; + rsaSvc.exportService = exportService != nullptr ? exportService : [](remote_service_admin_t* admin, char* serviceId, + celix_properties_t* properties, celix_array_list_t** registrations) -> celix_status_t { + (void)properties; + celix_array_list_t* references{}; + service_reference_pt reference{}; + char filter[256]; + snprintf(filter, 256, "(%s=%s)", (char *) CELIX_FRAMEWORK_SERVICE_ID, serviceId); + auto status = bundleContext_getServiceReferences(admin->ctx, nullptr, filter, &references); + EXPECT_EQ(CELIX_SUCCESS, status); + reference = (service_reference_pt)celix_arrayList_get(references, 0); + EXPECT_TRUE(reference != nullptr); + auto exportReg = (export_registration_t*)malloc(sizeof(export_registration_t)); + auto endpointProps = celix_properties_create(); + unsigned int size = 0; + char **keys; + serviceReference_getPropertyKeys(reference, &keys, &size); + for (unsigned int i = 0; i < size; i++) { + char *key = keys[i]; + const char *value{}; + if (serviceReference_getProperty(reference, key, &value) == CELIX_SUCCESS + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_INTERFACES) != 0 + && strcmp(key, (char*) CELIX_RSA_SERVICE_EXPORTED_CONFIGS) != 0) { + celix_properties_set(endpointProps, key, value); + } + } + const char *fwUuid = celix_bundleContext_getProperty(admin->ctx, CELIX_FRAMEWORK_UUID, nullptr); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_SERVICE_ID, serviceId); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_ID, "319bddfa-0252-4654-a3bd-298354d30207"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "tm_test_config_type"); + if (admin->dynamicIpSupport) { + celix_properties_set(endpointProps, CELIX_RSA_PORT, TEST_RSA_PORT); + } + status = endpointDescription_create(endpointProps, &exportReg->exportReference.endpoint); + EXPECT_EQ(CELIX_SUCCESS, status); + exportReg->exportReference.reference = reference; + *registrations = celix_arrayList_create(); + celix_arrayList_add(*registrations, exportReg); + + bundleContext_ungetServiceReference(admin->ctx, reference); + free(keys); + celix_arrayList_destroy(references); + return CELIX_SUCCESS; + }; + rsaSvc.exportRegistration_close = [](remote_service_admin_t* admin, export_registration_t* registration) -> celix_status_t { + (void)admin; + endpointDescription_destroy(registration->exportReference.endpoint); + free(registration); + return CELIX_SUCCESS; + }; + rsaSvc.exportRegistration_getExportReference = [](export_registration_t* registration, export_reference_t** reference) -> celix_status_t { + *reference = (export_reference_t*)calloc(1, sizeof(export_reference_t)); + (*reference)->endpoint = registration->exportReference.endpoint; + (*reference)->reference = registration->exportReference.reference; + return CELIX_SUCCESS; + }; + rsaSvc.exportReference_getExportedEndpoint = [](export_reference_t* reference, endpoint_description_t** endpoint) -> celix_status_t { + *endpoint = reference->endpoint; + return CELIX_SUCCESS; + }; + auto rsaProps = celix_properties_create(); + if (testDynamicIp) { + celix_properties_setBool(rsaProps, CELIX_RSA_DYNAMIC_IP_SUPPORT, true); + } + auto rsaId = celix_bundleContext_registerService(ctx.get(), &rsaSvc, CELIX_RSA_REMOTE_SERVICE_ADMIN, rsaProps); + EXPECT_TRUE(rsaId > 0); + + struct TmTestService { + void* handle; + } exportedService{}; + auto exportedSvcProps = celix_properties_create(); + celix_properties_set(exportedSvcProps, "service.exported.interfaces", "*"); + auto exportedSvcId = celix_bundleContext_registerService(ctx.get(), &exportedService, "tmTestService", exportedSvcProps); + EXPECT_TRUE(exportedSvcId > 0); + + endpoint_listener_t epl{}; + epl.handle = nullptr; + epl.endpointAdded = endpointAdded != nullptr ? endpointAdded : [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + return CELIX_SUCCESS; + }; + epl.endpointRemoved = [](void *handle, endpoint_description_t *endpoint, char *matchedFilter) -> celix_status_t { + (void)handle; + (void)endpoint; + (void)matchedFilter; + return CELIX_SUCCESS; + }; + const char *fwUuid = celix_bundleContext_getProperty(ctx.get(), CELIX_FRAMEWORK_UUID, nullptr); + char scope[256] = {0}; + (void)snprintf(scope, sizeof(scope), "(&(%s=*)(%s=%s))", CELIX_FRAMEWORK_SERVICE_NAME, + CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, fwUuid); + auto elpProps = celix_properties_create(); + celix_properties_set(elpProps, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, scope); + if (testDynamicIp) { + celix_properties_setBool(elpProps, CELIX_RSA_DISCOVERY_INTERFACE_SPECIFIC_ENDPOINTS_SUPPORT, true); + } + auto eplId = celix_bundleContext_registerService(ctx.get(), &epl, CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, elpProps); + EXPECT_TRUE(eplId > 0); + + service_reference_pt rsaSvcRef{}; + auto status = bundleContext_getServiceReference(ctx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN, &rsaSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + service_reference_pt exportedSvcRef{}; + status = bundleContext_getServiceReference(ctx.get(), "tmTestService", &exportedSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + service_reference_pt eplSvcRef{}; + status = bundleContext_getServiceReference(ctx.get(), CELIX_RSA_ENDPOINT_LISTENER_SERVICE_NAME, &eplSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + + testBody(tm.get(), rsaSvcRef, &rsaSvc, exportedSvcRef, &exportedService, eplSvcRef, &epl, ctx.get()); + + status = bundleContext_ungetServiceReference(ctx.get(), exportedSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + status = bundleContext_ungetServiceReference(ctx.get(), eplSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + status = bundleContext_ungetServiceReference(ctx.get(), rsaSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + + celix_bundleContext_unregisterService(ctx.get(), eplId); + celix_bundleContext_unregisterService(ctx.get(), exportedSvcId); + celix_bundleContext_unregisterService(ctx.get(), rsaId); + + if (testDynamicIp) { + unsetenv("CELIX_RSA_INTERFACES_OF_PORT_" TEST_RSA_PORT); + } + } + + void TestImportService(void (*testBody)(topology_manager_t* tm, service_reference_pt rsaSvcRef, void* rsaSvc, endpoint_description_t *importEndpoint)) { + remote_service_admin_t rsa{}; + rsa.ctx = ctx.get(); + remote_service_admin_service_t rsaSvc{}; + rsaSvc.admin = &rsa; + rsaSvc.importService = [](remote_service_admin_t* admin, endpoint_description_t* endpoint, import_registration_t** registration) -> celix_status_t { + (void)admin; + auto importReg = (import_registration_t*)calloc(1, sizeof(import_registration_t)); + importReg->endpoint = endpoint; + *registration = importReg; + return CELIX_SUCCESS; + }; + rsaSvc.importRegistration_close = [](remote_service_admin_t* admin, import_registration_t* registration) -> celix_status_t { + (void)admin; + free(registration); + return CELIX_SUCCESS; + }; + auto rsaId = celix_bundleContext_registerService(ctx.get(), &rsaSvc, CELIX_RSA_REMOTE_SERVICE_ADMIN, nullptr); + EXPECT_TRUE(rsaId > 0); + + auto endpointProps = celix_properties_create(); + celix_properties_set(endpointProps, CELIX_FRAMEWORK_SERVICE_NAME, "tmTestService"); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "1fb0bb2a-95ad-4cf9-8e79-072ec8bd4a85"); + celix_properties_setLong(endpointProps, CELIX_RSA_ENDPOINT_SERVICE_ID, 100); + celix_properties_set(endpointProps, CELIX_RSA_ENDPOINT_ID, "319bddfa-0252-4654-a3bd-298354d30207"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED, "true"); + celix_properties_set(endpointProps, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, "tm_test_config_type"); + endpoint_description_t* endpoint{}; + auto status = endpointDescription_create(endpointProps, &endpoint); + EXPECT_EQ(CELIX_SUCCESS, status); + + service_reference_pt rsaSvcRef{}; + status = bundleContext_getServiceReference(ctx.get(), CELIX_RSA_REMOTE_SERVICE_ADMIN, &rsaSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + + testBody(tm.get(), rsaSvcRef, &rsaSvc, endpoint); + + status = bundleContext_ungetServiceReference(ctx.get(), rsaSvcRef); + EXPECT_EQ(CELIX_SUCCESS, status); + + endpointDescription_destroy(endpoint); + celix_bundleContext_unregisterService(ctx.get(), rsaId); + } + + std::shared_ptr fw{}; + std::shared_ptr ctx{}; + std::shared_ptr logHelper{}; + std::shared_ptr tm{}; +}; + +#ifdef __cplusplus +} +#endif + +#endif //CELIX_TOPOLOGYMANAGERTESTSUITEBASECLASS_H diff --git a/bundles/remote_services/topology_manager/src/topology_manager.c b/bundles/remote_services/topology_manager/src/topology_manager.c index b462fc7d7..11f218a82 100644 --- a/bundles/remote_services/topology_manager/src/topology_manager.c +++ b/bundles/remote_services/topology_manager/src/topology_manager.c @@ -29,7 +29,12 @@ #include #include +#include + #include "topology_manager.h" +#include "celix_build_assert.h" +#include "celix_long_hash_map.h" +#include "celix_stdlib_cleanup.h" #include "bundle_context.h" #include "celix_compiler.h" #include "celix_constants.h" @@ -47,14 +52,30 @@ #include "hash_map.h" #include "celix_array_list.h" + +//The prefix of the config property which is used to store the interfaces of a port. e.g. CELIX_RSA_INTERFACES_OF_PORT_8080. The value is a comma-separated list of interface names. +#define CELIX_RSA_INTERFACES_OF_PORT_PREFIX "CELIX_RSA_INTERFACES_OF_PORT_" + +typedef struct celix_rsa_service_entry { + remote_service_admin_service_t* rsa; + bool dynamicIpSupport; +} celix_rsa_service_entry_t; + +typedef struct celix_exported_service_entry { + service_reference_pt reference; + celix_long_hash_map_t* registrations; //key:rsa service id, val:celix_array_list_t +} celix_exported_service_entry_t; + struct topology_manager { celix_bundle_context_t *context; - celix_array_list_t *rsaList; + celix_long_hash_map_t* rsaMap;//key:rsa service id, val:celix_rsa_service_entry_t* + celix_long_hash_map_t* dynamicIpEndpoints;//key:rsa service id, val: celix_long_hash_map_t> + celix_long_hash_map_t* networkIfNames;//key:server port, val:celix_array_list_t. a list of network interface names hash_map_pt listenerList; - hash_map_pt exportedServices; + celix_long_hash_map_t* exportedServices;//key:service id, val:celix_exported_service_entry_t* hash_map_pt importedServices; @@ -73,40 +94,76 @@ celix_status_t topologyManager_importScopeChanged(void *handle, char *service_na static celix_status_t topologyManager_notifyListenersEndpointAdded(topology_manager_pt manager, remote_service_admin_service_t *rsa, celix_array_list_t *registrations); static celix_status_t topologyManager_notifyListenersEndpointRemoved(topology_manager_pt manager, remote_service_admin_service_t *rsa, export_registration_t *export); +static celix_status_t topologyManager_getEndpointDescriptionForExportRegistration(remote_service_admin_service_t *rsa, export_registration_t *export, endpoint_description_t **endpoint); static celix_status_t topologyManager_addImportedService_nolock(void *handle, endpoint_description_t *endpoint, char *matchedFilter); static celix_status_t topologyManager_removeImportedService_nolock(void *handle, endpoint_description_t *endpoint, char *matchedFilter); -static celix_status_t topologyManager_addExportedService_nolock(void * handle, service_reference_pt reference, void * service); -static celix_status_t topologyManager_removeExportedService_nolock(void * handle, service_reference_pt reference, void * service); +static celix_status_t topologyManager_addExportedService_nolock(void * handle, service_reference_pt reference); +static void topologyManager_removeExportedService_nolock(void * handle, service_reference_pt reference); celix_status_t topologyManager_create(celix_bundle_context_t *context, celix_log_helper_t *logHelper, topology_manager_pt *manager, void **scope) { celix_status_t status = CELIX_SUCCESS; - *manager = calloc(1, sizeof(**manager)); - - if (!*manager) { + celix_autofree topology_manager_t* tm = *manager = calloc(1, sizeof(**manager)); + if (tm == NULL) { + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error allocating memory for topology_manager_t."); return CELIX_ENOMEM; } + tm->context = context; + tm->loghelper = logHelper; + tm->closed = false; + + status = celixThreadMutex_create(&tm->lock, NULL); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating mutex."); + return status; + } + celix_autoptr(celix_thread_mutex_t) lock = &tm->lock; + celix_autoptr(celix_long_hash_map_t) rsaMap = tm->rsaMap = celix_longHashMap_create(); + if (rsaMap == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating long hash map for rsa services."); + return CELIX_ENOMEM; + } + celix_autoptr(celix_long_hash_map_t) dynamicIpEndpoints = tm->dynamicIpEndpoints = celix_longHashMap_create(); + if (dynamicIpEndpoints == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating long hash map for dynamic ip endpoints."); + return CELIX_ENOMEM; + } + celix_autoptr(celix_long_hash_map_t) networkIfNames = tm->networkIfNames = celix_longHashMap_create(); + if (networkIfNames == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating long hash map for network interface names."); + return CELIX_ENOMEM; + } + celix_autoptr(celix_long_hash_map_t) exportedServices = tm->exportedServices = celix_longHashMap_create(); + if (exportedServices == NULL) { + celix_logHelper_logTssErrors(logHelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating long hash map for exported services."); + return CELIX_ENOMEM; + } - (*manager)->context = context; - (*manager)->rsaList = NULL; - - celixThreadMutex_create(&(*manager)->lock, NULL); - - (*manager)->rsaList = celix_arrayList_create(); + //TODO remove deprecated hashMap (*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)->closed = false; - - status = scope_scopeCreate(*manager, &(*manager)->scope); - assert(status == CELIX_SUCCESS); - scope_setExportScopeChangedCallback((*manager)->scope, topologyManager_exportScopeChanged); - scope_setImportScopeChangedCallback((*manager)->scope, topologyManager_importScopeChanged); - *scope = (*manager)->scope; - - (*manager)->loghelper = logHelper; + status = scope_scopeCreate(tm, &tm->scope); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(logHelper, "TOPOLOGY_MANAGER: Error creating scope."); + hashMap_destroy(tm->importedServices, false, false); + hashMap_destroy(tm->listenerList, false, false); + return status; + } + scope_setExportScopeChangedCallback(tm->scope, topologyManager_exportScopeChanged); + scope_setImportScopeChangedCallback(tm->scope, topologyManager_importScopeChanged); + *scope = tm->scope; + celix_steal_ptr(exportedServices); + celix_steal_ptr(networkIfNames); + celix_steal_ptr(dynamicIpEndpoints); + celix_steal_ptr(rsaMap); + celix_steal_ptr(lock); + celix_steal_ptr(tm); return status; } @@ -119,9 +176,22 @@ celix_status_t topologyManager_destroy(topology_manager_pt manager) { celixThreadMutex_lock(&manager->lock); hashMap_destroy(manager->importedServices, false, false); - hashMap_destroy(manager->exportedServices, false, false); hashMap_destroy(manager->listenerList, false, false); - celix_arrayList_destroy(manager->rsaList); + + assert(celix_longHashMap_size(manager->exportedServices) == 0); + celix_longHashMap_destroy(manager->exportedServices); + CELIX_LONG_HASH_MAP_ITERATE(manager->networkIfNames, iter) { + celix_array_list_t* ifNames = iter.value.ptrValue; + for (int i = 0; i < celix_arrayList_size(ifNames); ++i) { + free(celix_arrayList_get(ifNames, i)); + } + celix_arrayList_destroy(ifNames); + } + celix_longHashMap_destroy(manager->networkIfNames); + assert(celix_longHashMap_size(manager->dynamicIpEndpoints) == 0); + celix_longHashMap_destroy(manager->dynamicIpEndpoints); + assert(celix_longHashMap_size(manager->rsaMap) == 0); + celix_longHashMap_destroy(manager->rsaMap); celixThreadMutex_unlock(&manager->lock); celixThreadMutex_destroy(&manager->lock); @@ -183,16 +253,318 @@ celix_status_t topologyManager_rsaAdding(void * handle, service_reference_pt ref return status; } -celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt unusedRef CELIX_UNUSED, void * service) { +static celix_array_list_t* topologyManager_getNetworkInterfacesForPort(topology_manager_t* tm, unsigned int port) { + celix_status_t status = CELIX_SUCCESS; + celix_array_list_t* ifNames = celix_longHashMap_get(tm->networkIfNames, port); + if (ifNames == NULL) { + char ifNamesKey[64]; + CELIX_BUILD_ASSERT(sizeof(ifNamesKey) >= (sizeof(CELIX_RSA_INTERFACES_OF_PORT_PREFIX) + 10));//10 is max int len + (void)snprintf(ifNamesKey, sizeof(ifNamesKey), "%s%u", CELIX_RSA_INTERFACES_OF_PORT_PREFIX, port); + const char* ifNamesStr = celix_bundleContext_getProperty(tm->context, ifNamesKey, NULL); + if (ifNamesStr == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting interface names from config properties."); + return NULL; + } + celix_autoptr(celix_array_list_t) _ifNames = celix_arrayList_create(); + if (_ifNames == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating array list for interface names."); + return NULL; + } + celix_autofree char* ifNamesStrCopy = celix_utils_strdup(ifNamesStr); + if (ifNamesStrCopy == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error copying interface names string."); + return NULL; + } + char* savePtr = NULL; + char* token = strtok_r(ifNamesStrCopy, ",", &savePtr); + while (token != NULL && status == CELIX_SUCCESS) { + celix_autofree char* ifname = celix_utils_strdup(token); + if (ifname == NULL) { + status = CELIX_ENOMEM; + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error copying interface name."); + continue; + } + status = celix_arrayList_add(_ifNames, ifname); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error adding interface name to array list."); + continue; + } + celix_steal_ptr(ifname); + token = strtok_r(NULL, ",", &savePtr); + } + + CELIX_DO_IF(status, status = celix_longHashMap_put(tm->networkIfNames, port, _ifNames)); + + if (status != CELIX_SUCCESS) { + for (int i = 0; i < celix_arrayList_size(_ifNames); ++i) { + free(celix_arrayList_get(_ifNames, i)); + } + return NULL; + } + ifNames = celix_steal_ptr(_ifNames); + } + return ifNames; +} + +static endpoint_description_t* topologyManager_createEndpointWithNetworkInterface(topology_manager_t* tm, const char* ifname, + endpoint_description_t* exportedRegEndpoint) { + celix_autoptr(endpoint_description_t) endpoint = endpointDescription_clone(exportedRegEndpoint); + if (endpoint == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error cloning endpoint description."); + return NULL; + } + celix_status_t status = celix_properties_set(endpoint->properties, CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE, ifname); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error setting property %s.", CELIX_RSA_EXPORTED_ENDPOINT_EXPOSURE_INTERFACE); + return NULL; + } + uuid_t endpointUuid; + uuid_generate(endpointUuid); + char endpointUuidStr[37]; + uuid_unparse_lower(endpointUuid, endpointUuidStr); + status = celix_properties_set(endpoint->properties, CELIX_RSA_ENDPOINT_ID, endpointUuidStr); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error setting property %s.", CELIX_RSA_ENDPOINT_ID); + return NULL; + } + endpoint->id = celix_properties_get(endpoint->properties, CELIX_RSA_ENDPOINT_ID, ""); + status = celix_properties_set(endpoint->properties, CELIX_RSA_IP_ADDRESSES, "");//need to be filled in by discovery implementation + if (status) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error setting property %s.", CELIX_RSA_IP_ADDRESSES); + return NULL; + } + return celix_steal_ptr(endpoint); +} + +static celix_status_t topologyManager_generateEndpointsForDynamicIpExportedRegistration(topology_manager_t* tm, endpoint_description_t* exportedRegEndpoint, + celix_array_list_t* endpoints) { + celix_status_t status = CELIX_SUCCESS; + int port = celix_properties_getAsLong(exportedRegEndpoint->properties, CELIX_RSA_PORT, -1); + if (port < 0) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting port from dynamic ip endpoint description."); + return CELIX_ILLEGAL_ARGUMENT; + } + celix_array_list_t* ifNames = topologyManager_getNetworkInterfacesForPort(tm, port); + if (ifNames == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting network interface names for port %d.", port); + return CELIX_ILLEGAL_STATE; + } + + int size = celix_arrayList_size(ifNames); + for (int i = 0; i < size; ++i) { + const char* ifname = celix_arrayList_get(ifNames, i); + celix_autoptr(endpoint_description_t) endpoint = topologyManager_createEndpointWithNetworkInterface(tm, ifname, exportedRegEndpoint); + if (endpoint == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating endpoint for service %s on %s", exportedRegEndpoint->serviceName, ifname); + continue; + } + status = celix_arrayList_add(endpoints, endpoint); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error adding endpoint for service %s on %s", exportedRegEndpoint->serviceName, ifname); + continue; + } + celix_steal_ptr(endpoint); + } + return CELIX_SUCCESS; +} + +static void topologyManager_notifyListenersDynamicIpEndpointAdded(topology_manager_t* tm, celix_array_list_t* endpoints) { + celix_status_t status = CELIX_SUCCESS; + + hash_map_iterator_pt iter = hashMapIterator_create(tm->listenerList); + while (hashMapIterator_hasNext(iter)) { + service_reference_pt reference = hashMapIterator_nextKey(iter); + + const char *interfaceSpecEndpointSupport = NULL; + serviceReference_getProperty(reference, CELIX_RSA_DISCOVERY_INTERFACE_SPECIFIC_ENDPOINTS_SUPPORT, &interfaceSpecEndpointSupport); + if (interfaceSpecEndpointSupport == NULL || strcmp(interfaceSpecEndpointSupport, "true") != 0) { + continue; + } + + const char* scope = NULL; + serviceReference_getProperty(reference, CELIX_RSA_ENDPOINT_LISTENER_SCOPE, &scope); + celix_autoptr(celix_filter_t) filter = celix_filter_create(scope); + if (filter == NULL) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating filter for endpoint listener."); + continue; + } + + endpoint_listener_t *epl = NULL; + status = bundleContext_getService(tm->context, reference, (void **) &epl); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting endpoint listener."); + continue; + } + int size = celix_arrayList_size(endpoints); + for (int i = 0; i < size; i++) { + endpoint_description_t* endpoint = celix_arrayList_get(endpoints, i); + if (celix_filter_match(filter, endpoint->properties)) { + status = epl->endpointAdded(epl->handle, endpoint, (char*)scope); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Failed to add endpoint to endpoint listener."); + } + } + } + bundleContext_ungetService(tm->context, reference, NULL); + } + hashMapIterator_destroy(iter); + + return; +} + +static void topologyManager_notifyListenersDynamicIpEndpointRemoved(topology_manager_t* tm, celix_array_list_t* endpoints) { + celix_status_t status = CELIX_SUCCESS; + + hash_map_iterator_pt iter = hashMapIterator_create(tm->listenerList); + while (hashMapIterator_hasNext(iter)) { + endpoint_listener_t *epl = NULL; + service_reference_pt reference = hashMapIterator_nextKey(iter); + + status = bundleContext_getService(tm->context, reference, (void **) &epl); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting endpoint listener."); + continue; + } + int size = celix_arrayList_size(endpoints); + for (int i = 0; i < size; i++) { + endpoint_description_t* endpoint = celix_arrayList_get(endpoints, i); + status = epl->endpointRemoved(epl->handle, endpoint, NULL); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Failed to remove endpoint to endpoint listener."); + } + } + bundleContext_ungetService(tm->context, reference, NULL); + } + hashMapIterator_destroy(iter); + + return; +} + +static celix_long_hash_map_t* topologyManager_getDynamicIpEndpointMapForRsa(topology_manager_t* tm, long rsaSvcId) { + celix_autoptr(celix_long_hash_map_t) endpointMap = celix_longHashMap_get(tm->dynamicIpEndpoints, rsaSvcId); + if (endpointMap != NULL) { + return celix_steal_ptr(endpointMap); + } + + endpointMap = celix_longHashMap_create(); + if (endpointMap == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating long hash map for exported services."); + return NULL; + } + celix_status_t status = celix_longHashMap_put(tm->dynamicIpEndpoints, rsaSvcId, endpointMap); + if (status != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error adding exported services to map."); + return NULL; + } + return celix_steal_ptr(endpointMap); +} + +static void topologyManager_addDynamicIpEndpointsForExportedService(topology_manager_t* tm, long rsaSvcId, long exportedSvcId, + celix_array_list_t *registrations) { + celix_status_t status = CELIX_SUCCESS; + int regSize = celix_arrayList_size(registrations); + if (regSize == 0) { + return; + } + celix_long_hash_map_t* endpointMap = topologyManager_getDynamicIpEndpointMapForRsa(tm, rsaSvcId); + if (endpointMap == NULL) { + return; + } + + celix_array_list_t* endpointList = celix_arrayList_create(); + if (endpointList == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating array list for dynamic ip endpoints."); + return; + } + status = celix_longHashMap_put(endpointMap, exportedSvcId, endpointList); + if (status != CELIX_SUCCESS) { + celix_arrayList_destroy(endpointList); + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error adding dynamic ip endpoints list to map."); + return; + } + + celix_rsa_service_entry_t* rsaSvcEntry = celix_longHashMap_get(tm->rsaMap, rsaSvcId); + assert(rsaSvcEntry != NULL);//It must be not null, because the rsa service is already added to the rsaMap. + for (int i = 0; i < regSize; ++i) { + export_registration_t* exportReg = celix_arrayList_get(registrations, i); + endpoint_description_t* exportedRegEndpoint = NULL; + status = topologyManager_getEndpointDescriptionForExportRegistration(rsaSvcEntry->rsa, exportReg, &exportedRegEndpoint); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error getting endpoint description for exported registration."); + continue; + } + status = topologyManager_generateEndpointsForDynamicIpExportedRegistration(tm, exportedRegEndpoint, endpointList); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error generating endpoints for dynamic ip exported registration"); + } + } + + if (celix_arrayList_size(endpointList) > 0) { + topologyManager_notifyListenersDynamicIpEndpointAdded(tm, endpointList); + } + + return; +} + +static void topologyManager_removeDynamicIpEndpointsForExportedService(topology_manager_t* tm, long rsaSvcId, long exportedSvcId) { + celix_long_hash_map_t* endpointMap = celix_longHashMap_get(tm->dynamicIpEndpoints, rsaSvcId); + if (endpointMap == NULL) { + return; + } + celix_array_list_t* endpointList = celix_longHashMap_get(endpointMap, exportedSvcId); + if (endpointList != NULL) { + topologyManager_notifyListenersDynamicIpEndpointRemoved(tm, endpointList); + for (int i = 0; i < celix_arrayList_size(endpointList); ++i) { + endpoint_description_t* endpoint = celix_arrayList_get(endpointList, i); + endpointDescription_destroy(endpoint); + } + celix_longHashMap_remove(endpointMap, exportedSvcId); + celix_arrayList_destroy(endpointList); + } + + if (celix_longHashMap_size(endpointMap) == 0) { + celix_longHashMap_remove(tm->dynamicIpEndpoints, rsaSvcId); + celix_longHashMap_destroy(endpointMap); + } + return; +} + +celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt rsaSvcRef, void * service) { topology_manager_pt manager = (topology_manager_pt) handle; celix_properties_t *serviceProperties = NULL; remote_service_admin_service_t *rsa = (remote_service_admin_service_t *) service; celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_INFO, "TOPOLOGY_MANAGER: Added RSA"); + bool dynamicIpSupport = false; + const char *dynamicIpSupportStr = NULL; + serviceReference_getProperty(rsaSvcRef, CELIX_RSA_DYNAMIC_IP_SUPPORT, &dynamicIpSupportStr); + if (dynamicIpSupportStr != NULL && celix_utils_stringEquals(dynamicIpSupportStr, "true")) { + dynamicIpSupport = true; + } - celixThreadMutex_lock(&manager->lock); + celix_autofree celix_rsa_service_entry_t* rsaSvcEntry = calloc(1, sizeof(*rsaSvcEntry)); + if (rsaSvcEntry == NULL) { + return CELIX_ENOMEM; + } + rsaSvcEntry->dynamicIpSupport = dynamicIpSupport; + rsaSvcEntry->rsa = rsa; - celix_arrayList_add(manager->rsaList, rsa); + celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&manager->lock); + + long rsaSvcId = serviceReference_getServiceId(rsaSvcRef); + celix_status_t ret = celix_longHashMap_put(manager->rsaMap, rsaSvcId, rsaSvcEntry); + if (ret != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(manager->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error adding rsa service entry to map."); + return ret; + } + celix_steal_ptr(rsaSvcEntry); // add already imported services to new rsa hash_map_iterator_pt importedServicesIterator = hashMapIterator_create(manager->importedServices); @@ -203,7 +575,6 @@ celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt unus if (scope_allowImport(manager->scope, endpoint)) { import_registration_t *import = NULL; celix_status_t status = rsa->importService(rsa->admin, endpoint, &import); - if (status == CELIX_SUCCESS) { hash_map_pt imports = hashMapEntry_getValue(entry); @@ -220,31 +591,37 @@ celix_status_t topologyManager_rsaAdded(void * handle, service_reference_pt unus hashMapIterator_destroy(importedServicesIterator); // add already exported services to new rsa - 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); - const char* serviceId = NULL; - - serviceReference_getProperty(reference, CELIX_FRAMEWORK_SERVICE_ID, &serviceId); + CELIX_LONG_HASH_MAP_ITERATE(manager->exportedServices, iter) { + celix_exported_service_entry_t* svcEntry = iter.value.ptrValue; + service_reference_pt reference = svcEntry->reference; + long serviceId = iter.key; + char serviceIdStr[32]; + (void)snprintf(serviceIdStr, sizeof(serviceIdStr), "%li", serviceId); scope_getExportProperties(manager->scope, reference, &serviceProperties); - celix_array_list_t *endpoints = NULL; - celix_status_t status = rsa->exportService(rsa->admin, (char*)serviceId, serviceProperties, &endpoints); - - if (status == CELIX_SUCCESS) { - hash_map_pt exports = hashMapEntry_getValue(entry); - assert(exports != NULL);// It must not be NULL, It has been created in function topologyManager_addExportedService_nolock - hashMap_put(exports, rsa, endpoints); - topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); + celix_autoptr(celix_array_list_t) registrations = NULL; + celix_status_t status = rsa->exportService(rsa->admin, serviceIdStr, serviceProperties, ®istrations); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error exporting service."); + continue; + } + if (celix_longHashMap_put(svcEntry->registrations, rsaSvcId, registrations) != CELIX_SUCCESS) { + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error adding exported endpoints to map."); + for (int i = 0; i < celix_arrayList_size(registrations); ++i) { + export_registration_t* export = celix_arrayList_get(registrations, i); + rsa->exportRegistration_close(rsa->admin, export); + } + continue; } + if (dynamicIpSupport) { + topologyManager_addDynamicIpEndpointsForExportedService(manager, rsaSvcId,serviceId, registrations); + } else { + topologyManager_notifyListenersEndpointAdded(manager, rsa, registrations); + } + celix_steal_ptr(registrations); } - hashMapIterator_destroy(exportedServicesIterator); - celixThreadMutex_unlock(&manager->lock); - return CELIX_SUCCESS; } @@ -260,29 +637,30 @@ celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt re celix_status_t status = CELIX_SUCCESS; topology_manager_pt manager = (topology_manager_pt) handle; remote_service_admin_service_t *rsa = (remote_service_admin_service_t *) service; + long rsaSvcId = serviceReference_getServiceId(reference); celixThreadMutex_lock(&manager->lock); - hash_map_iterator_pt exportedSvcIter = hashMapIterator_create(manager->exportedServices); - - while (hashMapIterator_hasNext(exportedSvcIter)) { + CELIX_LONG_HASH_MAP_ITERATE(manager->exportedServices, iter) { + celix_exported_service_entry_t* svcEntry = iter.value.ptrValue; + service_reference_pt exportSvcRef = svcEntry->reference; + long exportedSvcId = serviceReference_getServiceId(exportSvcRef); - hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedSvcIter); - hash_map_pt exports = hashMapEntry_getValue(entry); + topologyManager_removeDynamicIpEndpointsForExportedService(manager, rsaSvcId, exportedSvcId); - celix_array_list_t *exports_list = (celix_array_list_t *)hashMap_remove(exports, rsa); + celix_array_list_t *exports_list = (celix_array_list_t *)celix_longHashMap_get(svcEntry->registrations, rsaSvcId); if (exports_list != NULL) { int exportsIter = 0; int exportListSize = celix_arrayList_size(exports_list); - for (exportsIter = 0; exports_list != NULL && exportsIter < exportListSize; exportsIter++) { + for (exportsIter = 0; exportsIter < exportListSize; exportsIter++) { export_registration_t *export = celix_arrayList_get(exports_list, exportsIter); topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); rsa->exportRegistration_close(rsa->admin, export); } celix_arrayList_destroy(exports_list); + celix_longHashMap_remove(svcEntry->registrations, rsaSvcId); } } - hashMapIterator_destroy(exportedSvcIter); hash_map_iterator_pt importedSvcIter = hashMapIterator_create(manager->importedServices); @@ -301,7 +679,8 @@ celix_status_t topologyManager_rsaRemoved(void * handle, service_reference_pt re } hashMapIterator_destroy(importedSvcIter); - celix_arrayList_remove(manager->rsaList, rsa); + free(celix_longHashMap_get(manager->rsaMap, rsaSvcId)); + celix_longHashMap_remove(manager->rsaMap, rsaSvcId); celixThreadMutex_unlock(&manager->lock); @@ -314,30 +693,30 @@ celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) celix_status_t status = CELIX_SUCCESS; topology_manager_pt manager = (topology_manager_pt) handle; service_registration_t *reg = NULL; - const char* serviceId = NULL; bool found; celix_properties_t *props; celix_autoptr(celix_filter_t) filter = celix_filter_create(filterStr); if (filter == NULL) { - printf("filter creating failed\n"); + celix_logHelper_error(manager->loghelper,"filter creating failed\n"); return CELIX_ENOMEM; } // add already exported services to new rsa - celixThreadMutex_lock(&manager->lock); + celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&manager->lock); - hash_map_iterator_pt exportedServicesIterator = hashMapIterator_create(manager->exportedServices); - int size = hashMap_size(manager->exportedServices); - service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt)); - char **srvIds = (char **) calloc(size, sizeof(char*)); + int size = celix_longHashMap_size(manager->exportedServices); + celix_autofree service_reference_pt *srvRefs = (service_reference_pt *) calloc(size, sizeof(service_reference_pt)); + if (srvRefs == NULL) { + return CELIX_ENOMEM; + } int nrFound = 0; found = false; - while (hashMapIterator_hasNext(exportedServicesIterator)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(exportedServicesIterator); - service_reference_pt reference = hashMapEntry_getKey(entry); + CELIX_LONG_HASH_MAP_ITERATE(manager->exportedServices, iter) { + celix_exported_service_entry_t* svcEntry = iter.value.ptrValue; + service_reference_pt reference = svcEntry->reference; reg = NULL; serviceReference_getServiceRegistration(reference, ®); if (reg != NULL) { @@ -345,15 +724,11 @@ celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) serviceRegistration_getProperties(reg, &props); status = filter_match(filter, props, &found); if (found) { - srvRefs[nrFound] = reference; - serviceReference_getProperty(reference, CELIX_FRAMEWORK_SERVICE_ID, &serviceId); - srvIds[nrFound++] = (char*)serviceId; + srvRefs[nrFound++] = reference; } } } - hashMapIterator_destroy(exportedServicesIterator); - if (nrFound > 0) { for (int i = 0; i < nrFound; i++) { // Question: can srvRefs become invalid meanwhile?? @@ -361,14 +736,8 @@ celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) serviceReference_getProperty(srvRefs[i], (char *) CELIX_RSA_SERVICE_EXPORTED_INTERFACES, &export); if (export) { - celix_status_t substatus = topologyManager_removeExportedService_nolock(manager, srvRefs[i], srvIds[i]); - - if (substatus != CELIX_SUCCESS) { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_ERROR, "TOPOLOGY_MANAGER: Removal of exported service (%s) failed.", srvIds[i]); - } else { - substatus = topologyManager_addExportedService_nolock(manager, srvRefs[i], srvIds[i]); - } - + topologyManager_removeExportedService_nolock(manager, srvRefs[i]); + celix_status_t substatus = topologyManager_addExportedService_nolock(manager, srvRefs[i]); if (substatus != CELIX_SUCCESS) { status = substatus; } @@ -376,12 +745,6 @@ celix_status_t topologyManager_exportScopeChanged(void *handle, char *filterStr) } } - free(srvRefs); - free(srvIds); - - // should unlock until here ?, avoid srvRefs[i] is released during topologyManager_removeExportedService - celixThreadMutex_unlock(&manager->lock); - return status; } @@ -439,11 +802,10 @@ static celix_status_t topologyManager_addImportedService_nolock(void *handle, en hashMap_put(manager->importedServices, endpoint, imports); if (scope_allowImport(manager->scope, endpoint)) { - int size = celix_arrayList_size(manager->rsaList); - - for (int iter = 0; iter < size; iter++) { + CELIX_LONG_HASH_MAP_ITERATE(manager->rsaMap, iter) { + celix_rsa_service_entry_t* rsaSvcEntry = iter.value.ptrValue; import_registration_t *import = NULL; - remote_service_admin_service_t *rsa = celix_arrayList_get(manager->rsaList, iter); + remote_service_admin_service_t *rsa = rsaSvcEntry->rsa; celix_status_t substatus = rsa->importService(rsa->admin, endpoint, &import); if (substatus == CELIX_SUCCESS) { hashMap_put(imports, rsa, import); @@ -523,7 +885,30 @@ celix_status_t topologyManager_removeImportedService(void *handle, endpoint_desc return status; } -static celix_status_t topologyManager_addExportedService_nolock(void * handle, service_reference_pt reference, void * service CELIX_UNUSED) { +static celix_exported_service_entry_t* exportedServiceEntry_create(topology_manager_t* tm, service_reference_pt reference) { + celix_autofree celix_exported_service_entry_t* svcEntry = calloc(1, sizeof(*svcEntry)); + if (svcEntry == NULL) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error allocating exported service entry."); + return NULL; + } + svcEntry->reference = reference; + celix_autoptr(celix_long_hash_map_t) registrations = svcEntry->registrations = celix_longHashMap_create(); + if (registrations == NULL) { + celix_logHelper_logTssErrors(tm->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error creating hash map for exported service registrations."); + return NULL; + } + celix_steal_ptr(registrations); + return celix_steal_ptr(svcEntry); +} + +static void exportedServiceEntry_destroy(celix_exported_service_entry_t* entry) { + celix_longHashMap_destroy(entry->registrations); + free(entry); + return; +} + +static celix_status_t topologyManager_addExportedService_nolock(void * handle, service_reference_pt reference) { topology_manager_pt manager = handle; celix_status_t status = CELIX_SUCCESS; long serviceId = serviceReference_getServiceId(reference); @@ -539,34 +924,59 @@ static celix_status_t topologyManager_addExportedService_nolock(void * handle, s scope_getExportProperties(manager->scope, reference, &serviceProperties); - hash_map_pt exports = hashMap_create(NULL, NULL, NULL, NULL); - assert(exports != NULL); - hashMap_put(manager->exportedServices, reference, exports); - int size = celix_arrayList_size(manager->rsaList); - - if (size == 0) { - celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_WARNING, "TOPOLOGY_MANAGER: No RSA available yet."); - } - - for (int iter = 0; iter < size; iter++) { - remote_service_admin_service_t *rsa = celix_arrayList_get(manager->rsaList, iter); + celix_exported_service_entry_t* svcEntry = exportedServiceEntry_create(manager, reference); + if (svcEntry == NULL) { + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error allocating exported service entry."); + return CELIX_ENOMEM; + } + status = celix_longHashMap_put(manager->exportedServices, serviceId, svcEntry); + if (status != CELIX_SUCCESS) { + exportedServiceEntry_destroy(svcEntry); + celix_logHelper_logTssErrors(manager->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error adding exported service entry to map."); + return status; + } - celix_array_list_t *endpoints = NULL; - celix_status_t substatus = rsa->exportService(rsa->admin, serviceIdStr, serviceProperties, &endpoints); + if (celix_longHashMap_size(manager->rsaMap) == 0) { + celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_WARNING, "TOPOLOGY_MANAGER: No RSA available yet."); + } - if (substatus == CELIX_SUCCESS) { - hashMap_put(exports, rsa, endpoints); - topologyManager_notifyListenersEndpointAdded(manager, rsa, endpoints); - } else { - status = substatus; - } + CELIX_LONG_HASH_MAP_ITERATE(manager->rsaMap, iter) { + long rsaSvcId = iter.key; + celix_rsa_service_entry_t* rsaSvcEntry = iter.value.ptrValue; + remote_service_admin_service_t *rsa = rsaSvcEntry->rsa; + + celix_autoptr(celix_array_list_t) registrationList = NULL; + celix_status_t substatus = rsa->exportService(rsa->admin, serviceIdStr, serviceProperties, ®istrationList); + if (substatus != CELIX_SUCCESS) { + status = substatus; + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error exporting service."); + continue; + } + substatus = celix_longHashMap_put(svcEntry->registrations, rsaSvcId, registrationList); + if (substatus != CELIX_SUCCESS) { + celix_logHelper_logTssErrors(manager->loghelper, CELIX_LOG_LEVEL_ERROR); + celix_logHelper_error(manager->loghelper, "TOPOLOGY_MANAGER: Error adding exported endpoints to map."); + for (int i = 0; i < celix_arrayList_size(registrationList); ++i) { + export_registration_t* reg = celix_arrayList_get(registrationList, i); + rsa->exportRegistration_close(rsa->admin, reg); + } + status = substatus; + continue; + } + if (rsaSvcEntry->dynamicIpSupport) { + topologyManager_addDynamicIpEndpointsForExportedService(manager, rsaSvcId, serviceId, registrationList); + } else { + topologyManager_notifyListenersEndpointAdded(manager, rsa, registrationList); + } + celix_steal_ptr(registrationList); } return status; } -celix_status_t topologyManager_addExportedService(void * handle, service_reference_pt reference, void * service) { +celix_status_t topologyManager_addExportedService(void * handle, service_reference_pt reference, void * service CELIX_UNUSED) { topology_manager_pt manager = handle; celix_status_t status = CELIX_SUCCESS; @@ -574,53 +984,52 @@ celix_status_t topologyManager_addExportedService(void * handle, service_referen celixThreadMutex_lock(&manager->lock); - status = topologyManager_addExportedService_nolock(handle, reference, service); + status = topologyManager_addExportedService_nolock(handle, reference); celixThreadMutex_unlock(&manager->lock); return status; } -static celix_status_t topologyManager_removeExportedService_nolock(void * handle, service_reference_pt reference, void * service CELIX_UNUSED) { +static void topologyManager_removeExportedService_nolock(void * handle, service_reference_pt reference) { topology_manager_pt manager = handle; - celix_status_t status = CELIX_SUCCESS; long serviceId = serviceReference_getServiceId(reference); celix_logHelper_log(manager->loghelper, CELIX_LOG_LEVEL_DEBUG, "TOPOLOGY_MANAGER: Remove exported service (%li).", serviceId); - 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_t *rsa = hashMapEntry_getKey(entry); - celix_array_list_t *exportRegistrations = hashMap_remove(exports, rsa); - if (exportRegistrations != NULL) { - int size = celix_arrayList_size(exportRegistrations); - for (int exportsIter = 0; exportsIter < size; exportsIter++) { - export_registration_t *export = celix_arrayList_get(exportRegistrations, exportsIter); - topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); - rsa->exportRegistration_close(rsa->admin, export); - } - celix_arrayList_destroy(exportRegistrations); - } - - hashMapIterator_destroy(iter); - iter = hashMapIterator_create(exports); + celix_exported_service_entry_t* svcEntry = celix_longHashMap_get(manager->exportedServices, serviceId); + if (svcEntry == NULL) { + celix_logHelper_debug(manager->loghelper, "TOPOLOGY_MANAGER: No exported service entry found for service id %li", serviceId); + return; + } - } - hashMapIterator_destroy(iter); - } - exports = hashMap_remove(manager->exportedServices, reference); + CELIX_LONG_HASH_MAP_ITERATE(svcEntry->registrations, iter) { + long rsaSvcId = iter.key; + celix_rsa_service_entry_t* rsaSvcEntry = celix_longHashMap_get(manager->rsaMap, rsaSvcId); + assert(rsaSvcEntry != NULL);//It must be not null, because the rsa will be removed from manager->exportedServices when rsa is removed + remote_service_admin_service_t* rsa = rsaSvcEntry->rsa; + + topologyManager_removeDynamicIpEndpointsForExportedService(manager, rsaSvcId, serviceId); + + celix_array_list_t *exportRegistrations = iter.value.ptrValue; + if (exportRegistrations != NULL) { + int size = celix_arrayList_size(exportRegistrations); + for (int exportsIter = 0; exportsIter < size; exportsIter++) { + export_registration_t *export = celix_arrayList_get(exportRegistrations, exportsIter); + topologyManager_notifyListenersEndpointRemoved(manager, rsa, export); + rsa->exportRegistration_close(rsa->admin, export); + } + celix_arrayList_destroy(exportRegistrations); + } + } - if (exports != NULL) { - hashMap_destroy(exports, false, false); - } + celix_longHashMap_remove(manager->exportedServices, serviceId); + exportedServiceEntry_destroy(svcEntry); - return status; + return; } -celix_status_t topologyManager_removeExportedService(void * handle, service_reference_pt reference, void * service) { +celix_status_t topologyManager_removeExportedService(void * handle, service_reference_pt reference, void * service CELIX_UNUSED) { topology_manager_pt manager = handle; celix_status_t status = CELIX_SUCCESS; @@ -628,7 +1037,7 @@ celix_status_t topologyManager_removeExportedService(void * handle, service_refe celixThreadMutex_lock(&manager->lock); - status = topologyManager_removeExportedService_nolock(handle, reference, service); + topologyManager_removeExportedService_nolock(handle, reference); celixThreadMutex_unlock(&manager->lock); @@ -659,6 +1068,27 @@ celix_status_t topologyManager_endpointListenerAdding(void* handle, service_refe return status; } +static void topologyManager_notifyDynamicIpEndpointsToListener(topology_manager_t* tm, endpoint_listener_t* listener, + char* scope, celix_filter_t* filter) { + CELIX_LONG_HASH_MAP_ITERATE(tm->dynamicIpEndpoints, iter) { + celix_long_hash_map_t* endpointMap = iter.value.ptrValue; + CELIX_LONG_HASH_MAP_ITERATE(endpointMap, iter2) { + celix_array_list_t* endpointList = (celix_array_list_t*)iter2.value.ptrValue; + int size = celix_arrayList_size(endpointList); + for (int i = 0; i < size; ++i) { + endpoint_description_t* endpoint = celix_arrayList_get(endpointList, i); + if (celix_filter_match(filter, endpoint->properties)) { + celix_status_t status = listener->endpointAdded(listener->handle, endpoint, scope); + if (status != CELIX_SUCCESS) { + celix_logHelper_error(tm->loghelper, "TOPOLOGY_MANAGER: Error adding endpoint to listener. %d", status); + } + } + } + } + } + return; +} + celix_status_t topologyManager_endpointListenerAdded(void* handle, service_reference_pt reference, void* service) { celix_status_t status = CELIX_SUCCESS; topology_manager_pt manager = handle; @@ -681,25 +1111,24 @@ celix_status_t topologyManager_endpointListenerAdded(void* handle, service_refer celix_autoptr(celix_filter_t) filter = celix_filter_create(scope); - hash_map_iterator_pt refIter = hashMapIterator_create(manager->exportedServices); - while (hashMapIterator_hasNext(refIter)) { - hash_map_pt rsaExports = hashMapIterator_nextValue(refIter); - hash_map_iterator_pt rsaIter = hashMapIterator_create(rsaExports); + CELIX_LONG_HASH_MAP_ITERATE(manager->exportedServices, iter) { + celix_exported_service_entry_t* svcEntry = iter.value.ptrValue; + CELIX_LONG_HASH_MAP_ITERATE(svcEntry->registrations, iter2) { + long rsaSvcId = iter2.key; + celix_rsa_service_entry_t* rsaSvcEntry = celix_longHashMap_get(manager->rsaMap, rsaSvcId); + celix_array_list_t *registrations = iter2.value.ptrValue; - while (hashMapIterator_hasNext(rsaIter)) { - hash_map_entry_pt entry = hashMapIterator_nextEntry(rsaIter); - remote_service_admin_service_t *rsa = hashMapEntry_getKey(entry); - celix_array_list_t *registrations = hashMapEntry_getValue(entry); + if (rsaSvcEntry->dynamicIpSupport) { + continue;//Dynamic ip endpoints are added later + } int arrayListSize = celix_arrayList_size(registrations); - int cnt = 0; - - for (; cnt < arrayListSize; cnt++) { + for (int cnt = 0; cnt < arrayListSize; cnt++) { export_registration_t *export = celix_arrayList_get(registrations, cnt); endpoint_description_t *endpoint = NULL; - status = topologyManager_getEndpointDescriptionForExportRegistration(rsa, export, &endpoint); + status = topologyManager_getEndpointDescriptionForExportRegistration(rsaSvcEntry->rsa, export, &endpoint); if (status == CELIX_SUCCESS) { bool matchResult = false; filter_match(filter, endpoint->properties, &matchResult); @@ -710,9 +1139,14 @@ celix_status_t topologyManager_endpointListenerAdded(void* handle, service_refer } } } - hashMapIterator_destroy(rsaIter); } - hashMapIterator_destroy(refIter); + + const char *interfaceSpecEndpointSupport = NULL; + serviceReference_getProperty(reference, CELIX_RSA_DISCOVERY_INTERFACE_SPECIFIC_ENDPOINTS_SUPPORT, &interfaceSpecEndpointSupport); + if (interfaceSpecEndpointSupport != NULL && strcmp(interfaceSpecEndpointSupport, "true") == 0) { + topologyManager_notifyDynamicIpEndpointsToListener(manager, (endpoint_listener_t *) service, (char *) scope, + filter); + } celixThreadMutex_unlock(&manager->lock); diff --git a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp index a7c64940e..9f07dddac 100644 --- a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp +++ b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp @@ -482,7 +482,6 @@ extern "C" { celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); - celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); @@ -535,7 +534,6 @@ extern "C" { celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); - celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); @@ -587,7 +585,6 @@ extern "C" { celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); - celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec celix_properties_set(props, "zone", "a_zone"); @@ -634,7 +631,6 @@ extern "C" { celix_properties_set(props, CELIX_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42"); celix_properties_set(props, CELIX_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42"); celix_properties_set(props, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE); - celix_properties_set(props, TST_CONFIGURATION_TYPE".url", "http://127.0.0.1:8080/calc"); celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_NAME, "org.apache.celix.test.MyBundle"); celix_properties_set(props, "service.version", "1.0.0"); celix_properties_set(props, "zone", "a_zone"); diff --git a/libs/utils/include/celix_errno.h b/libs/utils/include/celix_errno.h index e942afb05..8189192b3 100644 --- a/libs/utils/include/celix_errno.h +++ b/libs/utils/include/celix_errno.h @@ -124,7 +124,8 @@ CELIX_UTILS_EXPORT bool celix_utils_isCustomerStatusCode(celix_status_t code); #define CELIX_FACILITY_FRAMEWORK 1 /*! - * The facility of the http suppoter error code + * The facility of the http status error code + * @see https://en.wikipedia.org/wiki/List_of_HTTP_status_codes * */ #define CELIX_FACILITY_HTTP 2 @@ -135,6 +136,12 @@ CELIX_UTILS_EXPORT bool celix_utils_isCustomerStatusCode(celix_status_t code); */ #define CELIX_FACILITY_ZIP 3 +/*! + * The facility of the libcurl error code + * + */ +#define CELIX_FACILITY_CURL 4 + /*! * Make the error code accroding to the specification * \param fac Facility From 66a3f10cbf8a9ad0450be676d6e130bcab2a3c69 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sun, 4 Feb 2024 19:46:52 +0800 Subject: [PATCH 26/29] Improve unit test of discovery_zeroconf --- .../DiscoveryZeroconfAnnouncerTestSuite.cc | 26 ++++------------- .../src/DiscoveryZeroconfWatcherTestSuite.cc | 28 ------------------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc index af7bc489d..2f322a782 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfAnnouncerTestSuite.cc @@ -451,27 +451,11 @@ static void TestAddJumboEndpoint(celix_bundle_context *ctx, discovery_zeroconf_a discoveryZeroconfAnnouncer_endpointAdded(announcer, endpoint, nullptr); - bool found = false; - while (!found) { - DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", - [](DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char*, const char*, const char*, void* context){ - auto *found = static_cast(context); - *found = true; - }, &found); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(DNSServiceRefSockFD(dsRef), &readfds); - struct timeval tv{}; - tv.tv_sec = 3; - tv.tv_usec = 0; - int ret = select(DNSServiceRefSockFD(dsRef) + 1, &readfds, nullptr, nullptr, &tv); - if (ret > 0) { - DNSServiceProcessResult(dsRef); - } - DNSServiceRefDeallocate(dsRef); - } + DNSServiceRef dsRef{}; + DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", [](DNSServiceRef, DNSServiceFlags, uint32_t, DNSServiceErrorType, const char*, const char*, const char*, void* ){}, NULL); + EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); + DNSServiceProcessResult(dsRef); + DNSServiceRefDeallocate(dsRef); discoveryZeroconfAnnouncer_endpointRemoved(announcer, endpoint, nullptr); diff --git a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc index 8ff532ce8..ebf332c0a 100644 --- a/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc +++ b/bundles/remote_services/discovery_zeroconf/gtest/src/DiscoveryZeroconfWatcherTestSuite.cc @@ -345,34 +345,6 @@ class DiscoveryZeroconfWatcherWatchServiceTestSuite : public DiscoveryZeroconfWa sleep(3);//wait for mdnsd start testServiceRef = RegisterTestService(GetTestNetInterfaceIndex()); EXPECT_TRUE(testServiceRef != nullptr); - bool found = false; - while (!found) { - DNSServiceRef dsRef{}; - DNSServiceErrorType dnsErr = DNSServiceBrowse(&dsRef, 0, 0, DZC_SERVICE_PRIMARY_TYPE, "local.", - [](DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) { - (void)sdRef; - (void)flags; - (void)interfaceIndex; - (void)errorCode; - (void)serviceName; - (void)regtype; - (void)replyDomain; - auto *found = static_cast(context); - *found = true; - }, &found); - EXPECT_EQ(dnsErr, kDNSServiceErr_NoError); - fd_set readfds; - FD_ZERO(&readfds); - FD_SET(DNSServiceRefSockFD(dsRef), &readfds); - struct timeval tv{}; - tv.tv_sec = 3; - tv.tv_usec = 0; - int ret = select(DNSServiceRefSockFD(dsRef) + 1, &readfds, nullptr, nullptr, &tv); - if (ret > 0) { - DNSServiceProcessResult(dsRef); - } - DNSServiceRefDeallocate(dsRef); - } } static void TearDownTestCase() { From ce4dc3be91557a9dbfff113662df4391005db9ec Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sun, 4 Feb 2024 21:56:35 +0800 Subject: [PATCH 27/29] Replace OSGI_RSA_ prefix to CELIX_RSA_ --- .../remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c | 2 +- .../rsa_common/src/remote_proxy_factory_impl.c | 2 +- bundles/remote_services/topology_manager/src/activator.c | 2 +- .../remote_services/topology_manager/src/topology_manager.h | 1 - examples/conan_test_package/my_rsa_activator.c | 4 ++-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c index f667bb6aa..6e8c9ff08 100755 --- a/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c +++ b/bundles/remote_services/remote_service_admin_shm_v2/rsa_shm/src/rsa_shm_impl.c @@ -255,7 +255,7 @@ static void rsaShm_overlayProperties(celix_properties_t *additionalProperties, c static bool rsaShm_isConfigTypeMatched(celix_properties_t *properties) { bool matched = false; - /* If OSGI_RSA_SERVICE_EXPORTED_CONFIGS property is not set, then the Remote Service + /* If CELIX_RSA_SERVICE_EXPORTED_CONFIGS property is not set, then the Remote Service * Admin implementation must choose a convenient configuration type. */ const char *exportConfigs = celix_properties_get(properties, diff --git a/bundles/remote_services/rsa_common/src/remote_proxy_factory_impl.c b/bundles/remote_services/rsa_common/src/remote_proxy_factory_impl.c index 3e455951c..a72a7d7ca 100644 --- a/bundles/remote_services/rsa_common/src/remote_proxy_factory_impl.c +++ b/bundles/remote_services/rsa_common/src/remote_proxy_factory_impl.c @@ -112,7 +112,7 @@ celix_status_t remoteProxyFactory_register(remote_proxy_factory_t *remote_proxy_ } if (status == CELIX_SUCCESS) { - status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, OSGI_RSA_REMOTE_PROXY_FACTORY, + status = bundleContext_registerService(remote_proxy_factory_ptr->context_ptr, CELIX_RSA_REMOTE_PROXY_FACTORY, remote_proxy_factory_ptr->remote_proxy_factory_service_ptr, remote_proxy_factory_ptr->properties, &remote_proxy_factory_ptr->registration); } diff --git a/bundles/remote_services/topology_manager/src/activator.c b/bundles/remote_services/topology_manager/src/activator.c index 62c5999a1..d113ad3f5 100644 --- a/bundles/remote_services/topology_manager/src/activator.c +++ b/bundles/remote_services/topology_manager/src/activator.c @@ -36,11 +36,11 @@ #include "topology_manager.h" #include "endpoint_listener.h" #include "remote_constants.h" +#include "remote_service_admin.h" #include "listener_hook_service.h" #include "celix_log_helper.h" #include "scope.h" #include "tm_scope.h" -#include "topology_manager.h" struct activator { celix_bundle_context_t *context; diff --git a/bundles/remote_services/topology_manager/src/topology_manager.h b/bundles/remote_services/topology_manager/src/topology_manager.h index 9e88c2226..9c841750d 100644 --- a/bundles/remote_services/topology_manager/src/topology_manager.h +++ b/bundles/remote_services/topology_manager/src/topology_manager.h @@ -33,7 +33,6 @@ #include "celix_log_helper.h" #include "scope.h" -#define CELIX_RSA_REMOTE_SERVICE_ADMIN "remote_service_admin" typedef struct topology_manager topology_manager_t; typedef struct topology_manager *topology_manager_pt; diff --git a/examples/conan_test_package/my_rsa_activator.c b/examples/conan_test_package/my_rsa_activator.c index 8ba78934c..449b50604 100644 --- a/examples/conan_test_package/my_rsa_activator.c +++ b/examples/conan_test_package/my_rsa_activator.c @@ -56,7 +56,7 @@ static celix_status_t remoteServiceAdmin_getImportedEndpoints(remote_service_adm } static celix_status_t remoteServiceAdmin_importService(remote_service_admin_t *admin, endpoint_description_t *endpointDescription, import_registration_t **out) { - const char *importConfigs = celix_properties_get(endpointDescription->properties, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, NULL); + const char *importConfigs = celix_properties_get(endpointDescription->properties, CELIX_RSA_SERVICE_IMPORTED_CONFIGS, NULL); celix_logHelper_info(admin->loghelper, "%s called: %s\n", __FUNCTION__, importConfigs); return CELIX_ILLEGAL_ARGUMENT; } @@ -107,7 +107,7 @@ static celix_status_t my_rsa_start(my_remote_service_admin_activator_t* activato activator->adminService.importRegistration_getException = importRegistration_getException; activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference; - activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, OSGI_RSA_REMOTE_SERVICE_ADMIN, NULL); + activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, CELIX_RSA_REMOTE_SERVICE_ADMIN, NULL); } return status; From 8e14b97442908ae6be0a46412b6575462ca30e85 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sun, 4 Feb 2024 23:46:26 +0800 Subject: [PATCH 28/29] Remove IPV6 server for RSA_DFI, because civetweb not support IPV6 in linux-build-apt workflow --- .../gtest/src/rsa_client_server_tests.cc | 6 ------ .../remote_service_admin_dfi/src/remote_service_admin_dfi.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc index 47f2d5296..7fb210585 100644 --- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc +++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc @@ -538,9 +538,3 @@ TEST_F(RsaDfiDynamicIpServerTestSuite, CallingMultiTimesRemoteCalculatorTest) { }); } -TEST_F(RsaDfiDynamicIpServerTestSuite, IPV6RemoteCalculatorTest) { - TestRemoteCalculator([](tst_service_t* testSvc) { - auto ok = testSvc->testCalculator(testSvc->handle); - ASSERT_TRUE(ok); - }, "::1"); -} 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 index b3c354e52..87b5b3ffa 100644 --- 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 @@ -275,7 +275,7 @@ celix_status_t remoteServiceAdmin_create(celix_bundle_context_t *context, remote do { char *listeningPorts = NULL; if (bindToAllInterfaces || (*admin)->dynamicIpSupport) { - asprintf(&listeningPorts,"0.0.0.0:%s,[::]:%s", newPort,newPort); + asprintf(&listeningPorts,"0.0.0.0:%s", newPort); } else { asprintf(&listeningPorts,"%s:%s", (*admin)->ip, newPort); } From e48e5ed69654bafa61be0e070859e12deeca77f5 Mon Sep 17 00:00:00 2001 From: xuzhenbao Date: Sun, 18 Feb 2024 20:00:10 +0800 Subject: [PATCH 29/29] Improve CURL error code handling --- .../src/remote_service_admin_dfi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) 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 index 87b5b3ffa..aa4224758 100644 --- 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 @@ -966,6 +966,16 @@ celix_status_t remoteServiceAdmin_removeImportedService(remote_service_admin_t * return status; } +static bool shouldTryUseOtherDynamicIp(celix_status_t useUrlStatus) { + switch (useUrlStatus) { + case CELIX_SUCCESS: + case CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_OUT_OF_MEMORY): + return false; + default: + return true; + } +} + static celix_status_t remoteServiceAdmin_useDynamicIpUrlsForEndpoint(remote_service_admin_t* rsa, endpoint_description_t* endpointDescription, celix_status_t (*useUrl)(void* handle, const char* url), void* handle) { celix_status_t status = CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT); @@ -979,7 +989,7 @@ celix_status_t (*useUrl)(void* handle, const char* url), void* handle) { } else { celixThreadMutex_unlock(&rsa->importedServicesLock); } - if (status != CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT)) { + if (!shouldTryUseOtherDynamicIp(status)) { return status; } @@ -1004,7 +1014,7 @@ celix_status_t (*useUrl)(void* handle, const char* url), void* handle) { snprintf(url, sizeof(url), "http://[%s]:%d%s", ip, port, serviceUrl); } status = useUrl(handle, url); - if (status != CELIX_ERROR_MAKE(CELIX_FACILITY_CURL,CURLE_COULDNT_CONNECT)) { + if (!shouldTryUseOtherDynamicIp(status)) { celix_imported_endpoint_url_ref_t* urlRefNew = calloc(1, sizeof(*urlRefNew) + strlen(url) + 1); if (urlRefNew == NULL) { celix_logHelper_error(rsa->loghelper, "Error allocating memory for imported endpoint url reference");