AMQP_MANAGEMENT_HANDLE amqp_management_create()

in src/amqp_management.c [745:946]


AMQP_MANAGEMENT_HANDLE amqp_management_create(SESSION_HANDLE session, const char* management_node)
{
    AMQP_MANAGEMENT_INSTANCE* amqp_management;

    if ((session == NULL) ||
        (management_node == NULL))
    {
        /* Codes_SRS_AMQP_MANAGEMENT_01_002: [ If `session` or `management_node` is NULL then `amqp_management_create` shall fail and return NULL. ]*/
        LogError("Bad arguments: session = %p, management_node = %p", session, management_node);
        amqp_management = NULL;
    }
    else if (strlen(management_node) == 0)
    {
        /* Codes_SRS_AMQP_MANAGEMENT_01_030: [ If `management_node` is an empty string, then `amqp_management_create` shall fail and return NULL. ]*/
        LogError("Empty string management node");
        amqp_management = NULL;
    }
    else
    {
        /* Codes_SRS_AMQP_MANAGEMENT_01_001: [ `amqp_management_create` shall create a new CBS instance and on success return a non-NULL handle to it. ]*/
        amqp_management = (AMQP_MANAGEMENT_INSTANCE*)calloc(1, sizeof(AMQP_MANAGEMENT_INSTANCE));
        if (amqp_management == NULL)
        {
            /* Codes_SRS_AMQP_MANAGEMENT_01_005: [ If allocating memory for the new handle fails, `amqp_management_create` shall fail and return NULL. ]*/
            LogError("Cannot allocate memory for AMQP management handle");
        }
        else
        {
            amqp_management->sender_connected = 0;
            amqp_management->receiver_connected = 0;
            amqp_management->on_amqp_management_open_complete = NULL;
            amqp_management->on_amqp_management_open_complete_context = NULL;
            amqp_management->on_amqp_management_error = NULL;
            amqp_management->on_amqp_management_error_context = NULL;
            amqp_management->amqp_management_state = AMQP_MANAGEMENT_STATE_IDLE;
            amqp_management->status_code_key_name = NULL;
            amqp_management->status_description_key_name = NULL;

            /* Codes_SRS_AMQP_MANAGEMENT_01_003: [ `amqp_management_create` shall create a singly linked list for pending operations by calling `singlylinkedlist_create`. ]*/
            amqp_management->pending_operations = singlylinkedlist_create();
            if (amqp_management->pending_operations == NULL)
            {
                /* Codes_SRS_AMQP_MANAGEMENT_01_004: [ If `singlylinkedlist_create` fails, `amqp_management_create` shall fail and return NULL. ]*/
                LogError("Cannot create pending operations list");
            }
            else
            {
                /* Codes_SRS_AMQP_MANAGEMENT_01_181: [ `amqp_management_create` shall set the status code key name to be used for parsing the status code to `statusCode`. ]*/
                if (internal_set_status_code_key_name(amqp_management, "statusCode") != 0)
                {
                    LogError("Cannot set status code key name");
                }
                else
                {
                    /* Codes_SRS_AMQP_MANAGEMENT_01_182: [ `amqp_management_create` shall set the status description key name to be used for parsing the status description to `statusDescription`. ]*/
                    if (internal_set_status_description_key_name(amqp_management, "statusDescription") != 0)
                    {
                        LogError("Cannot set status description key name");
                    }
                    else
                    {
                        /* Codes_SRS_AMQP_MANAGEMENT_01_010: [ The `source` argument shall be a value created by calling `messaging_create_source` with `management_node` as argument. ]*/
                        AMQP_VALUE source = messaging_create_source(management_node);
                        if (source == NULL)
                        {
                            /* Codes_SRS_AMQP_MANAGEMENT_01_012: [ If `messaging_create_source` fails then `amqp_management_create` shall fail and return NULL. ]*/
                            LogError("Failed creating source AMQP value");
                        }
                        else
                        {
                            /* Codes_SRS_AMQP_MANAGEMENT_01_011: [ The `target` argument shall be a value created by calling `messaging_create_target` with `management_node` as argument. ]*/
                            AMQP_VALUE target = messaging_create_target(management_node);
                            if (target == NULL)
                            {
                                /* Codes_SRS_AMQP_MANAGEMENT_01_013: [ If `messaging_create_target` fails then `amqp_management_create` shall fail and return NULL. ]*/
                                LogError("Failed creating target AMQP value");
                            }
                            else
                            {
                                size_t management_node_length = strlen(management_node);

                                char* sender_link_name = (char*)malloc(management_node_length + COUNT_CHARS(sender_suffix) + 1);
                                if (sender_link_name == NULL)
                                {
                                    /* Codes_SRS_AMQP_MANAGEMENT_01_033: [ If any other error occurs `amqp_management_create` shall fail and return NULL. ]*/
                                    LogError("Failed allocating memory for sender link name");
                                }
                                else
                                {
                                    char* receiver_link_name;

                                    (void)memcpy(sender_link_name, management_node, management_node_length);
                                    (void)memcpy(sender_link_name + management_node_length, sender_suffix, COUNT_CHARS(sender_suffix) + 1);

                                    receiver_link_name = (char*)malloc(management_node_length + COUNT_CHARS(receiver_suffix) + 1);
                                    if (receiver_link_name == NULL)
                                    {
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_033: [ If any other error occurs `amqp_management_create` shall fail and return NULL. ]*/
                                        LogError("Failed allocating memory for receiver link name");
                                    }
                                    else
                                    {
                                        (void)memcpy(receiver_link_name, management_node, management_node_length);
                                        (void)memcpy(receiver_link_name + management_node_length, receiver_suffix, COUNT_CHARS(receiver_suffix) + 1);

                                        /* Codes_SRS_AMQP_MANAGEMENT_01_006: [ `amqp_management_create` shall create a sender link by calling `link_create`. ]*/
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_007: [ The `session` argument shall be set to `session`. ]*/
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_008: [ The `name` argument shall be constructed by concatenating the `management_node` value with `-sender`. ]*/
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_009: [ The `role` argument shall be `role_sender`. ]*/
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_019: [ The `source` argument shall be the value created by calling `messaging_create_source`. ]*/
                                        /* Codes_SRS_AMQP_MANAGEMENT_01_020: [ The `target` argument shall be the value created by calling `messaging_create_target`. ]*/
                                        amqp_management->sender_link = link_create(session, sender_link_name, role_sender, source, target);
                                        if (amqp_management->sender_link == NULL)
                                        {
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_014: [ If `link_create` fails when creating the sender link then `amqp_management_create` shall fail and return NULL. ]*/
                                            LogError("Failed creating sender link");
                                        }
                                        else
                                        {
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_015: [ `amqp_management_create` shall create a receiver link by calling `link_create`. ]*/
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_016: [ The `session` argument shall be set to `session`. ]*/
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_017: [ The `name` argument shall be constructed by concatenating the `management_node` value with `-receiver`. ]*/
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_018: [ The `role` argument shall be `role_receiver`. ]*/
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_019: [ The `source` argument shall be the value created by calling `messaging_create_source`. ]*/
                                            /* Codes_SRS_AMQP_MANAGEMENT_01_020: [ The `target` argument shall be the value created by calling `messaging_create_target`. ]*/
                                            amqp_management->receiver_link = link_create(session, receiver_link_name, role_receiver, source, target);
                                            if (amqp_management->receiver_link == NULL)
                                            {
                                                /* Codes_SRS_AMQP_MANAGEMENT_01_021: [ If `link_create` fails when creating the receiver link then `amqp_management_create` shall fail and return NULL. ]*/
                                                LogError("Failed creating receiver link");
                                            }
                                            else
                                            {
                                                /* Codes_SRS_AMQP_MANAGEMENT_01_022: [ `amqp_management_create` shall create a message sender by calling `messagesender_create` and passing to it the sender link handle. ]*/
                                                amqp_management->message_sender = messagesender_create(amqp_management->sender_link, on_message_sender_state_changed, amqp_management);
                                                if (amqp_management->message_sender == NULL)
                                                {
                                                    /* Codes_SRS_AMQP_MANAGEMENT_01_031: [ If `messagesender_create` fails then `amqp_management_create` shall fail and return NULL. ]*/
                                                    LogError("Failed creating message sender");
                                                }
                                                else
                                                {
                                                    /* Codes_SRS_AMQP_MANAGEMENT_01_023: [ `amqp_management_create` shall create a message receiver by calling `messagereceiver_create` and passing to it the receiver link handle. ]*/
                                                    amqp_management->message_receiver = messagereceiver_create(amqp_management->receiver_link, on_message_receiver_state_changed, amqp_management);
                                                    if (amqp_management->message_receiver == NULL)
                                                    {
                                                        /* Codes_SRS_AMQP_MANAGEMENT_01_032: [ If `messagereceiver_create` fails then `amqp_management_create` shall fail and return NULL. ]*/
                                                        LogError("Failed creating message receiver");
                                                        link_destroy(amqp_management->receiver_link);
                                                    }
                                                    else
                                                    {
                                                        free(receiver_link_name);
                                                        free(sender_link_name);
                                                        amqpvalue_destroy(target);
                                                        amqpvalue_destroy(source);

                                                        /* Codes_SRS_AMQP_MANAGEMENT_01_106: [ The message Id set on the message properties shall start at 0. ]*/
                                                        amqp_management->next_message_id = 0;

                                                        goto all_ok;
                                                    }

                                                    messagesender_destroy(amqp_management->message_sender);
                                                }

                                                link_destroy(amqp_management->receiver_link);
                                            }

                                            link_destroy(amqp_management->sender_link);
                                        }

                                        free(receiver_link_name);
                                    }

                                    free(sender_link_name);
                                }

                                amqpvalue_destroy(target);
                            }

                            amqpvalue_destroy(source);
                        }

                        free(amqp_management->status_description_key_name);
                    }

                    free(amqp_management->status_code_key_name);
                }

                singlylinkedlist_destroy(amqp_management->pending_operations);
            }

            free(amqp_management);
            amqp_management = NULL;
        }
    }

all_ok:
    /* Codes_SRS_AMQP_MANAGEMENT_01_056: [ On success it shall return an ASYNC_OPERATION_HANDLE. ] */
    return amqp_management;
}