Пример #1
0
/**
 * \brief This function create new tag group
 */
struct VSTagGroup *vs_taggroup_create(struct VSNode *node,
		uint16 tg_id,
		uint16 custom_type)
{
	struct VSTagGroup *tg = NULL;
	struct VBucket *tg_bucket;

	if ( !(v_hash_array_count_items(&node->tag_groups) < MAX_TAGGROUPS_COUNT) ) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"Maximal number of tag groups in node: %d reached.\n",
				node->id);
		return NULL;
	}

	/* Try to create new tag group */
	tg = (struct VSTagGroup*)calloc(1, sizeof(VSTagGroup));
	if(tg == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Out of memory.\n");
		return NULL;
	}

	/* Initialize new tag group */
	vs_taggroup_init(tg);

	if(tg_id == VRS_RESERVED_TAGGROUP_ID) {
		/* Try to find first free taggroup_id */
		tg->id = node->last_tg_id;
		while( v_hash_array_find_item(&node->tag_groups, tg) != NULL) {
			/* When not found, then try higher value */
			tg->id++;

			/* Skip IDs with special purpose */
			if(tg->id > LAST_TAGGROUP_ID) {
				tg->id = FIRST_TAGGROUP_ID;
			}
		}
	} else {
		tg->id = tg_id;
	}
	node->last_tg_id = tg->id;

	/* Try to add TagGroup to the hashed linked list */
	tg_bucket = v_hash_array_add_item(&node->tag_groups, tg, sizeof(struct VSTagGroup));

	if(tg_bucket == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"Tag group could not be added to node: %d.\n",
				node->id);
		free(tg);
		return NULL;
	}

	/* Copy type */
	tg->custom_type = custom_type;

	vs_node_inc_version(node);

	return tg;
}
Пример #2
0
/**
 * \brief This function creates new VSNode at Verse server
 */
struct VSNode *vs_node_create(struct VS_CTX *vs_ctx,
		struct VSNode *parent_node,
		struct VSUser *owner,
		uint32 node_id,
		uint16 custom_type)
{
	struct VSNode *node;
	struct VSLink *link;
	struct VBucket *bucket;

	if(! (v_hash_array_count_items(&vs_ctx->data.nodes) < VRS_MAX_COMMON_NODE_COUNT) ) {
		v_print_log(VRS_PRINT_DEBUG_MSG,
				"max number: %d of nodes reached\n",
				VRS_MAX_COMMON_NODE_COUNT);
		return NULL;
	}

	node = (struct VSNode*)calloc(1, sizeof(struct VSNode));
	if(node == NULL) {
		v_print_log(VRS_PRINT_ERROR, "Out of memory\n");
		return NULL;
	}

	vs_node_init(node);

	if(node_id == VRS_RESERVED_NODE_ID) {
		/* Try to find first free node_id. It is fast and easy, When
		 * VRS_LAST_COMMON_NODE_ID did not reach 0xFFFFFFFF-1 value yet and not used
		 * node_id are not reused.*/
		node->id = vs_ctx->data.last_common_node_id + 1;
		while( v_hash_array_find_item(&vs_ctx->data.nodes, &node) != NULL) {
			node->id++;
			/* Node id 0xFFFFFFFF has special purpose and node IDs in range <0, 65535>
			 * have special purposes too (skip them) */
			if(node->id > VRS_LAST_COMMON_NODE_ID)
				node->id = VRS_FIRST_COMMON_NODE_ID;
			/* TODO: implement faster finding of free node id */
		}
		vs_ctx->data.last_common_node_id = node->id;
	} else {
		node->id = node_id;
	}

	/* Create link to the parent node */
	if(parent_node != NULL) {
		link = vs_link_create(parent_node, node);
		if(link == NULL) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "link between nodes %d %d could not be created\n",
					parent_node->id, node->id);
			free(node);
			return NULL;
		}
	} else {
		/* This can happen only for root node */
		assert(node_id == VRS_ROOT_NODE_ID);
		node->parent_link = NULL;
		node->level = 0;
	}

	/* Add node to the hashed array of all verse nodes */
	bucket = v_hash_array_add_item(&vs_ctx->data.nodes, node, sizeof(struct VSNode));
	if(bucket == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "node %d could not be added to the hashed list of nodes\n",
				node->id);
		if(node->parent_link != NULL) {
			v_list_free_item(&parent_node->children_links, node->parent_link);
		}
		free(node);
		return NULL;
	}

	node->owner = owner;
	node->type = custom_type;

	return node;
}
Пример #3
0
/**
 * \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;
}
Пример #4
0
/**
 * \brief This function is called, when server receives command layer_create
 *
 * \param[in]	*vs_ctx				The pointer at verse server context
 * \param[in]	*vsession			The pointer at session of client that sent this command
 * \param[in]	*layer_create_cmd	The pointer at received command
 *
 * \return This function returns 0, when parameters of received command are
 * wrong. When all parameters are right, then it returns 1.
 */
int vs_handle_layer_create(struct VS_CTX *vs_ctx,
		struct VSession *vsession,
		struct Generic_Cmd *layer_create_cmd)
{
	struct VSNode *node;
	struct VSUser *user;
	struct VSLayer *parent_layer;
	struct VSLayer *layer;
	struct VBucket *vbucket;
	struct VSNodeSubscriber *node_subscriber;

	uint32 node_id = UINT32(layer_create_cmd->data[0]);
	uint16 parent_layer_id = UINT16(layer_create_cmd->data[UINT32_SIZE]);
	uint16 layer_id = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE]);
	uint8 data_type = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE]);
	uint8 count = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE+UINT8_SIZE]);
	uint16 type = UINT16(layer_create_cmd->data[UINT32_SIZE+UINT16_SIZE+UINT16_SIZE+UINT8_SIZE+UINT8_SIZE]);

	/* 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;
	}

	/* When parent layer id is not -1, then try to find this parent layer */
	if(parent_layer_id == RESERVED_LAYER_ID) {
		parent_layer = NULL;
	} else {
		parent_layer = vs_layer_find(node, parent_layer_id);
		if(parent_layer == NULL) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "%s() parent layer (id: %d) in node (id: %d) not found\n",
					__FUNCTION__, parent_layer_id, node_id);
			return 0;
		}
	}

	/* Node has to be created */
	if(!(node->state == ENTITY_CREATED || node->state == ENTITY_CREATING)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() node (id: %d) is not in CREATING or CREATED state: %d\n",
				__FUNCTION__, node->id, node->state);
		return 0;
	}

	/* Try to find user */
	if((user = vs_user_find(vs_ctx, vsession->user_id)) == NULL) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() vsession->user_id: %d not found\n",
				__FUNCTION__, vsession->user_id);
		return 0;
	}

	/* User has to have permission to write to the node */
	if(vs_node_can_write(vs_ctx, vsession, node) != 1) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s(): user: %s can't write to node: %d\n",
				__FUNCTION__, user->username, node->id);
		return 0;
	}

	/* Client has to send layer_create command with layer_id equal to
	 * the value 0xFFFF */
	if(layer_id != RESERVED_LAYER_ID) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer_id: %d is not 0xFFFF\n",
				__FUNCTION__, layer_id);
		return 0;
	}

	/* Is type of Layer supported? */
	if(!(data_type>VRS_VALUE_TYPE_RESERVED && data_type<=VRS_VALUE_TYPE_REAL64)) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() data_type: %d is not supported\n",
				__FUNCTION__, data_type);
		return 0;
	}

	vbucket = node->layers.lb.first;
	/* Check, if there isn't tag with the same type */
	while(vbucket != NULL) {
		layer = vbucket->data;
		if(layer->type == type) {
			v_print_log(VRS_PRINT_DEBUG_MSG, "%s() layer type: %d is already used in layer: %d\n",
					__FUNCTION__, type, layer->id);
			return 0;
		}
		vbucket = vbucket->next;
	}

	if (v_hash_array_count_items(&node->layers) > MAX_LAYERS_COUNT) {
		v_print_log(VRS_PRINT_DEBUG_MSG, "%s() max number of layers in node: %d was reached\n",
				node->id);
		return 0;
	}

	layer = vs_layer_create(node, parent_layer, data_type, count, type);

	/* Try to find first free id for layer */
	/* TODO: this could be more effective */
	layer->id = node->last_layer_id;
	while( v_hash_array_find_item(&node->layers, layer) != NULL ) {
		layer->id++;

		if(layer->id > LAST_LAYER_ID) {
			layer->id = FIRST_LAYER_ID;
		}
	}
	node->last_layer_id = layer->id;

	/* Try to add new Tag to the hashed linked list of tags */
	vbucket = v_hash_array_add_item(&node->layers, (void*)layer, sizeof(struct VSLayer));

	if(vbucket==NULL) {
		free(layer);
		return 0;
	}

	layer->state = ENTITY_CREATING;

	/* Send layer_create to all node subscribers */
	node_subscriber = node->node_subs.first;
	while(node_subscriber != NULL) {
		vs_layer_send_create(node_subscriber, node, layer);
		node_subscriber = node_subscriber->next;
	}

	return 0;
}