/** * \brief This function tries to load tag group data from MongoDB */ static void vs_mongo_taggroup_load_data(struct VSTagGroup *tg, bson *bson_version) { bson_iterator version_data_iter; /* Try to get tags of tag group */ if( bson_find(&version_data_iter, bson_version, "tags") == BSON_OBJECT ) { struct VSTag *tag; bson bson_tag; bson_iterator tags_iter, tag_iter; const char *key; int tag_id, data_type = -1, count = -1, tag_custom_type = -1; bson_iterator_subiterator(&version_data_iter, &tags_iter); while( bson_iterator_next(&tags_iter) == BSON_OBJECT ) { key = bson_iterator_key(&tags_iter); sscanf(key, "%d", &tag_id); bson_iterator_subobject_init(&tags_iter, &bson_tag, 0); if( bson_find(&tag_iter, &bson_tag, "data_type") == BSON_INT) { data_type = bson_iterator_int(&tag_iter); } if( bson_find(&tag_iter, &bson_tag, "count") == BSON_INT) { count = bson_iterator_int(&tag_iter); } if( bson_find(&tag_iter, &bson_tag, "custom_type") == BSON_INT) { tag_custom_type = bson_iterator_int(&tag_iter); } if(data_type != -1 && count != -1 && tag_custom_type != -1) { /* Create tag with specific ID */ tag = vs_tag_create(tg, tag_id, data_type, count, tag_custom_type); if(tag != NULL) { tag->state = ENTITY_CREATED; vs_mongo_tag_load_data(tag, &bson_tag); tag->flag = TAG_INITIALIZED; } } } } }
/** * \brief This function tries to handle Tag_Create command */ int vs_handle_tag_create(struct VS_CTX *vs_ctx, struct VSession *vsession, struct Generic_Cmd *tag_create) { struct VSNode *node; struct VSTagGroup *tg; struct VSTag *tag; struct VBucket *vbucket; struct VSEntitySubscriber *tg_subscriber; uint32 node_id = UINT32(tag_create->data[0]); uint16 taggroup_id = UINT16(tag_create->data[UINT32_SIZE]); uint16 tag_id = UINT16(tag_create->data[UINT32_SIZE + UINT16_SIZE]); uint8 data_type = UINT8(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE]); uint8 count = UINT8(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE + UINT8_SIZE]); uint16 type = UINT16(tag_create->data[UINT32_SIZE + UINT16_SIZE + UINT16_SIZE + UINT8_SIZE + UINT8_SIZE]); int ret = 0; /* Try to find node */ if((node = vs_node_find(vs_ctx, node_id)) == NULL) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) not found\n", __FUNCTION__, node_id); return 0; } pthread_mutex_lock(&node->mutex); /* Node has to be created */ if(vs_node_is_created(node) != 1) { goto end; } /* User has to have permission to write to the node */ if(vs_node_can_write(vsession, node) != 1) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to node: %d\n", __FUNCTION__, ((struct VSUser *)vsession->user)->username, node->id); goto end; } /* Try to find TagGroup */ if( (tg = vs_taggroup_find(node, taggroup_id)) == NULL) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_group (id: %d) in node (id: %d) not found\n", __FUNCTION__, taggroup_id, node_id); goto end; } /* Tag Group has to be created too (it can't be in DELETING or DELETED state ) */ if(!(tg->state == ENTITY_CREATED || tg->state == ENTITY_CREATING)) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag group (id: %d) from node (id: %d) is not in CREATING or CREATED state: %d\n", __FUNCTION__, tg->id, node->id, tg->state); goto end; } /* Client has to send tag_create command with tag_id equal to * the value 0xFFFF */ if(tag_id != RESERVED_TAG_ID) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_id: %d is not 0xFFFF\n", __FUNCTION__, tag_id); goto end; } /* Is type of Tag supported? */ if(!(data_type>VRS_VALUE_TYPE_RESERVED && data_type<=VRS_VALUE_TYPE_STRING8)) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag_type: %d is not supported\n", __FUNCTION__, data_type); goto end; } vbucket = tg->tags.lb.first; /* Check, if there isn't tag with the same type */ while(vbucket != NULL) { tag = vbucket->data; if(tag->custom_type == type) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() tag type: %d is already used in taggroup: %d\n", __FUNCTION__, type, tg->id); goto end; } vbucket = vbucket->next; } if (v_hash_array_count_items(&tg->tags) > MAX_TAGS_COUNT) { v_print_log(VRS_PRINT_DEBUG_MSG, "%s() max number of tags in node: %d tag_group: %d was reached\n", tg->id); goto end; } /* Try to create new tag */ tag = vs_tag_create(tg, RESERVED_TAG_ID, data_type, count, type); if(tag == NULL) { goto end; } ret = 1; tag->state = ENTITY_CREATING; /* Send TagCreate to all subscribers of tag group */ tg_subscriber = tg->tg_subs.first; while(tg_subscriber != NULL) { if(vs_tag_send_create(tg_subscriber, node, tg, tag) != 1) { ret = 0; } tg_subscriber = tg_subscriber->next; } end: pthread_mutex_unlock(&node->mutex); return ret; }