in src/cbs.c [504:648]
ASYNC_OPERATION_HANDLE cbs_put_token_async(CBS_HANDLE cbs, const char* type, const char* audience, const char* token, ON_CBS_OPERATION_COMPLETE on_cbs_put_token_complete, void* on_cbs_put_token_complete_context)
{
ASYNC_OPERATION_HANDLE result;
/* Codes_SRS_CBS_01_083: [ `on_cbs_put_token_complete_context` shall be allowed to be NULL. ]*/
if ((cbs == NULL) ||
(type == NULL) ||
(audience == NULL) ||
(token == NULL) ||
(on_cbs_put_token_complete == NULL))
{
/* Codes_SRS_CBS_01_050: [ If any of the arguments `cbs`, `type`, `audience`, `token` or `on_cbs_put_token_complete` is NULL `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Bad arguments: cbs = %p, type = %p, audience = %p, token = %p, on_cbs_put_token_complete = %p",
cbs, type, audience, token, on_cbs_put_token_complete);
result = NULL;
}
else if ((cbs->cbs_state == CBS_STATE_CLOSED) ||
(cbs->cbs_state == CBS_STATE_ERROR))
{
/* Codes_SRS_CBS_01_058: [ If `cbs_put_token_async` is called when the CBS instance is not yet open or in error, it shall fail and return `NULL`. ]*/
LogError("put token called while closed or in error");
result = NULL;
}
else
{
/* Codes_SRS_CBS_01_049: [ `cbs_put_token_async` shall construct a request message for the `put-token` operation. ]*/
MESSAGE_HANDLE message = message_create();
if (message == NULL)
{
/* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("message_create failed");
result = NULL;
}
else
{
AMQP_VALUE token_value = amqpvalue_create_string(token);
if (token_value == NULL)
{
/* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Failed creating token AMQP value");
result = NULL;
}
else
{
/* Codes_SRS_CBS_01_009: [ The body of the message MUST contain the token. ]*/
if (message_set_body_amqp_value(message, token_value) != 0)
{
/* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Failed setting the token in the message body");
result = NULL;
}
else
{
AMQP_VALUE application_properties = amqpvalue_create_map();
if (application_properties == NULL)
{
/* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Failed creating application properties map");
result = NULL;
}
else
{
if (add_string_key_value_pair_to_map(application_properties, "name", audience) != 0)
{
result = NULL;
}
else
{
if (message_set_application_properties(message, application_properties) != 0)
{
/* Codes_SRS_CBS_01_072: [ If constructing the message fails, `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Failed setting message application properties");
result = NULL;
}
else
{
result = CREATE_ASYNC_OPERATION(CBS_OPERATION, cbs_put_token_cancel_handler);
if (result == NULL)
{
LogError("Failed allocating async operation context");
}
else
{
CBS_OPERATION* cbs_operation = GET_ASYNC_OPERATION_CONTEXT(CBS_OPERATION, result);
LIST_ITEM_HANDLE list_item;
cbs_operation->on_cbs_operation_complete = on_cbs_put_token_complete;
cbs_operation->on_cbs_operation_complete_context = on_cbs_put_token_complete_context;
cbs_operation->pending_operations = cbs->pending_operations;
cbs_operation->token_operation_async_context = result;
list_item = singlylinkedlist_add(cbs->pending_operations, cbs_operation);
if (list_item == NULL)
{
LogError("Failed adding pending operation to list");
async_operation_destroy(result);
result = NULL;
}
else
{
/* Codes_SRS_CBS_01_051: [ `cbs_put_token_async` shall start the AMQP management operation by calling `amqp_management_execute_operation_async`, while passing to it: ]*/
/* Codes_SRS_CBS_01_052: [ The `amqp_management` argument shall be the one for the AMQP management instance created in `cbs_create`. ]*/
/* Codes_SRS_CBS_01_053: [ The `operation` argument shall be `put-token`. ]*/
/* Codes_SRS_CBS_01_054: [ The `type` argument shall be set to the `type` argument. ]*/
/* Codes_SRS_CBS_01_055: [ The `locales` argument shall be set to NULL. ]*/
/* Codes_SRS_CBS_01_056: [ The `message` argument shall be the message constructed earlier according to the CBS spec. ]*/
/* Codes_SRS_CBS_01_057: [ The arguments `on_execute_operation_complete` and `context` shall be set to a callback that is to be called by the AMQP management module when the operation is complete. ]*/
/* Codes_SRS_CBS_01_005: [ operation No string "put-token" ]*/
/* Codes_SRS_CBS_01_006: [ Type No string The type of the token being put, e.g., "amqp:jwt". ]*/
/* Codes_SRS_CBS_01_007: [ name No string The "audience" to which the token applies. ]*/
cbs_operation->amqp_management_async_context = amqp_management_execute_operation_async(cbs->amqp_management, "put-token", type, NULL, message, on_amqp_management_execute_operation_complete, list_item);
if (cbs_operation->amqp_management_async_context == NULL)
{
singlylinkedlist_remove(cbs->pending_operations, list_item);
/* Codes_SRS_CBS_01_084: [ If `amqp_management_execute_operation_async` fails `cbs_put_token_async` shall fail and return a non-zero value. ]*/
LogError("Failed starting AMQP management operation");
async_operation_destroy(result);
result = NULL;
}
else
{
/* Codes_SRS_CBS_01_081: [ On success `cbs_put_token_async` shall return an ASYNC_OPERATION_HANDLE. ]*/
}
}
}
}
}
amqpvalue_destroy(application_properties);
}
amqpvalue_destroy(token_value);
}
}
message_destroy(message);
}
}
return result;
}