void amqp_destroy_envelope(amqp_envelope_t *envelope)
{
  amqp_destroy_message(&envelope->message);
  amqp_bytes_free(envelope->routing_key);
  amqp_bytes_free(envelope->exchange);
  amqp_bytes_free(envelope->consumer_tag);
}
amqp_rpc_reply_t
amqp_consume_message(amqp_connection_state_t state, amqp_envelope_t *envelope,
                     struct timeval *timeout, AMQP_UNUSED int flags)
{
  int res;
  amqp_frame_t frame;
  amqp_basic_deliver_t *delivery_method;
  amqp_rpc_reply_t ret;

  memset(&ret, 0, sizeof(amqp_rpc_reply_t));
  memset(envelope, 0, sizeof(amqp_envelope_t));

  res = amqp_simple_wait_frame_noblock(state, &frame, timeout);
  if (AMQP_STATUS_OK != res) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = res;
    goto error_out1;
  }

  if (AMQP_FRAME_METHOD != frame.frame_type
      || AMQP_BASIC_DELIVER_METHOD != frame.payload.method.id) {
    amqp_put_back_frame(state, &frame);
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;
    goto error_out1;
  }

  delivery_method = frame.payload.method.decoded;

  envelope->channel = frame.channel;
  envelope->consumer_tag = amqp_bytes_malloc_dup(delivery_method->consumer_tag);
  envelope->delivery_tag = delivery_method->delivery_tag;
  envelope->redelivered = delivery_method->redelivered;
  envelope->exchange = amqp_bytes_malloc_dup(delivery_method->exchange);
  envelope->routing_key = amqp_bytes_malloc_dup(delivery_method->routing_key);

  if (amqp_bytes_malloc_dup_failed(envelope->consumer_tag) ||
      amqp_bytes_malloc_dup_failed(envelope->exchange) ||
      amqp_bytes_malloc_dup_failed(envelope->routing_key)) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = AMQP_STATUS_NO_MEMORY;
    goto error_out2;
  }

  ret = amqp_read_message(state, envelope->channel, &envelope->message, 0);
  if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
    goto error_out2;
  }

  ret.reply_type = AMQP_RESPONSE_NORMAL;
  return ret;

error_out2:
  amqp_bytes_free(envelope->routing_key);
  amqp_bytes_free(envelope->exchange);
  amqp_bytes_free(envelope->consumer_tag);
error_out1:
  return ret;
}
Exemple #3
0
static gboolean
afamqp_worker_publish(AMQPDestDriver *self, LogMessage *msg)
{
    gint pos = 0, ret;
    amqp_table_t table;
    amqp_basic_properties_t props;
    gboolean success = TRUE;
    SBGString *routing_key = sb_gstring_acquire();
    SBGString *body = sb_gstring_acquire();
    amqp_bytes_t body_bytes = amqp_cstring_bytes("");

    gpointer user_data[] = { &self->entries, &pos, &self->max_entries };

    value_pairs_foreach(self->vp, afamqp_vp_foreach, msg, self->seq_num,
                        &self->template_options, user_data);

    table.num_entries = pos;
    table.entries = self->entries;

    props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG
                   | AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_HEADERS_FLAG;
    props.content_type = amqp_cstring_bytes("text/plain");
    props.delivery_mode = self->persistent;
    props.headers = table;

    log_template_format(self->routing_key_template, msg, NULL, LTZ_LOCAL,
                        self->seq_num, NULL, sb_gstring_string(routing_key));

    if (self->body_template)
    {
        log_template_format(self->body_template, msg, NULL, LTZ_LOCAL,
                            self->seq_num, NULL, sb_gstring_string(body));
        body_bytes = amqp_cstring_bytes(sb_gstring_string(body)->str);
    }

    ret = amqp_basic_publish(self->conn, 1, amqp_cstring_bytes(self->exchange),
                             amqp_cstring_bytes(sb_gstring_string(routing_key)->str),
                             0, 0, &props, body_bytes);

    sb_gstring_release(routing_key);
    sb_gstring_release(body);

    if (ret < 0)
    {
        msg_error("Network error while inserting into AMQP server",
                  evt_tag_str("driver", self->super.super.super.id),
                  evt_tag_int("time_reopen", self->super.time_reopen), NULL);
        success = FALSE;
    }

    while (--pos >= 0)
    {
        amqp_bytes_free(self->entries[pos].key);
        amqp_bytes_free(self->entries[pos].value.value.bytes);
    }

    return success;
}
void BasicMessage::AppId(const std::string& app_id)
{
	if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id);
	m_impl->m_properties.app_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(app_id.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_APP_ID_FLAG;
}
void BasicMessage::AppIdClear()
{
	if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id);
    m_impl->m_properties._flags &= ~AMQP_BASIC_APP_ID_FLAG;
}
void BasicMessage::CorrelationId(const std::string& correlation_id)
{
	if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id);
	m_impl->m_properties.correlation_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(correlation_id.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_CORRELATION_ID_FLAG;
}
void BasicMessage::UserIdClear()
{
	if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id);
    m_impl->m_properties._flags &= ~AMQP_BASIC_USER_ID_FLAG;
}
Exemple #8
0
int main(int argc, char *argv[])
{
  char const *hostname;
  int port, status;
  char const *exchange;
  char const *routingkey;
  char const *messagebody;
  amqp_socket_t *socket = NULL;
  amqp_connection_state_t conn;
  amqp_bytes_t reply_to_queue;

  if (argc < 6) { /* minimum number of mandatory arguments */
    fprintf(stderr, "usage:\namqp_rpc_sendstring_client host port exchange routingkey messagebody\n");
    return 1;
  }

  hostname = argv[1];
  port = atoi(argv[2]);
  exchange = argv[3];
  routingkey = argv[4];
  messagebody = argv[5];

  /*
     establish a channel that is used to connect RabbitMQ server
  */

  conn = amqp_new_connection();

  socket = amqp_tcp_socket_new(conn);
  if (!socket) {
    printf("creating TCP socket");
  }

  status = amqp_socket_open(socket, hostname, port);
  if (status) {
    printf("opening TCP socket");
  }
    printf("established connection!\n");
  amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest");//                    "Logging in");
  amqp_channel_open(conn, 1);
  amqp_get_rpc_reply(conn);//, "Opening channel");
  printf("open channel!\n");
  /*
     create private reply_to queue
  */

  {
    amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_empty_bytes, 0, 0, 0, 1, amqp_empty_table);
    amqp_get_rpc_reply(conn);//, "Declaring queue");
    printf("declare queue!\n");
    reply_to_queue = amqp_bytes_malloc_dup(r->queue);
    if (reply_to_queue.bytes == NULL) {
      fprintf(stderr, "Out of memory while copying queue name");
      return 1;
    }
  }

  /*
     send the message
  */

  {
    /*
      set properties
    */
    amqp_basic_properties_t props;
    props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |
                   AMQP_BASIC_DELIVERY_MODE_FLAG |
                   AMQP_BASIC_REPLY_TO_FLAG |
                   AMQP_BASIC_CORRELATION_ID_FLAG;
    props.content_type = amqp_cstring_bytes("text/plain");
    props.delivery_mode = 2; /* persistent delivery mode */
    props.reply_to = amqp_bytes_malloc_dup(reply_to_queue);
    if (props.reply_to.bytes == NULL) {
      fprintf(stderr, "Out of memory while copying queue name");
      return 1;
    }
    props.correlation_id = amqp_cstring_bytes("1");

    /*
      publish
    */
    amqp_basic_publish(conn,
                                    1,
                                    amqp_cstring_bytes(exchange),
                                    amqp_cstring_bytes(routingkey),
                                    0,
                                    0,
                                    &props,
                                    amqp_cstring_bytes(messagebody));
    //             "Publishing");

    amqp_bytes_free(props.reply_to);
  }

  /*
    wait an answer
  */
    printf("waiting answer!\n");
  {
    amqp_basic_consume(conn, 1, reply_to_queue, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
    amqp_get_rpc_reply(conn);//, "Consuming");
    amqp_bytes_free(reply_to_queue);

    {
      amqp_frame_t frame;
      int result;

      amqp_basic_deliver_t *d;
      amqp_basic_properties_t *p;
      size_t body_target;
      size_t body_received;

      while (1) {
        amqp_maybe_release_buffers(conn);
        result = amqp_simple_wait_frame(conn, &frame);
        printf("Result: %d\n", result);
        if (result < 0) {
          break;
        }

        printf("Frame type: %d channel: %d\n", frame.frame_type, frame.channel);
        if (frame.frame_type != AMQP_FRAME_METHOD) {
          continue;
        }

        printf("Method: %s\n", amqp_method_name(frame.payload.method.id));
        if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) {
          continue;
        }

        d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
        printf("Delivery: %u exchange: %.*s routingkey: %.*s\n",
               (unsigned) d->delivery_tag,
               (int) d->exchange.len, (char *) d->exchange.bytes,
               (int) d->routing_key.len, (char *) d->routing_key.bytes);

        result = amqp_simple_wait_frame(conn, &frame);
        if (result < 0) {
          break;
        }

        if (frame.frame_type != AMQP_FRAME_HEADER) {
          fprintf(stderr, "Expected header!");
          abort();
        }
        p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
        if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
          printf("Content-type: %.*s\n",
                 (int) p->content_type.len, (char *) p->content_type.bytes);
        }
        printf("----\n");

        body_target = frame.payload.properties.body_size;
        body_received = 0;

        while (body_received < body_target) {
          result = amqp_simple_wait_frame(conn, &frame);
          if (result < 0) {
            break;
          }

          if (frame.frame_type != AMQP_FRAME_BODY) {
            fprintf(stderr, "Expected body!");
            abort();
          }

          body_received += frame.payload.body_fragment.len;
          printf("len -> %d \n",frame.payload.body_fragment.len);
          assert(body_received <= body_target);

          amqp_dump(frame.payload.body_fragment.bytes,
                    frame.payload.body_fragment.len);
        }

        if (body_received != body_target) {
          /* Can only happen when amqp_simple_wait_frame returns <= 0 */
          /* We break here to close the connection */
          break;
        }

        /* everything was fine, we can quit now because we received the reply */
        break;
      }

    }
  }

  /*
     closing
  */

  amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS);//, "Closing channel");
  amqp_connection_close(conn, AMQP_REPLY_SUCCESS);//, "Closing connection");
  amqp_destroy_connection(conn);//, "Ending connection");

  return 0;
}
void BasicMessage::ContentEncoding(const std::string& content_encoding)
{
	if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding);
	m_impl->m_properties.content_encoding = amqp_bytes_malloc_dup(amqp_cstring_bytes(content_encoding.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_CONTENT_ENCODING_FLAG;
}
void BasicMessage::MessageId(const std::string& message_id)
{
	if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id);
	m_impl->m_properties.message_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(message_id.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_MESSAGE_ID_FLAG;
}
BasicMessage::~BasicMessage()
{
	amqp_bytes_free(m_impl->m_body);
	if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type);
	if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding);
	if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id);
	if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to);
	if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration);
	if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id);
	if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type);
	if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id);
	if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.app_id);
	if (ClusterIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id);
}
void BasicMessage::Expiration(const std::string& expiration)
{
	if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration);
	m_impl->m_properties.expiration = amqp_bytes_malloc_dup(amqp_cstring_bytes(expiration.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_EXPIRATION_FLAG;
}
void BasicMessage::ExpirationClear()
{
	if (ExpirationIsSet()) amqp_bytes_free(m_impl->m_properties.expiration);
    m_impl->m_properties._flags &= ~AMQP_BASIC_EXPIRATION_FLAG;
}
void BasicMessage::ReplyToClear()
{
	if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to);
    m_impl->m_properties._flags &= ~AMQP_BASIC_REPLY_TO_FLAG;
}
void BasicMessage::ReplyTo(const std::string& reply_to)
{
	if (ReplyToIsSet()) amqp_bytes_free(m_impl->m_properties.reply_to);
	m_impl->m_properties.reply_to = amqp_bytes_malloc_dup(amqp_cstring_bytes(reply_to.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_REPLY_TO_FLAG;
}
void BasicMessage::CorrelationIdClear()
{
	if (CorrelationIdIsSet()) amqp_bytes_free(m_impl->m_properties.correlation_id);
    m_impl->m_properties._flags &= ~AMQP_BASIC_CORRELATION_ID_FLAG;
}
void BasicMessage::ClusterId(const std::string& cluster_id)
{
	if (AppIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id);
	m_impl->m_properties.cluster_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(cluster_id.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_CLUSTER_ID_FLAG;
}
void BasicMessage::MessageIdClear()
{
	if (MessageIdIsSet()) amqp_bytes_free(m_impl->m_properties.message_id);
    m_impl->m_properties._flags &= ~AMQP_BASIC_MESSAGE_ID_FLAG;
}
void BasicMessage::ClusterIdClear()
{
	if (ClusterIdIsSet()) amqp_bytes_free(m_impl->m_properties.cluster_id);
    m_impl->m_properties._flags &= ~AMQP_BASIC_CLUSTER_ID_FLAG;
}
void BasicMessage::Type(const std::string& type)
{
	if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type);
	m_impl->m_properties.type = amqp_bytes_malloc_dup(amqp_cstring_bytes(type.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_TYPE_FLAG;
}
Exemple #21
0
void * SWITCH_THREAD_FUNC mod_amqp_command_thread(switch_thread_t *thread, void *data)
{
	mod_amqp_command_profile_t *profile = (mod_amqp_command_profile_t *) data;

	while (profile->running) {
		amqp_queue_declare_ok_t *recv_queue;
		amqp_bytes_t queueName = { 0, NULL };

		/* Ensure we have an AMQP connection */
		if (!profile->conn_active) {
			switch_status_t status;
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Amqp no connection- reconnecting...\n");

			status = mod_amqp_connection_open(profile->conn_root, &(profile->conn_active), profile->name, profile->custom_attr);
			if ( status	!= SWITCH_STATUS_SUCCESS ) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n",
								  profile->name, status, profile->reconnect_interval_ms);
				switch_sleep(profile->reconnect_interval_ms * 1000);
				continue;
			}

			/* Check if exchange already exists */ 
			amqp_exchange_declare(profile->conn_active->state, 1,
								  amqp_cstring_bytes(profile->exchange),
								  amqp_cstring_bytes("topic"),
								  0, /* passive */
								  1, /* durable */
								  amqp_empty_table);

			if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Checking for command exchange")) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to create missing command exchange", profile->name);
				continue;
			}

			/* Ensure we have a queue */
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating command queue");
			recv_queue = amqp_queue_declare(profile->conn_active->state, // state
											1,                           // channel
											profile->queue ? amqp_cstring_bytes(profile->queue) : amqp_empty_bytes, // queue name
											0, 0,                        // passive, durable
											0, 1,                        // exclusive, auto-delete
											amqp_empty_table);           // args

			if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Declaring queue")) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Profile[%s] failed to connect with code(%d), sleeping for %dms\n",
								  profile->name, status, profile->reconnect_interval_ms);
				switch_sleep(profile->reconnect_interval_ms * 1000);
				continue;
			}

			if (queueName.bytes) {
				amqp_bytes_free(queueName);
			}

			queueName = amqp_bytes_malloc_dup(recv_queue->queue);

			if (!queueName.bytes) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Out of memory while copying queue name");
				break;
			}

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Created command queue %.*s", (int)queueName.len, (char *)queueName.bytes);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Binding command queue to exchange %s", profile->exchange);

			/* Bind the queue to the exchange */
			amqp_queue_bind(profile->conn_active->state,                   // state
							1,                                             // channel
							queueName,                                     // queue
							amqp_cstring_bytes(profile->exchange),         // exchange
							amqp_cstring_bytes(profile->binding_key),      // routing key
							amqp_empty_table);                             // args

			if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Binding queue")) {
				mod_amqp_connection_close(profile->conn_active);
				profile->conn_active = NULL;
				switch_sleep(profile->reconnect_interval_ms * 1000);
				continue;
			}

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Amqp reconnect successful- connected\n");
			continue;
		}

		// Start a command
		amqp_basic_consume(profile->conn_active->state,     // state
						   1,                               // channel
						   queueName,                       // queue
						   amqp_empty_bytes,                // command tag
						   0, 1, 0,                         // no_local, no_ack, exclusive
						   amqp_empty_table);               // args

		if (mod_amqp_log_if_amqp_error(amqp_get_rpc_reply(profile->conn_active->state), "Creating a command")) {
			mod_amqp_connection_close(profile->conn_active);
			profile->conn_active = NULL;
			switch_sleep(profile->reconnect_interval_ms * 1000);
			continue;
		}

		while (profile->running && profile->conn_active) {
			amqp_rpc_reply_t res;
			amqp_envelope_t envelope;
			struct timeval timeout = {0};
			char command[1024];
			enum ECommandFormat {
				COMMAND_FORMAT_UNKNOWN,
				COMMAND_FORMAT_PLAINTEXT
			} commandFormat = COMMAND_FORMAT_PLAINTEXT;
			char *fs_resp_exchange = NULL, *fs_resp_key = NULL;

			amqp_maybe_release_buffers(profile->conn_active->state);

			timeout.tv_usec = 500 * 1000;
			res = amqp_consume_message(profile->conn_active->state, &envelope, &timeout, 0);

			if (res.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION) {
				if (res.library_error == AMQP_STATUS_UNEXPECTED_STATE) {
					/* Unexpected frame. Discard it then continue */
					amqp_frame_t decoded_frame;
					amqp_simple_wait_frame(profile->conn_active->state, &decoded_frame);
				}

				if (res.library_error == AMQP_STATUS_SOCKET_ERROR) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A socket error occurred. Tearing down and reconnecting\n");
					break;
				}

				if (res.library_error == AMQP_STATUS_CONNECTION_CLOSED) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "AMQP connection was closed. Tearing down and reconnecting\n");
					break;
				}

				if (res.library_error == AMQP_STATUS_TCP_ERROR) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "A TCP error occurred. Tearing down and reconnecting\n");
					break;
				}

				if (res.library_error == AMQP_STATUS_TIMEOUT) {
					// nop
				}

				/* Try consuming again */
				continue;
			}

			if (res.reply_type != AMQP_RESPONSE_NORMAL) {
				break;
			}

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Delivery:%u, exchange:%.*s routingkey:%.*s\n",
							  (unsigned) envelope.delivery_tag, (int) envelope.exchange.len, (char *) envelope.exchange.bytes,
							  (int) envelope.routing_key.len, (char *) envelope.routing_key.bytes);

			if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {

				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Content-type: %.*s\n",
								  (int) envelope.message.properties.content_type.len, (char *) envelope.message.properties.content_type.bytes);

				if (strncasecmp("text/plain", envelope.message.properties.content_type.bytes, strlen("text/plain")) == 0) {
					commandFormat = COMMAND_FORMAT_PLAINTEXT;
				} else {
					commandFormat = COMMAND_FORMAT_UNKNOWN;
				}
			}

			if (envelope.message.properties.headers.num_entries) {
				int x = 0;

				for ( x = 0; x < envelope.message.properties.headers.num_entries; x++) {
					char *header_key = (char *)envelope.message.properties.headers.entries[x].key.bytes;
					char *header_value = (char *)envelope.message.properties.headers.entries[x].value.value.bytes.bytes;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AMQP message custom header key[%s] value[%s]\n", header_key, header_value);

					if ( !strncmp(header_key, "x-fs-api-resp-exchange", 22)) {
						fs_resp_exchange = header_value;
					} else if (!strncmp(header_key, "x-fs-api-resp-key", 17)) {
						fs_resp_key = header_value;
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring unrecognized event header [%s]\n", header_key);
					}
				}
			}

			if (commandFormat == COMMAND_FORMAT_PLAINTEXT) {
				switch_stream_handle_t stream = { 0 }; /* Collects the command output */

				/* Convert amqp bytes to c-string */
				snprintf(command, sizeof(command), "%.*s", (int) envelope.message.body.len, (char *) envelope.message.body.bytes);

				/* Execute the command */
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Executing: %s\n", command);

				SWITCH_STANDARD_STREAM(stream);

				if ( fs_resp_exchange && fs_resp_key ) {
					switch_status_t status = switch_console_execute(command, 0, &stream);
					mod_amqp_command_response(profile, command, stream, fs_resp_exchange, fs_resp_key, status);
				} else {
					if (switch_console_execute(command, 0, &stream) != SWITCH_STATUS_SUCCESS) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Remote command failed:\n%s\n", (char *) stream.data);
					} else {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Remote command succeeded:\n%s\n", (char *) stream.data);
					}
				}
				switch_safe_free(stream.data);
			}

			/* Tidy up */
			amqp_destroy_envelope(&envelope);
		}

		amqp_bytes_free(queueName);
		queueName.bytes = NULL;

		mod_amqp_connection_close(profile->conn_active);
		profile->conn_active = NULL;

		if (profile->running) {
			/* We'll reconnect, but sleep to avoid hammering resources */
			switch_sleep(500);
		}
	}

	/* Terminate the thread */
	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Command listener thread stopped\n");
	switch_thread_exit(thread, SWITCH_STATUS_SUCCESS);
	return NULL;
}
amqp_rpc_reply_t amqp_read_message_noblock(amqp_connection_state_t state,
                                           amqp_channel_t channel,
                                           amqp_message_t *message,
                                           AMQP_UNUSED int flags,
                                           struct timeval *timeout)
{
  amqp_frame_t frame;
  amqp_rpc_reply_t ret;

  size_t body_read;
  char *body_read_ptr;
  int res;

  memset(&ret, 0, sizeof(amqp_rpc_reply_t));
  memset(message, 0, sizeof(amqp_message_t));

  res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout);
  if (AMQP_STATUS_OK != res) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = res;

    goto error_out1;
  }

  if (AMQP_FRAME_HEADER != frame.frame_type) {
    if (AMQP_FRAME_METHOD == frame.frame_type &&
        (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
         AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {

      ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
      ret.reply = frame.payload.method;

    } else {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_UNEXPECTED_STATE;

      amqp_put_back_frame(state, &frame);
    }
    goto error_out1;
  }

  init_amqp_pool(&message->pool, 4096);
  res = amqp_basic_properties_clone(frame.payload.properties.decoded,
                                    &message->properties, &message->pool);

  if (AMQP_STATUS_OK != res) {
    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    ret.library_error = res;
    goto error_out3;
  }

  if (0 == frame.payload.properties.body_size) {
    message->body = amqp_empty_bytes;
  } else {
    message->body = amqp_bytes_malloc(frame.payload.properties.body_size);
    if (NULL == message->body.bytes) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_NO_MEMORY;
      goto error_out1;
    }
  }

  body_read = 0;
  body_read_ptr = message->body.bytes;

  while (body_read < message->body.len) {
    res = amqp_simple_wait_frame_on_channel_noblock(state, channel, &frame, timeout);
    if (AMQP_STATUS_OK != res) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = res;
      goto error_out2;
    }
    if (AMQP_FRAME_BODY != frame.frame_type) {
      if (AMQP_FRAME_METHOD == frame.frame_type &&
          (AMQP_CHANNEL_CLOSE_METHOD == frame.payload.method.id ||
           AMQP_CONNECTION_CLOSE_METHOD == frame.payload.method.id)) {

        ret.reply_type = AMQP_RESPONSE_SERVER_EXCEPTION;
        ret.reply = frame.payload.method;
      } else {
        ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
        ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
      }
      goto error_out2;
    }

    if (body_read + frame.payload.body_fragment.len > message->body.len) {
      ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;
      goto error_out2;
    }

    memcpy(body_read_ptr, frame.payload.body_fragment.bytes, frame.payload.body_fragment.len);

    body_read += frame.payload.body_fragment.len;
    body_read_ptr += frame.payload.body_fragment.len;
  }

  ret.reply_type = AMQP_RESPONSE_NORMAL;
  return ret;

error_out2:
  amqp_bytes_free(message->body);
error_out3:
  empty_amqp_pool(&message->pool);
error_out1:
  return ret;
}
void amqp_destroy_message(amqp_message_t *message)
{
  empty_amqp_pool(&message->pool);
  amqp_bytes_free(message->body);
}
void BasicMessage::ContentTypeClear()
{
	if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type);
    m_impl->m_properties._flags &= ~AMQP_BASIC_CONTENT_TYPE_FLAG;
}
void BasicMessage::TypeClear()
{
	if (TypeIsSet()) amqp_bytes_free(m_impl->m_properties.type);
    m_impl->m_properties._flags &= ~AMQP_BASIC_TYPE_FLAG;
}
void BasicMessage::ContentEncodingClear()
{
	if (ContentEncodingIsSet()) amqp_bytes_free(m_impl->m_properties.content_encoding);
    m_impl->m_properties._flags &= ~AMQP_BASIC_CONTENT_ENCODING_FLAG;
}
void BasicMessage::UserId(const std::string& user_id)
{
	if (UserIdIsSet()) amqp_bytes_free(m_impl->m_properties.user_id);
	m_impl->m_properties.user_id = amqp_bytes_malloc_dup(amqp_cstring_bytes(user_id.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_USER_ID_FLAG;
}
void BasicMessage::ContentType(const std::string& content_type)
{
	if (ContentTypeIsSet()) amqp_bytes_free(m_impl->m_properties.content_type);
	m_impl->m_properties.content_type = amqp_bytes_malloc_dup(amqp_cstring_bytes(content_type.c_str()));
    m_impl->m_properties._flags |= AMQP_BASIC_CONTENT_TYPE_FLAG;
}