int RabbitInBoundConnectionPoint::ListenMessage(void** destBuffer) throw (ConnectException)
			{
				amqp_rpc_reply_t res;
				amqp_envelope_t envelope;

				amqp_maybe_release_buffers(_conn);

				struct timeval timeout;
				timeout.tv_sec = 5;
				timeout.tv_usec = 0;

				res = amqp_consume_message(_conn, &envelope, &timeout, 0);
				  
				if (AMQP_RESPONSE_NORMAL == res.reply_type) 
				{
					int messageLen = (int) envelope.message.body.len;
					void* message = malloc(messageLen); 
					memcpy(message, envelope.message.body.bytes, messageLen);
					amqp_basic_ack(_conn, 1, envelope.delivery_tag, false);
					GetRabbitError("Ack Error");
					amqp_destroy_envelope(&envelope);
					*destBuffer = message;
					return messageLen;
				}
				else
				{
					if(res.library_error != AMQP_STATUS_TIMEOUT)
					{
						LOG(ERROR) << "Error al leer de Rabbit: " << amqp_error_string2(res.library_error);
						throw ConnectException("Error al leer de Rabbit", true);
					}
				}

				return 0;
			}
示例#2
0
文件: amqp.c 项目: Mindera/collectd
static void *camqp_subscribe_thread (void *user_data) /* {{{ */
{
    camqp_config_t *conf = user_data;
    int status;

    cdtime_t interval = plugin_get_interval ();

    while (subscriber_threads_running)
    {
        amqp_frame_t frame;

        status = camqp_connect (conf);
        if (status != 0)
        {
            struct timespec ts_interval;
            ERROR ("amqp plugin: camqp_connect failed. "
                    "Will sleep for %.3f seconds.",
                    CDTIME_T_TO_DOUBLE (interval));
            CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
            nanosleep (&ts_interval, /* remaining = */ NULL);
            continue;
        }

        status = amqp_simple_wait_frame (conf->connection, &frame);
        if (status < 0)
        {
            struct timespec ts_interval;
            ERROR ("amqp plugin: amqp_simple_wait_frame failed. "
                    "Will sleep for %.3f seconds.",
                    CDTIME_T_TO_DOUBLE (interval));
            camqp_close_connection (conf);
            CDTIME_T_TO_TIMESPEC (interval, &ts_interval);
            nanosleep (&ts_interval, /* remaining = */ NULL);
            continue;
        }

        if (frame.frame_type != AMQP_FRAME_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8,
                    frame.frame_type);
            continue;
        }

        if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32,
                    frame.payload.method.id);
            continue;
        }

        camqp_read_header (conf);

        amqp_maybe_release_buffers (conf->connection);
    } /* while (subscriber_threads_running) */

    camqp_config_free (conf);
    pthread_exit (NULL);
    return (NULL);
} /* }}} void *camqp_subscribe_thread */
示例#3
0
static int
noit_rabbimq_submit(iep_thread_driver_t *dr,
                    const char *payload, size_t payloadlen) {
  int rv;
  amqp_bytes_t body;
  struct amqp_driver *driver = (struct amqp_driver *)dr;
  const char *routingkey = driver->routingkey;

  body.len = payloadlen;
  body.bytes = (char *)payload;
  if(*payload == 'M' ||
     *payload == 'S' ||
     *payload == 'C' ||
     (*payload == 'H' && payload[1] == '1') ||
     (*payload == 'F' && payload[1] == '1') ||
     (*payload == 'B' && (payload[1] == '1' || payload[1] == '2'))) {
    char uuid_str[32 * 2 + 1];
    int account_id, check_id;
    if(extract_uuid_from_jlog(payload, payloadlen,
                              &account_id, &check_id, uuid_str)) {
      if(*routingkey) {
        char *replace;
        int newlen = strlen(driver->routingkey) + 1 + sizeof(uuid_str) + 2 * 32;
        replace = alloca(newlen);
        snprintf(replace, newlen, "%s.%x.%x.%d.%d%s", driver->routingkey,
                 account_id%16, (account_id/16)%16, account_id,
                 check_id, uuid_str);
        routingkey = replace;
      }
    }
  }
  rv = amqp_basic_publish(driver->connection, 1,
                          amqp_cstring_bytes(driver->exchange),
                          amqp_cstring_bytes(routingkey),
                          1, 0, NULL, body);
  if(rv < 0) {
    mtevL(mtev_error, "AMQP publish failed, disconnecting\n");
    amqp_connection_close(driver->connection, AMQP_REPLY_SUCCESS);
    amqp_destroy_connection(driver->connection);
    if(driver->sockfd >= 0) close(driver->sockfd);
    driver->sockfd = -1;
    driver->connection = NULL;
    return -1;
  }
  BUMPSTAT(publications);
  noit_rabbitmq_heartbeat(driver);
  noit_rabbitmq_read_frame(driver);
  amqp_maybe_release_buffers(driver->connection);
  if(driver->has_error) {
    amqp_connection_close(driver->connection, AMQP_REPLY_SUCCESS);
    amqp_destroy_connection(driver->connection);
    if(driver->sockfd >= 0) close(driver->sockfd);
    driver->sockfd = -1;
    driver->connection = NULL;
    return -1;
  }
  return 0;
}
示例#4
0
eSquere * eSquere::ConsumeMessage(std::string qname){
    if(this->IsError()) return this;
    amqp_maybe_release_buffers(this->connect);
    this->statusAMPQ=amqp_consume_message(this->connect, &this->Message, this->GetTimeOutPointer(), 0);
    this->SetStatusErrorAMPQ("Read Message "+qname);
    if(this->IsError()) return this;
    this->SetMessage(this->ToString(this->Message.message.body));
    return this;
}
示例#5
0
static void* _receiveThread(void* param) {
    MsgReceiver_t *receiver = (MsgReceiver_t *)param;
    amqp_envelope_t envelope;
    amqp_rpc_reply_t reply;
    amqp_frame_t *frame;
    time_t curtime;
    
    assert(receiver != NULL);
    
    LOG4CXX_DEBUG(logger, "_receiveThread: event receiver thread started");
    
    sendLeaseRequest(receiver);
    curtime = getCurrentTime();
    
    while(receiver->thread_run) {
        amqp_maybe_release_buffers(receiver->conn_state);
        
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        
        if(getElapsedSecond(curtime, getCurrentTime()) > 60*5) {
            sendLeaseRequest(receiver);
            curtime = getCurrentTime();
        }
        
        reply = amqp_consume_message(receiver->conn_state, &envelope, NULL, 0);
        if(reply.reply_type == AMQP_RESPONSE_NORMAL) {
            // call handler
            MsgClientCallback_t callback = receiver->callback;

            LOG4CXX_INFO(logger, "_receiveThread: received a message");
            
            if(callback != NULL) {
                LOG4CXX_INFO(logger, "_receiveThread: received a message - calling a callback function");
                callback((const char*)envelope.routing_key.bytes, envelope.routing_key.len, (const char*)envelope.message.body.bytes, envelope.message.body.len);
            }
            
            int ack_result = amqp_basic_ack(receiver->conn_state, receiver->channel, envelope.delivery_tag, false);
            if(ack_result != 0) {
                LOG4CXX_ERROR(logger, "_receiveThread: ack failed " << ack_result);
            }

            amqp_destroy_envelope(&envelope);
        } else {
            LOG4CXX_INFO(logger, "_receiveThread: an exception occurred");
        }
        
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    }
    
    receiver->thread_run = false;
}
示例#6
0
文件: amqp.c 项目: gnosek/collectd
static void *camqp_subscribe_thread (void *user_data) /* {{{ */
{
    camqp_config_t *conf = user_data;
    int status;

    while (subscriber_threads_running)
    {
        amqp_frame_t frame;

        status = camqp_connect (conf);
        if (status != 0)
        {
            ERROR ("amqp plugin: camqp_connect failed. "
                    "Will sleep for %i seconds.", interval_g);
            sleep (interval_g);
            continue;
        }

        status = amqp_simple_wait_frame (conf->connection, &frame);
        if (status < 0)
        {
            ERROR ("amqp plugin: amqp_simple_wait_frame failed. "
                    "Will sleep for %i seconds.", interval_g);
            camqp_close_connection (conf);
            sleep (interval_g);
            continue;
        }

        if (frame.frame_type != AMQP_FRAME_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8,
                    frame.frame_type);
            continue;
        }

        if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
        {
            DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32,
                    frame.payload.method.id);
            continue;
        }

        status = camqp_read_header (conf);

        amqp_maybe_release_buffers (conf->connection);
    } /* while (subscriber_threads_running) */

    camqp_config_free (conf);
    pthread_exit (NULL);
} /* }}} void *camqp_subscribe_thread */
示例#7
0
void consume(int argc, char* argv[])
{
    if (argc < 4)
    {
        help();
    }

    std::string queue = argv[2];
    int msg_cnt = atoi(argv[3]);
    // 消费
    amqp_basic_qos(conn, 
            channel_id,
            0, /* prefetch_size */
            1, /* prefetch_count */
            0 /* global */);

    amqp_basic_consume(conn,        /* connection */
            channel_id,  /* channel */
            amqp_cstring_bytes(queue.c_str()),  /* queue */
            amqp_cstring_bytes(int2str(channel_id).c_str()),     /* consumer_tag */
            0,       /* no_local */
            0,       /* no_ack */
            1,       /* exclusive */
            amqp_empty_table    /* argument */
            );

    int got = 0;
    while (got++ < msg_cnt)
    {
        amqp_envelope_t envelope;
        memset(&envelope, 0, sizeof(envelope));

        amqp_maybe_release_buffers(conn);

        amqp_consume_message(conn, &envelope, NULL, 0);
        check_amqp_reply("amqp consume msg failed.", "");

        std::string data((char*)envelope.message.body.bytes, envelope.message.body.len);

        int channel_id = envelope.channel;
        int delivery_tag = envelope.delivery_tag;

        std::cout << "channelid: " << channel_id << ", delivery_tag: " << delivery_tag << ", data[" << data << "]" << std::endl;
        amqp_basic_ack(conn, channel_id, delivery_tag, 0 /* multiple */);
        check_amqp_reply("amqp basic ack failed.", "amqp basic ack succ.");

        amqp_destroy_envelope(&envelope);
//        usleep(10000);
    }
}
void Channel::listen(Callable_envelope& callback){
	amqp_connection_state_t conn = this->conn_ptr->_getconn_n();
		//open channel
		//amqp_channel_open(conn, channel);
		//die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
		//set consumer
	amqp_basic_consume(conn,
			this->channel_n,
			amqp_cstring_bytes(this->queue_name.c_str()),
			amqp_empty_bytes, 0, 1, 0, amqp_empty_table);//auto ack consumer
	die_on_amqp_error(amqp_get_rpc_reply(this->conn_ptr->_getconn_n()), "rabbitmq_listen Consuming");


		{
			  while (1) {
			      amqp_rpc_reply_t res;
			      amqp_envelope_t envelope;

			      amqp_maybe_release_buffers(conn);

			      res = amqp_consume_message(conn, &envelope, NULL, 0);

			      if (AMQP_RESPONSE_NORMAL != res.reply_type) {
			        //this solution is not really work when network changed.

			    	  label_listen_reconnet:
			    	  Log::log.warning("Channel::listen, AMQP response abnormal\n");
			    	  Log::log.warning("Channel::listen, reconnecting...\n");
			    	  //first close previous
			    	  amqp_channel_close(this->conn_ptr->_getconn_n(), this->channel_n, AMQP_REPLY_SUCCESS);
			    	  amqp_connection_close(this->conn_ptr->_getconn_n(), AMQP_REPLY_SUCCESS);
			    	  amqp_destroy_connection(this->conn_ptr->_getconn_n());

			    	  //reconnect to rabbitMQ server!
			    	  this->conn_ptr->reconnnect();
			    	  amqp_channel_open(this->conn_ptr->_getconn_n(), channel_n);
			    	  if(amqp_get_rpc_reply(this->conn_ptr->_getconn_n()).reply_type !=AMQP_RESPONSE_NORMAL){
			    	  	Log::log.warning("Channel::publish:Opening channel_n error\n");
			    	  	sleep(2);
			    	  	goto label_listen_reconnet;
			    	  }else{
			    		  continue;
			    	  }
			      }
			      callback.callback(envelope);
			      amqp_destroy_envelope(&envelope);
			 }
		}
		die_on_amqp_error(amqp_channel_close(conn, this->channel_n, AMQP_REPLY_SUCCESS), "Closing channel");
}
示例#9
0
amqp_rpc_reply_t amqp_login(amqp_connection_state_t state,
			    char const *vhost,
			    int channel_max,
			    int frame_max,
			    int heartbeat,
			    amqp_sasl_method_enum sasl_method,
			    ...)
{
  va_list vl;
  amqp_rpc_reply_t result;
  int status;

  va_start(vl, sasl_method);

  status = amqp_login_inner(state, channel_max, frame_max, heartbeat, sasl_method, vl);
  if (status < 0) {
    result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    result.reply.id = 0;
    result.reply.decoded = NULL;
    result.library_error = -status;
    return result;
  }

  {
    amqp_method_number_t replies[] = { AMQP_CONNECTION_OPEN_OK_METHOD, 0 };
    amqp_connection_open_t s;
    s.virtual_host = amqp_cstring_bytes(vhost);
    s.capabilities.len = 0;
    s.capabilities.bytes = NULL;
    s.insist = 1;

    result = amqp_simple_rpc(state,
			     0,
			     AMQP_CONNECTION_OPEN_METHOD,
			     (amqp_method_number_t *) &replies,
			     &s);
    if (result.reply_type != AMQP_RESPONSE_NORMAL)
      return result;
  }
  amqp_maybe_release_buffers(state);

  va_end(vl);

  result.reply_type = AMQP_RESPONSE_NORMAL;
  result.reply.id = 0;
  result.reply.decoded = NULL;
  result.library_error = 0;
  return result;
}
示例#10
0
void ChannelImpl::MaybeReleaseBuffers()
{
    // Check to see if we have any amqp_frame_t's lying around, if not we can tell the library to recycle its buffers
    bool buffers_empty = true;
    for (channel_map_iterator_t it = m_open_channels.begin(); it != m_open_channels.end(); ++it)
    {
        if (!it->second.empty())
        {
            buffers_empty = false;
            break;
        }
    }

    if (buffers_empty)
    {
        amqp_maybe_release_buffers(m_connection);
    }
}
示例#11
0
int main(int argc,const char *argv[]) {

	const char *hostName;
	int port;
	const char *queueName;
	int prefetchCount;
	int noAck = 1;

	if (argc < 6) {
		fprintf(stderr,"Usage: consumer host port queuename prefetch_count no_ack\n");
		exit(1);
	}

	hostName = argv[1];
	port = atoi(argv[2]);
	queueName = argv[3];
	prefetchCount = atoi(argv[4]);
	if(strcmp(argv[5],"false")==0) noAck = 0;

	int sockfd;
	int channelId = 1;
	amqp_connection_state_t conn;
	conn = amqp_new_connection();

	die_on_error(sockfd = amqp_open_socket(hostName, port), "Opening socket");
	amqp_set_sockfd(conn, sockfd);
	die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),"Logging in");
	amqp_channel_open(conn, channelId);
	die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

	amqp_basic_qos(conn,channelId,0,prefetchCount,0);
	amqp_basic_consume(conn,channelId,amqp_cstring_bytes(queueName),amqp_empty_bytes,0,noAck,0,amqp_empty_table);
	die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

	int count = 0;
	amqp_frame_t frame;
	int result;
	amqp_basic_deliver_t *d;
	amqp_basic_properties_t *p;
	size_t body_target;
	size_t body_received;

	long long start = timeInMilliseconds();
	while(1){
		{
			amqp_maybe_release_buffers(conn);
			result = amqp_simple_wait_frame(conn, &frame);
			if (result < 0)
				break;
			if (frame.frame_type != AMQP_FRAME_METHOD)
				continue;
			if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
				continue;
			d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
			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;
			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;
				assert(body_received <= body_target);
			}

			if (body_received != body_target) {
				break;
			}
			if(!noAck)
				amqp_basic_ack(conn,channelId,d->delivery_tag,0);
		}

		count++;
		if(count%10000 == 0) {
			long long end = timeInMilliseconds();
			fprintf(stderr,"round %d takes %lld millseconds(10000 messages consumed every round)\n",count/10000-1,end-start);
			start = timeInMilliseconds();
		}
	}


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

	return 0;
}
示例#12
0
static void run(amqp_connection_state_t conn)
{
  uint64_t start_time = now_microseconds();
  int received = 0;
  int previous_received = 0;
  uint64_t previous_report_time = start_time;
  uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;

  amqp_frame_t frame;

  uint64_t now;

  while (1) {
    amqp_rpc_reply_t ret;
    amqp_envelope_t envelope;

    now = now_microseconds();
    if (now > next_summary_time) {
      int countOverInterval = received - previous_received;
      double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
      printf("%d ms: Received %d - %d since last report (%d Hz)\n",
             (int)(now - start_time) / 1000, received, countOverInterval, (int) intervalRate);

      previous_received = received;
      previous_report_time = now;
      next_summary_time += SUMMARY_EVERY_US;
    }

    amqp_maybe_release_buffers(conn);
    ret = amqp_consume_message(conn, &envelope, NULL, 0);

    if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
      if (AMQP_RESPONSE_LIBRARY_EXCEPTION == ret.reply_type &&
          AMQP_STATUS_UNEXPECTED_STATE == ret.library_error) {
        if (AMQP_STATUS_OK != amqp_simple_wait_frame(conn, &frame)) {
          return;
        }

        if (AMQP_FRAME_METHOD == frame.frame_type) {
          switch (frame.payload.method.id) {
            case AMQP_BASIC_ACK_METHOD:
              /* if we've turned publisher confirms on, and we've published a message
               * here is a message being confirmed
               */

              break;
            case AMQP_BASIC_RETURN_METHOD:
              /* if a published message couldn't be routed and the mandatory flag was set
               * this is what would be returned. The message then needs to be read.
               */
              {
                amqp_message_t message;
                ret = amqp_read_message(conn, frame.channel, &message, 0);
                if (AMQP_RESPONSE_NORMAL != ret.reply_type) {
                  return;
                }

                amqp_destroy_message(&message);
              }

              break;

            case AMQP_CHANNEL_CLOSE_METHOD:
              /* a channel.close method happens when a channel exception occurs, this
               * can happen by publishing to an exchange that doesn't exist for example
               *
               * In this case you would need to open another channel redeclare any queues
               * that were declared auto-delete, and restart any consumers that were attached
               * to the previous channel
               */
              return;

            case AMQP_CONNECTION_CLOSE_METHOD:
              /* a connection.close method happens when a connection exception occurs,
               * this can happen by trying to use a channel that isn't open for example.
               *
               * In this case the whole connection must be restarted.
               */
              return;

            default:
              fprintf(stderr ,"An unexpected method was received %d\n", frame.payload.method.id);
              return;
          }
        }
      }

    } else {
      amqp_destroy_envelope(&envelope);
    }

    received++;
  }
}
示例#13
0
int main(int argc, char const *const *argv)
{
  char const *hostname;
  int port, status;
  char const *exchange;
  char const *bindingkey;
  amqp_socket_t *socket = NULL;
  amqp_connection_state_t conn;

  amqp_bytes_t queuename;

  if (argc < 5) {
    fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey\n");
    return 1;
  }

  hostname = argv[1];
  port = atoi(argv[2]);
  exchange = argv[3];
  bindingkey = argv[4];

  conn = amqp_new_connection();

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

  status = amqp_socket_open(socket, hostname, port);
  if (status) {
    die("opening TCP socket");
  }

  die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
                    "Logging in");
  amqp_channel_open(conn, 1);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

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

  amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
                  amqp_empty_table);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");

  amqp_basic_consume(conn, 1, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

  {
    while (1) {
      amqp_rpc_reply_t res;
      amqp_envelope_t envelope;

      amqp_maybe_release_buffers(conn);

      res = amqp_consume_message(conn, &envelope, NULL, 0);

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

      printf("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) {
        printf("Content-type: %.*s\n",
               (int) envelope.message.properties.content_type.len,
               (char *) envelope.message.properties.content_type.bytes);
      }

      amqp_destroy_envelope(&envelope);
    }
  }

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

  return 0;
}
示例#14
0
static void run(amqp_connection_state_t conn)
{
  uint64_t start_time = now_microseconds();
  int received = 0;
  int previous_received = 0;
  uint64_t previous_report_time = start_time;
  uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;

  amqp_frame_t frame;
  int result;
  size_t body_received;
  size_t body_target;

  uint64_t now;

  while (1) {
    now = now_microseconds();
    if (now > next_summary_time) {
      int countOverInterval = received - previous_received;
      double intervalRate = countOverInterval / ((now - previous_report_time) / 1000000.0);
      printf("%d ms: Received %d - %d since last report (%d Hz)\n",
	     (int)(now - start_time) / 1000, received, countOverInterval, (int) intervalRate);

      previous_received = received;
      previous_report_time = now;
      next_summary_time += SUMMARY_EVERY_US;
    }

    amqp_maybe_release_buffers(conn);
    result = amqp_simple_wait_frame(conn, &frame);
    if (result < 0)
      return;

    if (frame.frame_type != AMQP_FRAME_METHOD)
      continue;

    if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
      continue;

    result = amqp_simple_wait_frame(conn, &frame);
    if (result < 0)
      return;
    
    if (frame.frame_type != AMQP_FRAME_HEADER) {
      fprintf(stderr, "Expected header!");
      abort();
    }

    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)
	return;

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

      body_received += frame.payload.body_fragment.len;
      assert(body_received <= body_target);
    }

    received++;
  }
}
示例#15
0
文件: lc_bus.c 项目: davidddw/lcm
static int lc_bus_consume_message_atomic(amqp_connection_state_t *conn,
        uint32_t flag, amqp_envelope_t *envelope,
        amqp_frame_t *frame, amqp_message_t *message, char *buf, int buf_len)
{
    static struct timeval timeout = { tv_sec: RECV_TIMEOUT, tv_usec: 0 };
    size_t body_remaining = 0, offset = 0;
    int res = LC_BUS_OK;
    amqp_basic_deliver_t *deliver = NULL;

    if (!envelope || !frame || !message) {
        return 0;
    }

    amqp_maybe_release_buffers(*conn);
#if 0
    amqp_consume_message(*conn, envelope, &timeout, 0);
#endif

    res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout);
    if (res) {
        LB_SYSLOG(LOG_ERR, "waiting for method frame, ret=%d.\n", res);
        if (res != AMQP_STATUS_TIMEOUT) {
            return -1;
        }
        return 0;
    }
    if (frame->frame_type != AMQP_FRAME_METHOD ||
        frame->payload.method.id != AMQP_BASIC_DELIVER_METHOD) {
        LB_SYSLOG(LOG_WARNING, "got frame type 0x%X (expect AMQP_FRAME_METHOD "
                "0x%X) method 0x%X (expect AMQP_BASIC_DELIVER_METHOD 0x%X), "
                "ignore this message.\n", frame->frame_type, AMQP_FRAME_METHOD,
                frame->payload.method.id, AMQP_BASIC_DELIVER_METHOD);
        return 0;
    }
    LB_SYSLOG(LOG_INFO, "got frame type 0x%X method 0x%X.\n",
            frame->frame_type, frame->payload.method.id);
    deliver = (amqp_basic_deliver_t *)frame->payload.method.decoded;

    res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout);
    if (res) {
        LB_SYSLOG(LOG_ERR, "waiting for header frame, ret=%d\n", res);
        if (res != AMQP_STATUS_TIMEOUT) {
            return -1;
        }
        return 0;
    }
    if (frame->frame_type != AMQP_FRAME_HEADER) {
        LB_SYSLOG(LOG_ERR, "got frame type 0x%X (expect "
                "AMQP_FRAME_HEADER 0x%X).\n",
                frame->frame_type, AMQP_FRAME_HEADER);
        return 0;
    }
    body_remaining = frame->payload.properties.body_size;
    LB_SYSLOG(LOG_INFO, "got frame type 0x%X (AMQP_FRAME_HEADER), "
            "AMQP_FRAME_BODY len %zd\n",
            frame->frame_type, body_remaining);

    while (body_remaining) {
        res = amqp_simple_wait_frame_noblock(*conn, frame, &timeout);
        if (res) {
            LB_SYSLOG(LOG_ERR, "waiting for body frame, ret=%d\n", res);
            if (res != AMQP_STATUS_TIMEOUT) {
                return -1;
            }
            return 0;
        }
        if (frame->frame_type != AMQP_FRAME_BODY) {
            LB_SYSLOG(LOG_ERR, "expected header, got frame type 0x%X\n",
                    frame->frame_type);
            return 0;
        }
        LB_SYSLOG(LOG_DEBUG, "got body len %zd\n",
                frame->payload.body_fragment.len);

        memcpy(buf + offset, frame->payload.body_fragment.bytes,
                MINV(buf_len - offset, frame->payload.body_fragment.len));
        if (buf_len - offset < frame->payload.body_fragment.len) {
            offset = buf_len;
        } else {
            offset += frame->payload.body_fragment.len;
        }
        body_remaining -= frame->payload.body_fragment.len;
    }

    if (flag & LC_BUS_CONSUME_WITH_ACK) {
        res = amqp_basic_ack(
                    *conn,
                    LC_BUS_CHANNEL,
                    deliver->delivery_tag,
                    0  /* multiple */
                    );
        if (res) {
            LB_SYSLOG(LOG_ERR, "basic ack, channel=%u ret=%d\n",
                    LC_BUS_CHANNEL, res);
            return 0;
        }
    }

    if (buf_len == offset) {
        /* buffer is not enough */
        return 0;
    }
    return offset;
}
示例#16
0
static
int rabbitmq_consume_message_and_forward(zloop_t *loop, zmq_pollitem_t *item, void* arg)
{
    rabbit_listener_state_t *state = (rabbit_listener_state_t*)arg;
    void *receiver = state->receiver;
    amqp_connection_state_t conn = state->conn;
    amqp_rpc_reply_t res;
    amqp_envelope_t envelope;

    amqp_maybe_release_buffers(conn);

    // printf("[D] consuming\n");
    res = amqp_consume_message(conn, &envelope, NULL, 0);

    if (AMQP_RESPONSE_NORMAL != res.reply_type) {
        zsys_interrupted = 1;
        log_amqp_error(res, "consuming from RabbitMQ");
        return -1;
    }

    // if (envelope.message.properties._flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
    //     printf("[D] content-type: %.*s\n",
    //            (int) envelope.message.properties.content_type.len,
    //            (char *) envelope.message.properties.content_type.bytes);
    // }

    const char *meta_data = NULL;
    amqp_basic_properties_t *properties = &envelope.message.properties;
    amqp_table_t *headers = &properties->headers;
    int n = headers->num_entries;
    for (int i = 0; i < n; i++) {
        amqp_bytes_t *key = &headers->entries[i].key;
        if (key->len == 4 && memcmp(key->bytes, "info", 4) == 0) {
            amqp_field_value_t *value = &headers->entries[i].value;
            if (value->kind == 'S' && value->value.bytes.len == sizeof(msg_meta_t))
                meta_data = value->value.bytes.bytes;
        }
    }

    // send messages to main thread
    zmsg_t *msg = zmsg_new();
    // skip request-stream prefix, leaving only app-env
    if (envelope.exchange.len > 15 && !strncmp(envelope.exchange.bytes, "request-stream-", 15))
        zmsg_addmem(msg, envelope.exchange.bytes+15, envelope.exchange.len-15);
    else
        zmsg_addmem(msg, envelope.exchange.bytes, envelope.exchange.len);
    zmsg_addmem(msg, envelope.routing_key.bytes, envelope.routing_key.len);
    zmsg_addmem(msg, envelope.message.body.bytes, envelope.message.body.len);
    if (meta_data)
        zmsg_addmem(msg, meta_data, sizeof(msg_meta_t));
    // zmsg_dump(msg);

    if (zmq_output_socket_ready(receiver)) {
        zmsg_send(&msg, receiver);
    } else {
        if (!zsys_interrupted)
            fprintf(stderr, "[E] dropped message because receiver socket wasn't ready\n");
        zmsg_destroy(&msg);
    }

    amqp_destroy_envelope(&envelope);

    return 0;
}
int main(int argc, const char **argv) {

	const char *hostname;
	int port;
	const char *exchange;
	const char *routingkey;
	const char *exchangetype = "direct";

	if (argc < 5) {
		fprintf(stderr, "Usage: receive_logs_direct host port exchange routingkeys...\n");
		return 1;
	}

	hostname = argv[1];
	port = atoi(argv[2]);
	exchange = argv[3];

	int sockfd;
	int channelid = 1;
	amqp_connection_state_t conn;
	conn = amqp_new_connection();

	die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket");
	amqp_set_sockfd(conn, sockfd);
	die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),"Logging in");
	amqp_channel_open(conn, channelid);
	die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

	amqp_exchange_declare(conn,channelid,amqp_cstring_bytes(exchange),amqp_cstring_bytes(exchangetype),0,1,
						  amqp_empty_table);
	die_on_amqp_error(amqp_get_rpc_reply(conn),"Declaring exchange");

	amqp_queue_declare_ok_t *r = amqp_queue_declare(conn,channelid,amqp_empty_bytes,0,0,1,0,amqp_empty_table);

	int i;
	for(i = 4;i < argc;i++)
	{
		routingkey = argv[i];
		amqp_queue_bind(conn,channelid,amqp_bytes_malloc_dup(r->queue),amqp_cstring_bytes(exchange),
						amqp_cstring_bytes(routingkey),amqp_empty_table);
	}

	amqp_basic_qos(conn,channelid,0,1,0);
	amqp_basic_consume(conn,channelid,amqp_bytes_malloc_dup(r->queue),amqp_empty_bytes,0,0,0,amqp_empty_table);
	die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

	{
		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);
			}

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

			int sleep_seconds = 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;
				assert(body_received <= body_target);

				int i;
				for(i = 0; i<frame.payload.body_fragment.len; i++)
				{
					printf("%c",*((char*)frame.payload.body_fragment.bytes+i));
					if(*((char*)frame.payload.body_fragment.bytes+i) == '.')
						sleep_seconds++;
				}
				printf("\n");

			}

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

			amqp_basic_ack(conn,channelid,d->delivery_tag,0);
		}
	}

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

	return 0;
}
示例#18
0
amqp_rpc_reply_t amqp_simple_rpc(amqp_connection_state_t state,
				 amqp_channel_t channel,
				 amqp_method_number_t request_id,
				 amqp_method_number_t *expected_reply_ids,
				 void *decoded_request_method)
{
  int status;
  amqp_rpc_reply_t result;

  memset(&result, 0, sizeof(result));

  status = amqp_send_method(state, channel, request_id, decoded_request_method);
  if (status < 0) {
    result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
    result.library_error = -status;
    return result;
  }

  {
    amqp_frame_t frame;

  retry:
    status = wait_frame_inner(state, &frame);
    if (status < 0) {
      result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
      result.library_error = -status;
      return result;
    }

    /*
     * We store the frame for later processing unless it's something
     * that directly affects us here, namely a method frame that is
     * either
     *  - on the channel we want, and of the expected type, or
     *  - on the channel we want, and a channel.close frame, or
     *  - on channel zero, and a connection.close frame.
     */
    if (!( (frame.frame_type == AMQP_FRAME_METHOD) &&
	   (   ((frame.channel == channel) &&
		((amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids)) ||
		 (frame.payload.method.id == AMQP_CHANNEL_CLOSE_METHOD)))
	    ||
	       ((frame.channel == 0) &&
		(frame.payload.method.id == AMQP_CONNECTION_CLOSE_METHOD))   ) ))
    {
      amqp_frame_t *frame_copy = amqp_pool_alloc(&state->decoding_pool, sizeof(amqp_frame_t));
      amqp_link_t *link = amqp_pool_alloc(&state->decoding_pool, sizeof(amqp_link_t));

      if (frame_copy == NULL || link == NULL) {
	result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
	result.library_error = ERROR_NO_MEMORY;
	return result;
      }

      *frame_copy = frame;

      link->next = NULL;
      link->data = frame_copy;

      if (state->last_queued_frame == NULL) {
	state->first_queued_frame = link;
      } else {
	state->last_queued_frame->next = link;
      }
      state->last_queued_frame = link;

      goto retry;
    }

    result.reply_type = (amqp_id_in_reply_list(frame.payload.method.id, expected_reply_ids))
      ? AMQP_RESPONSE_NORMAL
      : AMQP_RESPONSE_SERVER_EXCEPTION;

    result.reply = frame.payload.method;
    amqp_maybe_release_buffers(state);
    return result;
  }
}
示例#19
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;
}
示例#20
0
int main(int argc, char const * const *argv) {
  char const *hostname;
  int port;
  char const *exchange;
  char const *bindingkey;

  int sockfd;
  amqp_connection_state_t conn;

  amqp_bytes_t queuename;

  if (argc < 5) {
    fprintf(stderr, "Usage: amqp_listen host port exchange bindingkey\n");
    return 1;
  }

  hostname = argv[1];
  port = atoi(argv[2]);
  exchange = argv[3];
  bindingkey = argv[4];

  conn = amqp_new_connection();

  die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket");
  amqp_set_sockfd(conn, sockfd);
  die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
		    "Logging in");
  amqp_channel_open(conn, 1);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

  {
    amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, AMQP_EMPTY_BYTES, 0, 0, 0, 1,
						    AMQP_EMPTY_TABLE);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
    queuename = amqp_bytes_malloc_dup(r->queue);
    if (queuename.bytes == NULL) {
      die_on_error(-ENOMEM, "Copying queue name");
    }
  }

  amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey),
		  AMQP_EMPTY_TABLE);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");

  amqp_basic_consume(conn, 1, queuename, AMQP_EMPTY_BYTES, 0, 1, 0);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

  {
    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;
	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;
      }
    }
  }

  die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS), "Closing channel");
  die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
  amqp_destroy_connection(conn);
  die_on_error(close(sockfd), "Closing socket");

  return 0;
}
示例#21
0
int main(int argc, char **argv) {
  char const *hostname = "amqpbroker"; // amqp hostname
  int port = 5672; // amqp port
  static int verbose_flag = 0; // be verbose?
  static int foreground_flag = 0;
  static int passive = 0;  // declare queue passively?
  static int exclusive = 0;  // declare queue as exclusive?
  static int durable = 0;  // decalre queue as durable?
  static int no_ack = 0;
  static int msg_limit = 0; // maxiumum number of messages to retrieve
  int const no_local = 1;   // we never want to see messages we publish
  int c; // for option parsing
  char const *exchange = "";
  char const *bindingkey = "";
  char const *vhost = "/";
  char const *username = "******";
  char const *password = "******";
  char const *program = NULL;
  char const *program_args = NULL;
  amqp_bytes_t queue = AMQP_EMPTY_BYTES;

  int sockfd;
  amqp_connection_state_t conn;

  amqp_bytes_t queuename;

  if (NULL != getenv("AMQP_HOST"))
    hostname = getenv("AMQP_HOST");
  if (NULL != getenv("AMQP_PORT"))
    port = atoi(getenv("AMQP_PORT"));
  port = port > 0 ? port : 5672; // 5672 is the default amqp port
  if (NULL != getenv("AMQP_VHOST"))
    vhost = getenv("AMQP_VHOST");
  if (NULL != getenv("AMQP_USER"))
    username = getenv("AMQP_USER");
  if (NULL != getenv("AMQP_PASSWORD"))
    password = getenv("AMQP_PASSWORD");
  if (NULL != getenv("AMQP_QUEUE"))
    queue = amqp_cstring_bytes(getenv("AMQP_QUEUE"));
  if (NULL != getenv("AMQP_QUEUE_PASSIVE"))
    passive = atoi(getenv("AMQP_QUEUE_PASSIVE"));
  if (NULL != getenv("AMQP_QUEUE_EXCLUSIVE"))
    exclusive = atoi(getenv("AMQP_QUEUE_EXCLUSIVE"));
  if (NULL != getenv("AMQP_QUEUE_DURABLE"))
    durable = atoi(getenv("AMQP_QUEUE_DURABLE"));
  if (NULL != getenv("AMQP_MSG_LIMIT"))
    msg_limit = atoi(getenv("AMQP_MSG_LIMIT"));
  msg_limit = msg_limit > 0 ? msg_limit : 0; // default to unlimited

  while(1) {
    static struct option long_options[] =
    {
      {"verbose", no_argument,  &verbose_flag, 1},
      {"user", required_argument, 0, 'u'},
      {"password", required_argument, 0, 'p'},
      {"vhost", required_argument, 0, 'v'},
      {"host", required_argument, 0, 'h'},
      {"port", required_argument, 0, 'P'},
      {"number", required_argument, 0, 'n'},
      {"foreground", no_argument, 0, 'f'},
      {"passive", no_argument, &passive, 1},
      {"exclusive", no_argument, &exclusive, 1},
      {"durable", no_argument, &durable, 1},
      {"no-ack", no_argument, &no_ack, 1},
      {"execute", required_argument, 0, 'e'},
      {"queue", required_argument, 0, 'q'},
      {"help", no_argument, 0, '?'},
      {0, 0, 0, 0}
    };
    int option_index = 0;
    c = getopt_long(argc, argv, "v:h:P:u:p:n:fe:q:?",
                    long_options, &option_index);
    if(c == -1)
      break;

    switch(c) {
      case 0: // no_argument
        break;
      case 'v':
        vhost = optarg;
        break;
      case 'h':
        hostname = optarg;
        break;
      case 'P':
        port = atoi(optarg);
        port = port > 0 ? port : 5672; // 5672 is the default amqp port
        break;
      case 'f':
        foreground_flag = 1;
      case 'n':
        msg_limit = atoi(optarg);
        msg_limit = msg_limit > 0 ? msg_limit : 0; // deafult to unlimited
        break;
      case 'e':
        program = optarg;
        break;
      case 'u':
        username = optarg;
        break;
      case 'p':
        password = optarg;
        break;
      case 'q':
        queue = amqp_cstring_bytes(optarg);
        break;
      case '?':
      default:
        print_help(argv[0]);
        exit(1);
    }
  }

  if ((argc-optind) < 2) {
    print_help(argv[0]);
    return 1;
  }
  exchange = argv[optind];
  bindingkey = argv[optind+1];

  if (NULL != program) {
    // check that the program is executable
    char *wend;
    wend = strchr(program, ' ');
    if(wend){
        *wend = '\0';
        program_args = wend+1;
    }
    if (0 != access(program, X_OK)) {
        fprintf(stderr, "Program doesn't have execute permission, aborting: %s\n", program);
        exit(-1);
      }
    if(wend){
        *wend = ' ';
    }
  }

  if ((passive != 0) && (passive != 1)) {
    fprintf(stderr, "Queue option 'passive' must be 0 or 1: %u\n", passive);
    exit(-1);
  }
  if ((exclusive != 0) && (exclusive != 1)) {
    fprintf(stderr, "Queue option 'exclusive' must be 0 or 1: %u\n", exclusive);
    exit(-1);
  }
  if ((durable != 0) && (durable != 1)) {
    fprintf(stderr, "Queue option 'durable' must be 0 or 1: %u\n", durable);
    exit(-1);
  }

  conn = amqp_new_connection();

  die_on_error(sockfd = amqp_open_socket(hostname, port), "Opening socket");
  amqp_set_sockfd(conn, sockfd);
  die_on_amqp_error(amqp_login(conn, vhost,
                               0,         /* channel_max */
                               10485760,  /* max frame size, 10MB */
                               30,        /* heartbeat, 30 secs */
                               AMQP_SASL_METHOD_PLAIN,
                               username, password),
        "Logging in");
  amqp_channel_open(conn, AMQP_CHANNEL);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");
  {
    int optval = 1;
    socklen_t optlen = sizeof(optlen);
    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
  }
  {
    amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, AMQP_CHANNEL, queue, passive,
        durable, exclusive, 1, AMQP_EMPTY_TABLE);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue");
    queuename = amqp_bytes_malloc_dup(r->queue);
    if (queuename.bytes == NULL) {
      fprintf(stderr, "Out of memory while copying queue name\n");
      return 1;
    }
  }

  amqp_queue_bind(conn, AMQP_CHANNEL, queuename, amqp_cstring_bytes(exchange),
                  amqp_cstring_bytes(bindingkey), AMQP_EMPTY_TABLE);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue");

  /* Set our prefetch to the maximum number of messages we want to ensure we
   * don't take more than we want according to --number option from user */
  int prefetch_limit = DEFAULT_PREFETCH;
  if (msg_limit > 0 && msg_limit <= 65535)
    prefetch_limit = msg_limit;

  amqp_basic_qos(conn, AMQP_CHANNEL, 0, prefetch_limit, 0);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Setting Basic QOS (prefetch limit)");

  amqp_basic_consume(conn, AMQP_CHANNEL, queuename, AMQP_EMPTY_BYTES, no_local, no_ack, exclusive,
                     AMQP_EMPTY_TABLE);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

  // If executing a program, daemonise
  if(NULL != program && 0 == foreground_flag)
  {
    pid_t pid, sid;
    pid = fork();
    if (pid < 0) {
      exit(EXIT_FAILURE);
    } else if(pid > 0) {
      exit(EXIT_SUCCESS);
    }
    umask(0);
    sid = setsid();
    if (sid < 0)
      exit(EXIT_FAILURE);
  }

  {
    amqp_frame_t frame;
    int result;
    int status = 0; /* wait() status, used whether to send ACK */

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

    install_term_handler(SIGINT);
    install_term_handler(SIGTERM);
    install_term_handler(SIGHUP);

    int msg_count = 0;
    while (1) {
      char tempfile[] = "/tmp/amqp.XXXXXX";
      int tempfd;

      // exit if we've reached our maximum message count
      if((0 != msg_limit) && (msg_limit == msg_count))
        break;
      // we haven't reached our limit; move on to the next
      msg_count++;

      if(g_shutdown == 1)
          break;

      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_HEARTBEAT) {
        // send the same heartbeat frame back
        amqp_send_frame(conn, &frame);
        continue;
      } else 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;

      tempfd = mkstemp(tempfile);
      //tempfd = open(tempfile, O_WRONLY | O_CREAT | O_EXCL, 660);
      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;
        assert(body_received <= body_target);

        if (write(tempfd, frame.payload.body_fragment.bytes,
                          frame.payload.body_fragment.len) < 0) {
          perror("Error while writing received message to temp file");
        }
      }

      close(tempfd);

      {
        char *routekey = (char *)calloc(1, d->routing_key.len + 1);
        strncpy(routekey, (char *)d->routing_key.bytes, d->routing_key.len);

        if(NULL != program) {
          // fork and run the program in the background
          pid_t pid = fork();
          if (pid == 0) {
            if(execl(program, program, program_args, routekey, tempfile, NULL) == -1) {
              perror("Could not execute program");
              exit(EXIT_FAILURE);
            }
          } else {
            status = 0;
            wait(&status);
          }
        } else {
          // print to stdout & flush.
          printf("%s %s\n", routekey, tempfile);
          fflush(stdout);
        }
        free(routekey);
      }

      // send ack on successful processing of the frame
      if((0 == status) && (0 == no_ack))
        amqp_basic_ack(conn, frame.channel, d->delivery_tag, 0);


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

  die_on_amqp_error(amqp_channel_close(conn, AMQP_CHANNEL, AMQP_REPLY_SUCCESS), "Closing channel");
  die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
  die_on_error(amqp_destroy_connection(conn), "Ending connection");

  return 0;
}
示例#22
0
/* Threads */
void *janus_rmq_in_thread(void *data) {
	if(rmq_client == NULL) {
		JANUS_LOG(LOG_ERR, "No RabbitMQ connection??\n");
		return NULL;
	}
	JANUS_LOG(LOG_VERB, "Joining RabbitMQ in thread\n");

	struct timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 20000;
	amqp_frame_t frame;
	while(!rmq_client->destroy && !g_atomic_int_get(&stopping)) {
		amqp_maybe_release_buffers(rmq_client->rmq_conn);
		/* Wait for a frame */
		int res = amqp_simple_wait_frame_noblock(rmq_client->rmq_conn, &frame, &timeout);
		if(res != AMQP_STATUS_OK) {
			/* No data */
			if(res == AMQP_STATUS_TIMEOUT)
				continue;
			JANUS_LOG(LOG_VERB, "Error on amqp_simple_wait_frame_noblock: %d (%s)\n", res, amqp_error_string2(res));
			break;
		}
		/* We expect method first */
		JANUS_LOG(LOG_VERB, "Frame type %d, channel %d\n", frame.frame_type, frame.channel);
		if(frame.frame_type != AMQP_FRAME_METHOD)
			continue;
		JANUS_LOG(LOG_VERB, "Method %s\n", amqp_method_name(frame.payload.method.id));
		gboolean admin = FALSE;
		if(frame.payload.method.id == AMQP_BASIC_DELIVER_METHOD) {
			amqp_basic_deliver_t *d = (amqp_basic_deliver_t *)frame.payload.method.decoded;
			JANUS_LOG(LOG_VERB, "Delivery #%u, %.*s\n", (unsigned) d->delivery_tag, (int) d->routing_key.len, (char *) d->routing_key.bytes);
			/* Check if this is a Janus or Admin API request */
			if(rmq_client->admin_api_enabled) {
				if(d->routing_key.len == rmq_client->to_janus_admin_queue.len) {
					size_t i=0;
					admin = TRUE;
					char *inq = (char *)d->routing_key.bytes;
					char *expq = (char *)rmq_client->to_janus_admin_queue.bytes;
					for(i=0; i< d->routing_key.len; i++) {
						if(inq[i] != expq[i]) {
							admin = FALSE;
							break;
						}
					}
				}
			}
			JANUS_LOG(LOG_VERB, "  -- This is %s API request\n", admin ? "an admin" : "a Janus");
		}
		/* Then the header */
		amqp_simple_wait_frame(rmq_client->rmq_conn, &frame);
		JANUS_LOG(LOG_VERB, "Frame type %d, channel %d\n", frame.frame_type, frame.channel);
		if(frame.frame_type != AMQP_FRAME_HEADER)
			continue;
		amqp_basic_properties_t *p = (amqp_basic_properties_t *)frame.payload.properties.decoded;
		if(p->_flags & AMQP_BASIC_REPLY_TO_FLAG) {
			JANUS_LOG(LOG_VERB, "  -- Reply-to: %.*s\n", (int) p->reply_to.len, (char *) p->reply_to.bytes);
		}
		char *correlation = NULL;
		if(p->_flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
			correlation = g_malloc0(p->correlation_id.len+1);
			sprintf(correlation, "%.*s", (int) p->correlation_id.len, (char *) p->correlation_id.bytes);
			JANUS_LOG(LOG_VERB, "  -- Correlation-id: %s\n", correlation);
		}
		if(p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
			JANUS_LOG(LOG_VERB, "  -- Content-type: %.*s\n", (int) p->content_type.len, (char *) p->content_type.bytes);
		}
		/* And the body */
		uint64_t total = frame.payload.properties.body_size, received = 0;
		char *payload = g_malloc0(total+1), *index = payload;
		while(received < total) {
			amqp_simple_wait_frame(rmq_client->rmq_conn, &frame);
			JANUS_LOG(LOG_VERB, "Frame type %d, channel %d\n", frame.frame_type, frame.channel);
			if(frame.frame_type != AMQP_FRAME_BODY)
				break;
			sprintf(index, "%.*s", (int) frame.payload.body_fragment.len, (char *) frame.payload.body_fragment.bytes);
			received += frame.payload.body_fragment.len;
			index = payload+received;
		}
		JANUS_LOG(LOG_VERB, "Got %"SCNu64"/%"SCNu64" bytes from the %s queue (%"SCNu64")\n",
			received, total, admin ? "admin API" : "Janus API", frame.payload.body_fragment.len);
		JANUS_LOG(LOG_VERB, "%s\n", payload);
		/* Parse the JSON payload */
		json_error_t error;
		json_t *root = json_loads(payload, 0, &error);
		g_free(payload);
		/* Notify the core, passing both the object and, since it may be needed, the error
		 * We also specify the correlation ID as an opaque request identifier: we'll need it later */
		gateway->incoming_request(&janus_rabbitmq_transport, rmq_session, correlation, admin, root, &error);
	}
	JANUS_LOG(LOG_INFO, "Leaving RabbitMQ in thread\n");
	return NULL;
}
示例#23
0
static void run ( amqp_connection_state_t conn, int log_fd , const char *result_routing_key )
{
    int received = 0;
    amqp_frame_t frame;

    while ( 1 )
    {
        amqp_rpc_reply_t ret;
        amqp_envelope_t envelope;

        amqp_maybe_release_buffers ( conn );
        ret = amqp_consume_message ( conn, &envelope, NULL, 0 );

        if ( AMQP_RESPONSE_NORMAL == ret.reply_type )
        {
            int i;
            amqp_bytes_t body = envelope.message.body;
            const char *title = "A new message received:\n";

            fprintf ( stdout, title, received );
            for ( i = 0; i < body.len; i++ )
            {
                fprintf ( stdout, "%c", * ( char* ) ( body.bytes + i ) );
            }
            puts ( "\n" );

            write ( log_fd, ( void * ) title, strlen ( title ) );
            write ( log_fd, body.bytes, body.len );
            write ( log_fd, ( void * ) "\n\n", 2 );

	    /* Send a reply. */
            amqp_basic_properties_t props;
            props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG  | AMQP_BASIC_MESSAGE_ID_FLAG;
	    
	    printf("message id: %s", (const char*)envelope.message.properties.message_id.bytes);
	    
            props.message_id = amqp_bytes_malloc_dup ( envelope.message.properties.message_id );
            props.content_type = amqp_cstring_bytes ( "text/json" );
            props.delivery_mode = 2; /* persistent delivery mode */

            const char *result_body = "{\"IsException\": false, \"Result\": [{\"IsException\": false, \"Result\": []}]}";

            die_on_error ( amqp_basic_publish ( conn,
                                                1,
                                                amqp_cstring_bytes ( "" ),
                                                amqp_cstring_bytes ( result_routing_key ),
                                                0,
                                                0,
                                                &props,
                                                amqp_cstring_bytes ( result_body ) ),
			   "Publishing" );

            amqp_destroy_envelope ( &envelope );
        }
        else
        {
            if ( AMQP_RESPONSE_LIBRARY_EXCEPTION == ret.reply_type &&
                    AMQP_STATUS_UNEXPECTED_STATE == ret.library_error )
            {
                if ( AMQP_STATUS_OK != amqp_simple_wait_frame ( conn, &frame ) )
                {
                    return;
                }

                if ( AMQP_FRAME_METHOD == frame.frame_type )
                {
                    switch ( frame.payload.method.id )
                    {
                    case AMQP_BASIC_ACK_METHOD:
                        /* if we've turned publisher confirms on, and we've published a message
                         * here is a message being confirmed
                         */

                        break;
                    case AMQP_BASIC_RETURN_METHOD:
                        /* if a published message couldn't be routed and the mandatory flag was set
                         * this is what would be returned. The message then needs to be read.
                         */
                    {
                        amqp_message_t message;
                        ret = amqp_read_message ( conn, frame.channel, &message, 0 );

                        if ( AMQP_RESPONSE_NORMAL != ret.reply_type )
                        {
                            return;
                        }

                        amqp_destroy_message ( &message );
                    }

                    break;

                    case AMQP_CHANNEL_CLOSE_METHOD:
                        /* a channel.close method happens when a channel exception occurs, this
                         * can happen by publishing to an exchange that doesn't exist for example
                         *
                         * In this case you would need to open another channel redeclare any queues
                         * that were declared auto-delete, and restart any consumers that were attached
                         * to the previous channel
                         */
                        return;

                    case AMQP_CONNECTION_CLOSE_METHOD:
                        /* a connection.close method happens when a connection exception occurs,
                         * this can happen by trying to use a channel that isn't open for example.
                         *
                         * In this case the whole connection must be restarted.
                         */
                        return;

                    default:
                        fprintf ( stderr ,"An unexpected method was received %d\n", frame.payload.method.id );
                        return;
                    }
                }
            }

        }

        received++;
    }
}
示例#24
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;
}
示例#25
0
int main(int argc, char const *const *argv)
{
  char const *hostname;
  int port, status;
  char const *queuename;
  amqp_socket_t *socket;
  amqp_connection_state_t conn;

  if (argc < 4) {
    fprintf(stderr, "Usage: amqps_listenq host port queuename "
            "[cacert.pem [key.pem cert.pem]]\n");
    return 1;
  }

  hostname = argv[1];
  port = atoi(argv[2]);
  queuename = argv[3];

  conn = amqp_new_connection();

  socket = amqp_ssl_socket_new();
  if (!socket) {
    die("creating SSL/TLS socket");
  }

  if (argc > 4) {
    status = amqp_ssl_socket_set_cacert(socket, argv[4]);
    if (status) {
      die("setting CA certificate");
    }
  }

  if (argc > 6) {
    status = amqp_ssl_socket_set_key(socket, argv[6], argv[5]);
    if (status) {
      die("setting client cert");
    }
  }

  status = amqp_socket_open(socket, hostname, port);
  if (status) {
    die("opening SSL/TLS connection");
  }

  amqp_set_socket(conn, socket);
  die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, "guest", "guest"),
                    "Logging in");
  amqp_channel_open(conn, 1);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

  amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), amqp_empty_bytes, 0, 0, 0, amqp_empty_table);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

  {
    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;
        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;
      }

      amqp_basic_ack(conn, 1, d->delivery_tag, 0);
    }
  }

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

  return 0;
}
示例#26
0
int main(int argc, char const * const *argv) {
    char const *hostname;
    int port;
    char const *queuename;
    char const *amqp_user;
    char const *amqp_passwd;
    amqp_frame_t frame;
    int result;
    char *ret = NULL;

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

    int sockfd;
    amqp_connection_state_t conn;

    if (argc < 6) {
        fprintf(stderr, "Usage: amqp_listenq host port queuename user password\n");
        return 1;
    }

    hostname = argv[1];
    port = atoi(argv[2]);
    queuename = argv[3];
    amqp_user = argv[4];
    amqp_passwd = argv[5];

    conn = amqp_new_connection();

    ads_utils_error(sockfd = amqp_open_socket(hostname, port), "Opening socket");
    amqp_set_sockfd(conn, sockfd);
    ads_utils_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, amqp_user, 
                amqp_passwd), "Logging in");
    amqp_channel_open(conn, 1);
    ads_utils_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

    amqp_basic_consume(conn, 1, amqp_cstring_bytes(queuename), AMQP_EMPTY_BYTES, 0, 0, 0, AMQP_EMPTY_TABLE);
    ads_utils_amqp_error(amqp_get_rpc_reply(conn), "Consuming");

    amqp_maybe_release_buffers(conn);
    result = amqp_simple_wait_frame(conn, &frame);
    if (result < 0)
        exit(0);

    if (frame.frame_type != AMQP_FRAME_METHOD) 
        exit(0);

    if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
    exit(0);

    d = (amqp_basic_deliver_t *) frame.payload.method.decoded;

    result = amqp_simple_wait_frame(conn, &frame);
    if (result < 0)
        exit(0);

    if (frame.frame_type != AMQP_FRAME_HEADER) {
        fprintf(stderr, "Expected header!");
        return 1;
    }
    p = (amqp_basic_properties_t *) frame.payload.properties.decoded;

    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!");
            return 1;
        }

        body_received += frame.payload.body_fragment.len;
        assert(body_received <= body_target);

        ret = ads_utils_amqp_dump(frame.payload.body_fragment.bytes,
        frame.payload.body_fragment.len);
        printf("%s\n", ret);
        free(ret);
    }

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

    amqp_basic_ack(conn, 1, d->delivery_tag, 0);

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

    return 0;
}
示例#27
0
文件: rpc.c 项目: AJStubzy/zentyal
void rpc_run(struct status *status)
{
    int ret;

    DEBUG(2, ("[*] Running RPC command\n"));

    /* Init command control */
    if (!control_init(status)) {
        return;
    }

    /* Enter control loop */
    while (rpc_check_run_flag(status)) {
        amqp_rpc_reply_t    result;
        amqp_envelope_t     envelope;
        amqp_basic_properties_t response_header;
        amqp_bytes_t        response_body;

        response_header._flags = 0;
        amqp_maybe_release_buffers(status->conn);
        result = amqp_consume_message(status->conn, &envelope, NULL, 0);
        if (result.reply_type != AMQP_RESPONSE_NORMAL) {
            if (AMQP_RESPONSE_LIBRARY_EXCEPTION == result.reply_type &&
                AMQP_STATUS_UNEXPECTED_STATE == result.library_error)
            {
                amqp_frame_t    frame;

                if (AMQP_STATUS_OK != amqp_simple_wait_frame(status->conn, &frame)) {
                    DEBUG(0, ("[!] Error consuming message\n"));
                    control_abort(status);
                    break;
                }
                if (AMQP_FRAME_METHOD == frame.frame_type) {
                    switch (frame.payload.method.id) {
                    case AMQP_BASIC_ACK_METHOD:
                        /* if we've turned publisher confirms on, and we've published a message
                         * here is a message being confirmed
                         */
                        break;
                    case AMQP_BASIC_RETURN_METHOD:
                        /* if a published message couldn't be routed and the mandatory flag was set
                         * this is what would be returned. The message then needs to be read.
                         */
                    {
                        amqp_message_t  message;

                        result = amqp_read_message(status->conn, frame.channel, &message, 0);
                        if (AMQP_RESPONSE_NORMAL != result.reply_type) {
                            control_abort(status);
                            return;
                        }
                        amqp_destroy_message(&message);
                    }
                    break;
                    case AMQP_CHANNEL_CLOSE_METHOD:
                        /* a channel.close method happens when a channel exception occurs, this
                         * can happen by publishing to an exchange that doesn't exist for example
                         *
                         * In this case you would need to open another channel redeclare any queues
                         * that were declared auto-delete, and restart any consumers that were attached
                         * to the previous channel
                         */
                        return;
                    case AMQP_CONNECTION_CLOSE_METHOD:
                        /* a connection.close method happens when a connection exception occurs,
                         * this can happen by trying to use a channel that isn't open for example.
                         *
                         * In this case the whole connection must be restarted.
                         */
                        return;
                    default:
                        DEBUG(0, ("[!] An unexpected method was received %d\n", frame.payload.method.id));
                        return;
                    }
                    continue;
                }
                continue;
            }
            DEBUG(0, ("[!] Error consuming message\n"));
            control_abort(status);
            break;
        }

        DEBUG(2, ("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) {
            DEBUG(2, ("Content-type: %.*s\n",
                  (int) envelope.message.properties.content_type.len,
                  (char *) envelope.message.properties.content_type.bytes));
        }
        if (envelope.message.properties._flags & AMQP_BASIC_REPLY_TO_FLAG) {
            response_header._flags |= AMQP_BASIC_REPLY_TO_FLAG;
            response_header.reply_to = amqp_bytes_malloc_dup(envelope.message.properties.reply_to);
            DEBUG(2, ("Reply-to: %.*s\n",
                  (int) envelope.message.properties.reply_to.len,
                  (char *) envelope.message.properties.reply_to.bytes));
        }
        if (envelope.message.properties._flags & AMQP_BASIC_CORRELATION_ID_FLAG) {
            response_header._flags |= AMQP_BASIC_CORRELATION_ID_FLAG;
            response_header.correlation_id = amqp_bytes_malloc_dup(envelope.message.properties.correlation_id);
            DEBUG(2, ("Correlation-id: %.*s\n",
                  (int) envelope.message.properties.correlation_id.len,
                  (char *) envelope.message.properties.correlation_id.bytes));
        }

        /* Handle the request */
        response_body = control_handle(status, envelope.message.body);
        DEBUG(2, ("[*] Sending response '%s'\n", (char*)response_body.bytes));

        /* Send the response */
        response_header._flags |= AMQP_BASIC_CONTENT_TYPE_FLAG;
        response_header.content_type = amqp_cstring_bytes("text/plain");

        response_header._flags |= AMQP_BASIC_DELIVERY_MODE_FLAG;
        response_header.delivery_mode = 1;
        ret = amqp_basic_publish(status->conn, 1,
                     amqp_empty_bytes,
                     amqp_bytes_malloc_dup(envelope.message.properties.reply_to),
                     0, /* Mandatory */
                     0, /* Inmediate */
                     &response_header,
                     response_body);
        if (ret != AMQP_STATUS_OK) {
            DEBUG(0, ("[!] Error publishing command response: %s\n", amqp_error_string2(ret)));
        }

        //* Free memory */
        amqp_destroy_envelope(&envelope);
    }

    /* Clean up control */
    control_free(status);
}
示例#28
0
unsigned int rmq_receive()
{
  pwr_tStatus sts;
  int search_remtrans = 0;
  remtrans_item* remtrans;
  amqp_rpc_reply_t ret;
  amqp_envelope_t envelope;
  struct timeval t = { 2, 0 };
  rabbit_header header;
  int msg_received = 0;

  amqp_maybe_release_buffers(ctx->conn);
  ret = amqp_consume_message(ctx->conn, &envelope, &t, 0);
  switch (ret.reply_type) {
  case AMQP_RESPONSE_NORMAL: {
    break;
  }
  case AMQP_RESPONSE_NONE:
    return REM__SUCCESS;
  case AMQP_RESPONSE_SERVER_EXCEPTION:
    return REM__EXCEPTION;
  case AMQP_RESPONSE_LIBRARY_EXCEPTION:
    switch (ret.library_error) {
    case AMQP_STATUS_TIMEOUT: {
      amqp_destroy_envelope(&envelope);
      return REM__TIMEOUT;
    }
    case AMQP_STATUS_UNEXPECTED_STATE: {
      amqp_frame_t frame;

      sts = amqp_simple_wait_frame_noblock(ctx->conn, &frame, &t);
      if (sts == AMQP_STATUS_TIMEOUT) {
        printf("Wait frame timeout\n");
        return REM__EXCEPTION;
      } else if (sts == AMQP_STATUS_OK) {
        if (frame.frame_type == AMQP_FRAME_METHOD) {
          switch (frame.payload.method.id) {
          case AMQP_BASIC_ACK_METHOD:
            printf("Basic ack method called\n");
            break;
          case AMQP_BASIC_RETURN_METHOD:
            printf("Basic return method called\n");
            break;
          case AMQP_CHANNEL_CLOSE_METHOD:
            printf("Channel close method called\n");
            break;
          case AMQP_CONNECTION_CLOSE_METHOD:
            printf("Connection close method called\n");
            break;
          default:;
          }
        }
        return REM__EXCEPTION;
      } else
        return REM__EXCEPTION;
    }
    }
    // Reconnect...
    rmq_close(1);
    return REM__EXCEPTION;
  default:
    printf("Unknown Reply type: %d\n", ret.reply_type);
  }

  if (debug)
    printf("Received message %d\n", (int)envelope.message.body.len);

  if (envelope.message.body.len > 0 && rn_rmq->DisableHeader) {
    /* Header disabled, take the first receive remtrans object */

    remtrans = rn.remtrans;
    search_remtrans = 1;

    while (remtrans && search_remtrans) {
      /* Match? */
      if (remtrans->objp->Direction == REMTRANS_IN) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans, (char*)envelope.message.body.bytes,
            envelope.message.body.len);
        msg_received = 1;
      }
      remtrans = (remtrans_item*)remtrans->next;
    }
    if (search_remtrans) {
      rn_rmq->ErrCount++;
      errh_Info("RabbitMQ Receive no remtrans %s", rn_rmq->ReceiveQueue);
    }
  } else if (envelope.message.body.len >= sizeof(rabbit_header)) {
    memcpy(&header, envelope.message.body.bytes, sizeof(rabbit_header));

    /* Convert the header to host byte order */
    header.msg_size = ntohs(header.msg_size);
    header.msg_id[0] = ntohs(header.msg_id[0]);
    header.msg_id[1] = ntohs(header.msg_id[1]);

    search_remtrans = 1;
    remtrans = rn.remtrans;
    while (remtrans && search_remtrans) {
      if (remtrans->objp->Address[0] == header.msg_id[0]
          && remtrans->objp->Address[1] == header.msg_id[1]
          && remtrans->objp->Direction == REMTRANS_IN) {
        search_remtrans = false;
        sts = RemTrans_Receive(remtrans,
            (char*)envelope.message.body.bytes + sizeof(rabbit_header),
            envelope.message.body.len);
        if (sts != STATUS_OK && sts != STATUS_BUFF)
          errh_Error("Error from RemTrans_Receive, queue %s, status %d",
              rn_rmq->ReceiveQueue, sts, 0);
        msg_received = 1;
        break;
      }
      remtrans = (remtrans_item*)remtrans->next;
    }
    if (search_remtrans) {
      rn_rmq->ErrCount++;
      errh_Info("No remtrans for received message, queue %s, class %d, type %d",
          rn_rmq->ReceiveQueue, header.msg_id[0], header.msg_id[1]);
    }
  }

  if (ctx->op->Acknowledge) {
    if (msg_received)
      amqp_basic_ack(ctx->conn, ctx->channel, envelope.delivery_tag, 0);
    else
      /* Requeue the message */
      amqp_basic_nack(ctx->conn, ctx->channel, envelope.delivery_tag, 0, 1);
  }
  amqp_destroy_envelope(&envelope);

  return sts;
}