Пример #1
0
static celix_status_t etcdWatcher_addAlreadyExistingNodes(node_discovery_pt node_discovery, int* highestModified) {
    celix_status_t status = CELIX_SUCCESS;
    char** endpointArray = calloc(MAX_NODES, sizeof(*endpointArray));
    char rootPath[MAX_ROOTNODE_LENGTH];
    int i, size;

    *highestModified = -1;

    if (!endpointArray) {
        status = CELIX_ENOMEM;
    } else {

        for (i = 0; i < MAX_NODES; i++) {
            endpointArray[i] = calloc(MAX_KEY_LENGTH, sizeof(*endpointArray[i]));
        }

        // we need to go though all nodes and get the highest modifiedIndex
        if (((status = etcdWatcher_getRootPath(node_discovery->context, &rootPath[0])) == CELIX_SUCCESS) && (etcd_getEndpoints(rootPath, endpointArray, &size) == true)) {
            for (i = 0; i < size; i++) {
                node_description_pt nodeDescription = NULL;

                char* key = endpointArray[i];
                int modIndex = 0;

                // check for key ..

                char action[MAX_ACTION_LENGTH];
                char etcdValue[MAX_VALUE_LENGTH];

                if (etcd_get(key, &etcdValue[0], &action[0], &modIndex) != true) {
                    printf("NODE_DISCOVERY: Could not retrieve value for %s\n", key);
                    status = CELIX_ILLEGAL_STATE;
                }
                else  {
                    status = etcdWatcher_getWiringEndpointFromKey(node_discovery, key, &etcdValue[0], &nodeDescription);

                    node_discovery_addNode(node_discovery, nodeDescription);
                }

                if (modIndex > *highestModified) {
                    *highestModified = modIndex;
                }
            }
        }

        for (i = 0; i < MAX_NODES; i++) {
            free(endpointArray[i]);
        }
    }

    free(endpointArray);

    return status;
}
Пример #2
0
static celix_status_t etcdWatcher_getLocalNodePath(bundle_context_pt context, node_description_pt ownNodeDescription, char* localNodePath) {
    celix_status_t status = CELIX_SUCCESS;
    char rootPath[MAX_ROOTNODE_LENGTH];

    if ((etcdWatcher_getRootPath(context, &rootPath[0]) != CELIX_SUCCESS)) {
        status = CELIX_ILLEGAL_STATE;
    } else if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
        snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s/%s", &rootPath[0], ownNodeDescription->zoneId, ownNodeDescription->nodeId);
    } else {
        snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s/%s", &rootPath[0], ownNodeDescription->zoneId, ownNodeDescription->nodeId);
    }

    return status;
}
Пример #3
0
// gets everything from provided key
celix_status_t etcdWatcher_getWiringEndpointFromKey(node_discovery_pt node_discovery, char* etcdKey, char* etcdValue, node_description_pt* nodeDescription) {

    celix_status_t status = CELIX_SUCCESS;

    char rootPath[MAX_ROOTNODE_LENGTH];
    char expr[MAX_LOCALNODE_LENGTH];
    char zoneId[MAX_LOCALNODE_LENGTH];
    char nodeId[MAX_LOCALNODE_LENGTH];
    char wireId[MAX_LOCALNODE_LENGTH];

    etcdWatcher_getRootPath(node_discovery->context, &rootPath[0]);

    snprintf(expr, MAX_LOCALNODE_LENGTH, "/%s/%%[^/]/%%[^/]/%%[^/].*", rootPath);

    int foundItems = sscanf(etcdKey, expr, &zoneId[0], &nodeId[0], &wireId[0]);

    if (foundItems != 3) {
        printf("NODE_DISCOVERY: Could not find zone/node/wire (key: %s) \n", etcdKey);
        status = CELIX_ILLEGAL_STATE;
    } else {
        properties_pt nodeDescProperties = properties_create();
        status = nodeDescription_create(nodeId, zoneId, nodeDescProperties, nodeDescription);

        if (status == CELIX_SUCCESS) {
            wiring_endpoint_description_pt wiringEndpointDescription = NULL;
            properties_pt wiringDescProperties = properties_create();

            if (etcdValue != NULL) {
                if (wiringEndpoint_properties_load(etcdValue, wiringDescProperties) != CELIX_SUCCESS) {
                    printf("NODE_DISCOVERY:  Error while loading wiring properties");
                }
            }

            status = wiringEndpointDescription_create(wireId, wiringDescProperties, &wiringEndpointDescription);

            if (status == CELIX_SUCCESS) {
                celixThreadMutex_lock(&(*nodeDescription)->wiring_ep_desc_list_lock);
                arrayList_add((*nodeDescription)->wiring_ep_descriptions_list, wiringEndpointDescription);
                celixThreadMutex_unlock(&(*nodeDescription)->wiring_ep_desc_list_lock);
            }
        } else {
            printf("NODE_DISCOVERY:  Could not create Node description\n");
        }
    }

    return status;
}
Пример #4
0
/*
 * performs (blocking) etcd_watch calls to check for
 * changing discovery endpoint information within etcd.
 */
static void* etcdWatcher_run(void* data) {
    etcd_watcher_pt watcher = (etcd_watcher_pt) data;
    time_t timeBeforeWatch = time(NULL);
    static char rootPath[MAX_ROOTNODE_LENGTH];
    int highestModified = 0;

    bundle_context_pt context = watcher->discovery->context;

    etcdWatcher_addAlreadyExistingWatchpoints(watcher->discovery, &highestModified);
    etcdWatcher_getRootPath(context, &rootPath[0]);

    while (watcher->running) {

        char rkey[MAX_KEY_LENGTH];
        char value[MAX_VALUE_LENGTH];
        char preValue[MAX_VALUE_LENGTH];
        char action[MAX_ACTION_LENGTH];
        int modIndex;

        if (etcd_watch(rootPath, highestModified + 1, &action[0], &preValue[0], &value[0], &rkey[0], &modIndex) == true) {
            if (strcmp(action, "set") == 0) {
                etcdWatcher_addEntry(watcher, &rkey[0], &value[0]);
            } else if (strcmp(action, "delete") == 0) {
                etcdWatcher_removeEntry(watcher, &rkey[0], &value[0]);
            } else if (strcmp(action, "expire") == 0) {
                etcdWatcher_removeEntry(watcher, &rkey[0], &value[0]);
            } else if (strcmp(action, "update") == 0) {
                etcdWatcher_addEntry(watcher, &rkey[0], &value[0]);
            } else {
                logHelper_log(*watcher->loghelper, OSGI_LOGSERVICE_INFO, "Unexpected action: %s", action);
            }

            highestModified = modIndex;
        }

        // update own framework uuid
        if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL/2)) {
            etcdWatcher_addOwnFramework(watcher);
            timeBeforeWatch = time(NULL);
        }
    }

    return NULL;
}
Пример #5
0
static celix_status_t etcdWatcher_getLocalNodePath(bundle_context_pt context, char* localNodePath) {
    celix_status_t status = CELIX_SUCCESS;
    char rootPath[MAX_ROOTNODE_LENGTH];
    char* uuid = NULL;

    if ((etcdWatcher_getRootPath(context, &rootPath[0]) != CELIX_SUCCESS)) {
        status = CELIX_ILLEGAL_STATE;
    }
    else if (((bundleContext_getProperty(context, OSGI_FRAMEWORK_FRAMEWORK_UUID, &uuid)) != CELIX_SUCCESS) || (!uuid)) {
        status = CELIX_ILLEGAL_STATE;
    }
    else if (rootPath[strlen(&rootPath[0]) - 1] == '/') {
        snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s%s", &rootPath[0], uuid);
    }
    else {
        snprintf(localNodePath, MAX_LOCALNODE_LENGTH, "%s/%s", &rootPath[0], uuid);
    }

    return status;
}
Пример #6
0
/*
 * retrieves all already existing discovery endpoints
 * from etcd and adds them to the poller.
 *
 * returns the modifiedIndex of the last modified
 * discovery endpoint (see etcd documentation).
 */
static celix_status_t etcdWatcher_addAlreadyExistingWatchpoints(discovery_pt discovery, int* highestModified) {
    celix_status_t status = CELIX_SUCCESS;
    char** nodeArr = calloc(MAX_NODES, sizeof(*nodeArr));
    char rootPath[MAX_ROOTNODE_LENGTH];
    int i, size;

    *highestModified = -1;

    for (i = 0; i < MAX_NODES; i++) {
        nodeArr[i] = calloc(MAX_KEY_LENGTH, sizeof(*nodeArr[i]));
    }

    // we need to go though all nodes and get the highest modifiedIndex
    if (((status = etcdWatcher_getRootPath(discovery->context, &rootPath[0])) == CELIX_SUCCESS) &&
            (etcd_getNodes(rootPath, nodeArr, &size) == true)) {
        for (i = 0; i < size; i++) {
            char* key = nodeArr[i];
            char value[MAX_VALUE_LENGTH];
            char action[MAX_VALUE_LENGTH];
            int modIndex;

            if (etcd_get(key, &value[0], &action[0], &modIndex) == true) {
                // TODO: check that this is not equals to the local endpoint
                endpointDiscoveryPoller_addDiscoveryEndpoint(discovery->poller, &value[0]);

                if (modIndex > *highestModified) {
                    *highestModified = modIndex;
                }
            }
        }
    }

    for (i = 0; i < MAX_NODES; i++) {
        free(nodeArr[i]);
    }

    free(nodeArr);

    return status;
}
Пример #7
0
/*
 * performs (blocking) etcd_watch calls to check for
 * changing discovery endpoint information within etcd.
 */
static void* etcdWatcher_run(void* data) {
    etcd_watcher_pt watcher = (etcd_watcher_pt) data;
    time_t timeBeforeWatch = time(NULL);
    char rootPath[MAX_ROOTNODE_LENGTH];
    int highestModified = 0;

    node_discovery_pt node_discovery = watcher->node_discovery;
    bundle_context_pt context = node_discovery->context;

    memset(rootPath, 0, MAX_ROOTNODE_LENGTH);

    etcdWatcher_addAlreadyExistingNodes(node_discovery, &highestModified);
    etcdWatcher_getRootPath(context, rootPath);

    while ((celixThreadMutex_lock(&watcher->watcherLock) == CELIX_SUCCESS) && watcher->running) {

        char rkey[MAX_KEY_LENGTH];
        char value[MAX_VALUE_LENGTH];
        char preValue[MAX_VALUE_LENGTH];
        char action[MAX_ACTION_LENGTH];
        int modIndex;

        celixThreadMutex_unlock(&watcher->watcherLock);

        if (etcd_watch(rootPath, highestModified + 1, &action[0], &preValue[0], &value[0], &rkey[0], &modIndex) == true) {
            if ((strcmp(action, "set") == 0) || (strcmp(action, "create") == 0)) {
                node_description_pt nodeDescription = NULL;
                celix_status_t status = etcdWatcher_getWiringEndpointFromKey(node_discovery, &rkey[0], &value[0], &nodeDescription);

                if (status == CELIX_SUCCESS) {
                    node_discovery_addNode(node_discovery, nodeDescription);
                }
            } else if (strcmp(action, "delete") == 0) {
                node_description_pt nodeDescription = NULL;
                celix_status_t status = etcdWatcher_getWiringEndpointFromKey(node_discovery, &rkey[0], NULL, &nodeDescription);
                if (status == CELIX_SUCCESS) {
                    node_discovery_removeNode(node_discovery, nodeDescription);
                }
            } else if (strcmp(action, "expire") == 0) {
                node_description_pt nodeDescription = NULL;
                celix_status_t status = etcdWatcher_getWiringEndpointFromKey(node_discovery, &rkey[0], NULL, &nodeDescription);
                if (status == CELIX_SUCCESS) {
                    node_discovery_removeNode(node_discovery, nodeDescription);
                }
            } else if (strcmp(action, "update") == 0) {
                node_description_pt nodeDescription = NULL;
                celix_status_t status = etcdWatcher_getWiringEndpointFromKey(node_discovery, &rkey[0], &value[0], &nodeDescription);

                if (status == CELIX_SUCCESS) {
                    node_discovery_addNode(node_discovery, nodeDescription);
                }
            } else {
                fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Unexpected action: %s", action);
            }
            highestModified = modIndex;
        }
        /* prevent busy waiting, in case etcd_watch returns false */
        else if (time(NULL) - timeBeforeWatch <= (DEFAULT_ETCD_TTL / 4)) {
            sleep(DEFAULT_ETCD_TTL / 4);
        }

        // update own framework uuid
        if (time(NULL) - timeBeforeWatch > (DEFAULT_ETCD_TTL / 4)) {
            etcdWatcher_addOwnNode(watcher);

            // perform additional full-sync
            etcdWatcher_addAlreadyExistingNodes(node_discovery, &highestModified);
            timeBeforeWatch = time(NULL);
        }
    }

    if (watcher->running == false) {
        celixThreadMutex_unlock(&watcher->watcherLock);
    }

    return NULL;
}