static AMQP_VALUE on_message_received(const void* context, MESSAGE_HANDLE message) { AMQP_MANAGEMENT_INSTANCE* amqp_management_instance = (AMQP_MANAGEMENT_INSTANCE*)context; AMQP_VALUE application_properties; if (message_get_application_properties(message, &application_properties) != 0) { /* error */ } else { PROPERTIES_HANDLE response_properties; if (message_get_properties(message, &response_properties) != 0) { /* error */ } else { AMQP_VALUE key; AMQP_VALUE value; AMQP_VALUE map; AMQP_VALUE correlation_id_value; if (properties_get_correlation_id(response_properties, &correlation_id_value) != 0) { /* error */ } else { map = amqpvalue_get_inplace_described_value(application_properties); if (map == NULL) { /* error */ } else { key = amqpvalue_create_string("status-code"); if (key == NULL) { /* error */ } else { value = amqpvalue_get_map_value(map, key); if (value == NULL) { /* error */ } else { int32_t status_code; if (amqpvalue_get_int(value, &status_code) != 0) { /* error */ } else { size_t i = 0; while (i < amqp_management_instance->operation_message_count) { if (amqp_management_instance->operation_messages[i]->operation_state == OPERATION_STATE_AWAIT_REPLY) { AMQP_VALUE expected_message_id = amqpvalue_create_ulong(amqp_management_instance->operation_messages[i]->message_id); OPERATION_RESULT operation_result; if (expected_message_id == NULL) { break; } else { if (amqpvalue_are_equal(correlation_id_value, expected_message_id)) { /* 202 is not mentioned in the draft in any way, this is a workaround for an EH bug for now */ if ((status_code != 200) && (status_code != 202)) { operation_result = OPERATION_RESULT_OPERATION_FAILED; } else { operation_result = OPERATION_RESULT_OK; } amqp_management_instance->operation_messages[i]->on_operation_complete(amqp_management_instance->operation_messages[i]->callback_context, operation_result, 0, NULL); remove_operation_message_by_index(amqp_management_instance, i); amqpvalue_destroy(expected_message_id); break; } amqpvalue_destroy(expected_message_id); } } } } amqpvalue_destroy(value); } amqpvalue_destroy(key); } } } properties_destroy(response_properties); } application_properties_destroy(application_properties); } return messaging_delivery_accepted(); }
static SEND_ONE_MESSAGE_RESULT send_one_message(MESSAGE_SENDER_INSTANCE* message_sender_instance, MESSAGE_WITH_CALLBACK* message_with_callback, MESSAGE_HANDLE message) { SEND_ONE_MESSAGE_RESULT result; size_t encoded_size; size_t total_encoded_size = 0; MESSAGE_BODY_TYPE message_body_type; message_format message_format; if ((message_get_body_type(message, &message_body_type) != 0) || (message_get_message_format(message, &message_format) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { // header HEADER_HANDLE header; AMQP_VALUE header_amqp_value; PROPERTIES_HANDLE properties; AMQP_VALUE properties_amqp_value; AMQP_VALUE application_properties; AMQP_VALUE application_properties_value; AMQP_VALUE body_amqp_value = NULL; size_t body_data_count; message_get_header(message, &header); header_amqp_value = amqpvalue_create_header(header); if (header != NULL) { amqpvalue_get_encoded_size(header_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // properties message_get_properties(message, &properties); properties_amqp_value = amqpvalue_create_properties(properties); if (properties != NULL) { amqpvalue_get_encoded_size(properties_amqp_value, &encoded_size); total_encoded_size += encoded_size; } // application properties message_get_application_properties(message, &application_properties); application_properties_value = amqpvalue_create_application_properties(application_properties); if (application_properties != NULL) { amqpvalue_get_encoded_size(application_properties_value, &encoded_size); total_encoded_size += encoded_size; } result = SEND_ONE_MESSAGE_OK; // body - amqp data switch (message_body_type) { default: result = SEND_ONE_MESSAGE_ERROR; break; case MESSAGE_BODY_TYPE_VALUE: { AMQP_VALUE message_body_amqp_value; if (message_get_inplace_body_amqp_value(message, &message_body_amqp_value) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { body_amqp_value = amqpvalue_create_amqp_value(message_body_amqp_value); if ((body_amqp_value == NULL) || (amqpvalue_get_encoded_size(body_amqp_value, &encoded_size) != 0)) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } } break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; if (message_get_body_amqp_data_count(message, &body_data_count) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_get_encoded_size(body_amqp_data, &encoded_size) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { total_encoded_size += encoded_size; } amqpvalue_destroy(body_amqp_data); } } } } break; } } if (result == 0) { void* data_bytes = amqpalloc_malloc(total_encoded_size); PAYLOAD payload = { data_bytes, 0 }; result = SEND_ONE_MESSAGE_OK; if (header != NULL) { if (amqpvalue_encode(header_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Header:", header_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (properties != NULL)) { if (amqpvalue_encode(properties_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Properties:", properties_amqp_value); } if ((result == SEND_ONE_MESSAGE_OK) && (application_properties != NULL)) { if (amqpvalue_encode(application_properties_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Application properties:", application_properties_value); } if (result == SEND_ONE_MESSAGE_OK) { switch (message_body_type) { case MESSAGE_BODY_TYPE_VALUE: { if (amqpvalue_encode(body_amqp_value, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; } log_message_chunk(message_sender_instance, "Body - amqp value:", body_amqp_value); break; } case MESSAGE_BODY_TYPE_DATA: { BINARY_DATA binary_data; size_t i; for (i = 0; i < body_data_count; i++) { if (message_get_body_amqp_data(message, i, &binary_data) != 0) { result = SEND_ONE_MESSAGE_ERROR; } else { amqp_binary binary_value = { binary_data.bytes, binary_data.length }; AMQP_VALUE body_amqp_data = amqpvalue_create_data(binary_value); if (body_amqp_data == NULL) { result = SEND_ONE_MESSAGE_ERROR; } else { if (amqpvalue_encode(body_amqp_data, encode_bytes, &payload) != 0) { result = SEND_ONE_MESSAGE_ERROR; break; } amqpvalue_destroy(body_amqp_data); } } } break; } } } if (result == SEND_ONE_MESSAGE_OK) { message_with_callback->message_send_state = MESSAGE_SEND_STATE_PENDING; switch (link_transfer(message_sender_instance->link, message_format, &payload, 1, on_delivery_settled, message_with_callback)) { default: case LINK_TRANSFER_ERROR: if (message_with_callback->on_message_send_complete != NULL) { message_with_callback->on_message_send_complete(message_with_callback->context, MESSAGE_SEND_ERROR); } result = SEND_ONE_MESSAGE_ERROR; break; case LINK_TRANSFER_BUSY: message_with_callback->message_send_state = MESSAGE_SEND_STATE_NOT_SENT; result = SEND_ONE_MESSAGE_BUSY; break; case LINK_TRANSFER_OK: result = SEND_ONE_MESSAGE_OK; break; } } amqpalloc_free(data_bytes); if (body_amqp_value != NULL) { amqpvalue_destroy(body_amqp_value); } amqpvalue_destroy(application_properties); amqpvalue_destroy(application_properties_value); amqpvalue_destroy(properties_amqp_value); properties_destroy(properties); } } return result; }
int amqpmanagement_start_operation(AMQP_MANAGEMENT_HANDLE amqp_management, const char* operation, const char* type, const char* locales, MESSAGE_HANDLE message, ON_OPERATION_COMPLETE on_operation_complete, void* context) { int result; if ((amqp_management == NULL) || (operation == NULL)) { result = __LINE__; } else { AMQP_VALUE application_properties; if (message_get_application_properties(message, &application_properties) != 0) { result = __LINE__; } else { if ((add_string_key_value_pair_to_map(application_properties, "operation", operation) != 0) || (add_string_key_value_pair_to_map(application_properties, "type", type) != 0) || ((locales != NULL) && (add_string_key_value_pair_to_map(application_properties, "locales", locales) != 0))) { result = __LINE__; } else { if ((message_set_application_properties(message, application_properties) != 0) || (set_message_id(message, amqp_management->next_message_id) != 0)) { result = __LINE__; } else { OPERATION_MESSAGE_INSTANCE* pending_operation_message = amqpalloc_malloc(sizeof(OPERATION_MESSAGE_INSTANCE)); if (pending_operation_message == NULL) { result = __LINE__; } else { pending_operation_message->message = message_clone(message); pending_operation_message->callback_context = context; pending_operation_message->on_operation_complete = on_operation_complete; pending_operation_message->operation_state = OPERATION_STATE_NOT_SENT; pending_operation_message->message_id = amqp_management->next_message_id; amqp_management->next_message_id++; OPERATION_MESSAGE_INSTANCE** new_operation_messages = amqpalloc_realloc(amqp_management->operation_messages, (amqp_management->operation_message_count + 1) * sizeof(OPERATION_MESSAGE_INSTANCE*)); if (new_operation_messages == NULL) { message_destroy(message); amqpalloc_free(pending_operation_message); result = __LINE__; } else { amqp_management->operation_messages = new_operation_messages; amqp_management->operation_messages[amqp_management->operation_message_count] = pending_operation_message; amqp_management->operation_message_count++; if (send_operation_messages(amqp_management) != 0) { if (on_operation_complete != NULL) { on_operation_complete(context, OPERATION_RESULT_CBS_ERROR, 0, NULL); } result = __LINE__; } else { result = 0; } } } } } amqpvalue_destroy(application_properties); } } return result; }