static celix_status_t etcdWatcher_addOwnFramework(etcd_watcher_pt watcher) { celix_status_t status = CELIX_BUNDLE_EXCEPTION; char localNodePath[MAX_LOCALNODE_LENGTH]; char value[MAX_VALUE_LENGTH]; char action[MAX_VALUE_LENGTH]; char url[MAX_VALUE_LENGTH]; int modIndex; char* endpoints = NULL; char* ttlStr = NULL; int ttl; bundle_context_pt context = watcher->discovery->context; endpoint_discovery_server_pt server = watcher->discovery->server; // register own framework if ((status = etcdWatcher_getLocalNodePath(context, &localNodePath[0])) != CELIX_SUCCESS) { return status; } if (endpointDiscoveryServer_getUrl(server, &url[0]) != CELIX_SUCCESS) { snprintf(url, MAX_VALUE_LENGTH, "http://%s:%s/%s", DEFAULT_SERVER_IP, DEFAULT_SERVER_PORT, DEFAULT_SERVER_PATH); } endpoints = &url[0]; if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) { ttl = DEFAULT_ETCD_TTL; } else { char* endptr = ttlStr; errno = 0; ttl = strtol(ttlStr, &endptr, 10); if (*endptr || errno != 0) { ttl = DEFAULT_ETCD_TTL; } } if (etcd_get(localNodePath, &value[0], &action[0], &modIndex) != true) { etcd_set(localNodePath, endpoints, ttl, false); } else if (etcd_set(localNodePath, endpoints, ttl, true) == false) { logHelper_log(*watcher->loghelper, OSGI_LOGSERVICE_WARNING, "Cannot register local discovery"); } else { status = CELIX_SUCCESS; } return status; }
int main(int argc, char *argv[]) { char *h; etcd_response response; const struct etcd_data *val; const char *key = "/key1", *value = "value1"; if (argc <= 1) { hostname = DEFAULT_HOSTNAME; port = DEFAULT_PORT; } else { /* Input in format 'host:port' */ hostname = h = strdup(argv[1]); h = strchr(hostname, ':'); *h++ = '\0'; port = atoi(h); } response = etcd_set(key, value, 0); assert(response == ETCD_SUCCESS); val = etcd_get(key); assert(val->response == ETCD_SUCCESS); assert(strcmp(val->value, value) == 0); free((struct etcd_data *)val); response = etcd_delete(key); assert(response == ETCD_SUCCESS); val = etcd_get(key); assert(val->response == ETCD_FAILURE); free((struct etcd_data *)val); response = etcd_set(key, value, 5); assert(response == ETCD_SUCCESS); response = etcd_test_and_set(key, "value2", value, 0); assert(response == ETCD_SUCCESS); response = etcd_test_and_set(key, "value2", value, 0); assert(response == ETCD_FAILURE); return 0; }
celix_status_t etcdWatcher_addOwnNode(etcd_watcher_pt watcher) { celix_status_t status = CELIX_BUNDLE_EXCEPTION; char localNodePath[MAX_LOCALNODE_LENGTH]; char* ttlStr = NULL; int ttl; node_discovery_pt node_discovery = watcher->node_discovery; bundle_context_pt context = node_discovery->context; node_description_pt ownNodeDescription = node_discovery->ownNode; // register own framework status = etcdWatcher_getLocalNodePath(context, ownNodeDescription, &localNodePath[0]); // determine ttl if ((bundleContext_getProperty(context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) { ttl = DEFAULT_ETCD_TTL; } else { char* endptr = ttlStr; errno = 0; ttl = strtol(ttlStr, &endptr, 10); if (*endptr || errno != 0) { ttl = DEFAULT_ETCD_TTL; } } // register every wiring endpoint array_list_iterator_pt endpointIter = arrayListIterator_create(ownNodeDescription->wiring_ep_descriptions_list); while (status == CELIX_SUCCESS && arrayListIterator_hasNext(endpointIter)) { wiring_endpoint_description_pt wiringEndpointDesc = arrayListIterator_next(endpointIter); if (wiringEndpointDesc == NULL) { status = CELIX_ILLEGAL_ARGUMENT; } else { char etcdKey[MAX_LOCALNODE_LENGTH]; char etcdValue[MAX_LOCALNODE_LENGTH]; char* wireId = properties_get(wiringEndpointDesc->properties, WIRING_ENDPOINT_DESCRIPTION_WIRE_ID_KEY); wiringEndpoint_properties_store(wiringEndpointDesc->properties, &etcdValue[0]); snprintf(etcdKey, MAX_LOCALNODE_LENGTH, "%s/%s", localNodePath, wireId); // TODO : implement update etcd_set(etcdKey, etcdValue, ttl, false); } } arrayListIterator_destroy(endpointIter); return status; }
etcd_response etcd_test_and_set(const char *key, const char *value, const char *oldValue, unsigned ttl) { char *url, *data, *tmpdata; const struct etcd_data *retdata; etcd_response response; int ret; if (!is_valid_key(key) || !is_valid_value(value)) { return ETCD_FAILURE; } if (!is_valid_value(oldValue)) { /* If the old value is NULL, then this should act like etcd_set() */ if (oldValue == NULL) { return etcd_set(key, value, ttl); } return ETCD_FAILURE; } url = etcd_url(key, NULL); ret = asprintf(&data, "value=%s&prevValue=%s", value, oldValue); assert(ret >= 0); if (ttl > 0) { ret = asprintf(&tmpdata, "%s&ttl=%u", data, ttl); assert(ret >= 0); free(data); data = tmpdata; } retdata = http_request(url, ETCD_SET, data); assert(retdata != NULL); response = retdata->response; if (response == ETCD_FAILURE) { debug(retdata->errmsg); } free(url); free(data); free((struct etcd_data *)retdata); return response; }
celix_status_t etcdWriter_addPublisherEndpoint(etcd_writer_pt writer, pubsub_endpoint_pt pubEP, bool storeEP){ celix_status_t status = CELIX_BUNDLE_EXCEPTION; if(storeEP){ const char *fwUUID = NULL; bundleContext_getProperty(writer->pubsub_discovery->context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &fwUUID); if(fwUUID && strcmp(pubEP->frameworkUUID, fwUUID) == 0) { celixThreadMutex_lock(&writer->localPubsLock); pubsub_endpoint_pt p = NULL; pubsubEndpoint_clone(pubEP, &p); arrayList_add(writer->localPubs,p); celixThreadMutex_unlock(&writer->localPubsLock); } } char *key; const char* ttlStr = NULL; int ttl = 0; // determine ttl if ((bundleContext_getProperty(writer->pubsub_discovery->context, CFG_ETCD_TTL, &ttlStr) != CELIX_SUCCESS) || !ttlStr) { ttl = DEFAULT_ETCD_TTL; } else { char* endptr = NULL; errno = 0; ttl = strtol(ttlStr, &endptr, 10); if (*endptr || errno != 0) { ttl = DEFAULT_ETCD_TTL; } } const char *rootPath = etcdWriter_getRootPath(writer->pubsub_discovery->context); asprintf(&key,"%s/%s/%s/%s/%ld",rootPath,pubEP->scope,pubEP->topic,pubEP->frameworkUUID,pubEP->serviceID); if(!etcd_set(key,pubEP->endpoint,ttl,false)){ status = CELIX_ILLEGAL_ARGUMENT; } FREE_MEM(key); return status; }