static filter_pt filter_parseFilter(char * filterString, int * pos) { filter_pt filter; filter_skipWhiteSpace(filterString, pos); if (filterString[*pos] != '(') { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '(' in filter string '%s'.", filterString); return NULL; } (*pos)++; filter = filter_parseFilterComp(filterString, pos); filter_skipWhiteSpace(filterString, pos); if (filterString[*pos] != ')') { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing ')' in filter string '%s'.", filterString); if(filter!=NULL){ filter_destroy(filter); } return NULL; } (*pos)++; filter_skipWhiteSpace(filterString, pos); if(filter != NULL){ if(filter->value == NULL && filter->operand!=PRESENT){ filter_destroy(filter); return NULL; } } return filter; }
static char * filter_parseAttr(char * filterString, int * pos) { char c; int begin = *pos; int end = *pos; int length = 0; filter_skipWhiteSpace(filterString, pos); c = filterString[*pos]; while (c != '~' && c != '<' && c != '>' && c != '=' && c != '(' && c != ')') { (*pos)++; if (!isspace(c)) { end = *pos; } c = filterString[*pos]; } length = end - begin; if (length == 0) { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing attr."); return NULL; } else { char * attr = (char *) malloc(length+1); strncpy(attr, filterString+begin, length); attr[length] = '\0'; return attr; } }
static char * filter_parseValue(char * filterString, int * pos) { char *value = calloc(strlen(filterString) + 1, sizeof(*value)); int keepRunning = 1; while (keepRunning) { char c = filterString[*pos]; switch (c) { case ')': { keepRunning = 0; break; } case '(': { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid value."); free(value); return NULL; } case '\0':{ fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Unclosed bracket."); free(value); return NULL; } case '\\': { (*pos)++; c = filterString[*pos]; } /* no break */ default: { char ch[2]; ch[0] = c; ch[1] = '\0'; strcat(value, ch); (*pos)++; break; } } } if (strlen(value) == 0) { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing value."); free(value); return NULL; } return value; }
filter_pt filter_create(const char* filterString) { filter_pt filter = NULL; char* filterStr = (char*) filterString; int pos = 0; filter = filter_parseFilter(filterStr, &pos); if (pos != strlen(filterStr)) { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Extraneous trailing characters."); filter_destroy(filter); return NULL; } if(filter != NULL){ filter->filterStr = filterStr; } return filter; }
static filter_pt filter_parseNot(char * filterString, int * pos) { filter_pt child = NULL; filter_skipWhiteSpace(filterString, pos); if (filterString[*pos] != '(') { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '('."); return NULL; } child = filter_parseFilter(filterString, pos); filter_pt filter = (filter_pt) malloc(sizeof(*filter)); filter->operand = NOT; filter->attribute = NULL; filter->value = child; return filter; }
static filter_pt filter_parseOr(char * filterString, int * pos) { array_list_pt operands = NULL; filter_skipWhiteSpace(filterString, pos); bool failure = false; if (filterString[*pos] != '(') { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: Missing '('."); return NULL; } arrayList_create(&operands); while(filterString[*pos] == '(') { filter_pt child = filter_parseFilter(filterString, pos); if(child == NULL){ failure = true; break; } arrayList_add(operands, child); } if(failure == true){ array_list_iterator_pt listIt = arrayListIterator_create(operands); while(arrayListIterator_hasNext(listIt)){ filter_pt f = arrayListIterator_next(listIt); filter_destroy(f); } arrayListIterator_destroy(listIt); arrayList_destroy(operands); operands = NULL; } filter_pt filter = (filter_pt) malloc(sizeof(*filter)); filter->operand = OR; filter->attribute = NULL; filter->value = operands; return filter; }
/* * 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; }
static array_list_pt filter_parseSubstring(char * filterString, int * pos) { char *sub = calloc(strlen(filterString) + 1, sizeof(*sub)); array_list_pt operands = NULL; int keepRunning = 1; arrayList_create(&operands); while (keepRunning) { char c = filterString[*pos]; switch (c) { case ')': { if (strlen(sub) > 0) { arrayList_add(operands, strdup(sub)); } keepRunning = 0; break; } case '\0':{ fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Unclosed bracket."); keepRunning = false; break; } case '(': { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid value."); keepRunning = false; break; } case '*': { if (strlen(sub) > 0) { arrayList_add(operands, strdup(sub)); } sub[0] = '\0'; arrayList_add(operands, NULL); (*pos)++; break; } case '\\': { (*pos)++; c = filterString[*pos]; } /* no break */ default: { char ch[2]; ch[0] = c; ch[1] = '\0'; strcat(sub, ch); (*pos)++; break; } } } free(sub); if (arrayList_size(operands) == 0) { fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Missing value."); arrayList_destroy(operands); return NULL; } return operands; }
static filter_pt filter_parseItem(char * filterString, int * pos) { char * attr = filter_parseAttr(filterString, pos); if(attr == NULL){ return NULL; } filter_skipWhiteSpace(filterString, pos); switch(filterString[*pos]) { case '~': { if (filterString[*pos + 1] == '=') { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); *pos += 2; filter->operand = APPROX; filter->attribute = attr; filter->value = filter_parseValue(filterString, pos); return filter; } break; } case '>': { if (filterString[*pos + 1] == '=') { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); *pos += 2; filter->operand = GREATEREQUAL; filter->attribute = attr; filter->value = filter_parseValue(filterString, pos); return filter; } else { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); *pos += 1; filter->operand = GREATER; filter->attribute = attr; filter->value = filter_parseValue(filterString, pos); return filter; } break; } case '<': { if (filterString[*pos + 1] == '=') { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); *pos += 2; filter->operand = LESSEQUAL; filter->attribute = attr; filter->value = filter_parseValue(filterString, pos); return filter; } else { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); *pos += 1; filter->operand = LESS; filter->attribute = attr; filter->value = filter_parseValue(filterString, pos); return filter; } break; } case '=': { filter_pt filter = NULL; array_list_pt subs; if (filterString[*pos + 1] == '*') { int oldPos = *pos; *pos += 2; filter_skipWhiteSpace(filterString, pos); if (filterString[*pos] == ')') { filter_pt filter = (filter_pt) malloc(sizeof(*filter)); filter->operand = PRESENT; filter->attribute = attr; filter->value = NULL; return filter; } *pos = oldPos; } filter = (filter_pt) malloc(sizeof(*filter)); (*pos)++; subs = filter_parseSubstring(filterString, pos); if(subs!=NULL){ if (arrayList_size(subs) == 1) { char * string = (char *) arrayList_get(subs, 0); if (string != NULL) { filter->operand = EQUAL; filter->attribute = attr; filter->value = string; arrayList_clear(subs); arrayList_destroy(subs); return filter; } } } filter->operand = SUBSTRING; filter->attribute = attr; filter->value = subs; return filter; } } fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Invalid operator."); free(attr); return NULL; }