Example #1
0
char *consume_message(amqp_connection_state_t connection_state_,
                      const char *queue_name_, uint64_t *out_body_size_) {
  amqp_basic_consume_ok_t *result =
      amqp_basic_consume(connection_state_, fixed_channel_id,
                         amqp_cstring_bytes(queue_name_), amqp_empty_bytes,
                         /*no_local*/ 0,
                         /*no_ack*/ 1,
                         /*exclusive*/ 0, amqp_empty_table);
  assert(result != NULL);

  amqp_envelope_t envelope;
  struct timeval timeout = { 5, 0 };
  amqp_rpc_reply_t rpc_reply =
      amqp_consume_message(connection_state_, &envelope, &timeout, 0);
  assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL);

  *out_body_size_ = envelope.message.body.len;
  char *body = malloc(*out_body_size_);
  if (*out_body_size_) {
    memcpy(body, envelope.message.body.bytes, *out_body_size_);
  }

  amqp_destroy_envelope(&envelope);
  return body;
}
Example #2
0
bool rpc_open(struct status *status)
{
    bool retval = false;
    int ret = 0;

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

    /* Adquire lock */
    ret = pthread_spin_lock(&status->lock);
    if (ret) {
        fprintf(stderr, "[!] pthread_spin_lock: %s\n", strerror(ret));
        return false;
    }

    /* Open connection */
    status->conn = get_amqp_connection();
    if (!status->conn) {
        retval = false;
        goto unlock;
    }

    /* Declare the control queue */
    amqp_queue_declare(status->conn,
               1, /* Channel */
               amqp_cstring_bytes("Zentyal.OpenChange.Migrate.Control"),
               0, /* Passive */
               0, /* Durable */
               1, /* Exclusive */
               1, /* Auto delete */
               amqp_empty_table);
    if (amqp_get_rpc_reply(status->conn).reply_type != AMQP_RESPONSE_NORMAL) {
        fprintf(stderr, "[!] Error declaring queue\n");
        retval = false;
        goto unlock;
    }

    /* Start the consumer */
    amqp_basic_consume(status->conn, 1,
               amqp_cstring_bytes("Zentyal.OpenChange.Migrate.Control"), /* Queue */
               amqp_cstring_bytes("Zentyal.OpenChange.Migrate.Control"), /* Tag */
               0,  /* no local */
               1,  /* no ack */
               0,  /* exclusive */
               amqp_empty_table);
    if (amqp_get_rpc_reply(status->conn).reply_type != AMQP_RESPONSE_NORMAL) {
        fprintf(stderr, "[!] Error starting consumer\n");
        retval = false;
        goto unlock;
    }

    retval = true;

unlock:
    /* Release lock */
    pthread_spin_unlock(&status->lock);

    return retval;
}
Example #3
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 < 3) {
    fprintf(stderr, "Usage: amqp_consumer host port\n");
    return 1;
  }

  hostname = argv[1];
  port = atoi(argv[2]);
  exchange = "amq.direct"; /* argv[3]; */
  bindingkey = "test queue"; /* 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) {
      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");

  run(conn);

  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;
}
bool initAmqp(amqp_connection_state_t &conn, amqp_socket_t *socket, int &status, amqp_bytes_t &queuename) {
	conn = amqp_new_connection();

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

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

	if (!die_on_amqp_error(amqp_login(conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, amqp_user, amqp_pass), "Logging in")) {
		return false;
	};
	amqp_channel_open(conn, 1);
	if (!die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel")) {
		return false;
	}

	// passive 0 durable 1 auto-delete 0 internal 0 exchange
	amqp_exchange_declare_ok_t_ *er = amqp_exchange_declare(conn, 1, amqp_cstring_bytes(exchange), amqp_cstring_bytes(exchange_type), 0, 1, 0, 0, amqp_empty_table);
	if (!die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring exchange")) {
		return false;
	}

	// passive 0 durable 1 exclusive 0 auto-delete 0 queue
	amqp_queue_declare_ok_t *r = amqp_queue_declare(conn, 1, amqp_cstring_bytes(bindingkey), 0, 1, 0, 0, amqp_empty_table);
	if (!die_on_amqp_error(amqp_get_rpc_reply(conn), "Declaring queue")) {
		return false;
	}
	queuename = amqp_bytes_malloc_dup(r->queue);
	if (queuename.bytes == NULL) {
	  fprintf(stderr, "Out of memory while copying queue name");
	  return false;
	}

	amqp_queue_bind(conn, 1, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(bindingkey), amqp_empty_table);
	if (!die_on_amqp_error(amqp_get_rpc_reply(conn), "Binding queue")) {
		return false;
	}

	// no-local 0 no-ack 0 exclusive 0 consumer
	amqp_basic_consume(conn, 1, queuename, amqp_cstring_bytes(consumer_name), 1, 0, 0, amqp_empty_table);
	if (!die_on_amqp_error(amqp_get_rpc_reply(conn), "Consuming")) {
		return false;
	}
	
	return true;
}
void
RabbitMQConnection::consumeQueue (const std::string &queue_name,
                                  const std::string &tag)
{
  amqp_bytes_t queue = amqp_cstring_bytes (queue_name.c_str() );
  amqp_bytes_t tag_id = amqp_cstring_bytes (tag.c_str() );

  amqp_basic_consume (conn, 1, queue, tag_id, /* no_local */ false,
                      /* no_ack */ false, /* exclusive */ false,
                      amqp_empty_table);
  exception_on_error (amqp_get_rpc_reply (conn), "Consuming");
}
Example #6
0
	void MQChannel::BasicConsume(const std::string &queue, const std::string &tag,
		bool noLocal, bool noAck, bool exclusive, amqp_table_t args)
	{
		amqp_basic_consume(
			mConn,
			mChannel,
			amqp_cstring_bytes(queue.c_str()),
			amqp_cstring_bytes(tag.c_str()),
			noLocal,
			noAck,
			exclusive,
			args);
	}
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");
}
Example #8
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 RabbitInBoundConnectionPoint::ConnectPoint() throw (ConnectException)
			{
				ConnectRabbit();

				amqp_exchange_declare(_conn, 1, amqp_cstring_bytes(_exchange), amqp_cstring_bytes(_exchangetype),
						0, 1, amqp_empty_table);
				GetRabbitError("Declaracion Exchange");

				amqp_queue_declare(_conn, 1, amqp_cstring_bytes(_queue), 0, 1, 0, 0, amqp_empty_table);
				GetRabbitError("Declaracion Queue");

				amqp_queue_bind(_conn, 1, amqp_cstring_bytes(_queue), amqp_cstring_bytes(_exchange), amqp_cstring_bytes(_routingKey),
				  amqp_empty_table);
				GetRabbitError("Binding Queue");

				amqp_basic_consume(_conn, 1, amqp_cstring_bytes(_queue), amqp_empty_bytes, 0, 0, 0, amqp_empty_table);
				GetRabbitError("Binding Queue");
			}
Example #10
0
eSquere * eSquere::Consume(std::string qname){
    if(this->IsError()) return this;
// amqp_basic_consume(
//    amqp_connection_state_t state, 
//    amqp_channel_t channel, 
//    amqp_bytes_t queue, 
//    amqp_bytes_t consumer_tag, 
//    amqp_boolean_t no_local, 
//    amqp_boolean_t no_ack, 
//    amqp_boolean_t exclusive, 
//    amqp_table_t arguments);    
    amqp_basic_consume(
            this->connect, 
            1, 
            amqp_cstring_bytes(qname.c_str()), 
            amqp_empty_bytes, 
            0, 
            0, 
            0, 
            amqp_empty_table);
    return this->ErrorRPC("Consuming "+qname);
    
}
Example #11
0
int main ( int argc, char const *const *argv )
{
    if ( argc != 3 )
    {
        printf ( "usage: %s CFG_FILE LOG_FILE\n", argv[0] );

        return -1;
    }

    const char *log_filename = argv[2];
    int flags = O_CREAT | O_APPEND | O_RDWR;
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
    int log_fd = open ( log_filename, flags, mode );

    if ( log_fd < 0 )
    {
        fprintf ( stderr, "ERROR: Falied to open the log file '%s'\n", log_filename );

        exit ( 1 );
    }

    /* Read the configuration file. */
    struct lcfg *cfg = lcfg_new ( argv[1] );

    if ( lcfg_parse ( cfg ) != lcfg_status_ok )
    {
        printf ( "lcfg error: %s\n", lcfg_error_get ( cfg ) );

        return -1;
    }

    /* Read all the configuration parameters. */
    fprintf ( stdout, "Starting Murano agent with the following configuration:\n\n" );

    const char *host = get_config_value ( cfg, "RABBITMQ_HOST" , 1 );
    int port = atoi ( get_config_value ( cfg, "RABBITMQ_PORT" , 1 ) );
    const char *vhost = get_config_value ( cfg, "RABBITMQ_VHOST"  , 1 );
    const char *username = get_config_value ( cfg, "RABBITMQ_USERNAME"  , 1 );
    const char *password = get_config_value ( cfg, "RABBITMQ_PASSWORD"  , 1 );
    const char *queuename = get_config_value ( cfg, "RABBITMQ_INPUT_QUEUE"  , 1 );
    const char *result_routing_key = get_config_value ( cfg, "RABBITMQ_RESULT_ROUTING_KEY", 1 );

    amqp_connection_state_t conn = amqp_new_connection();
    amqp_socket_t *socket = NULL;
    amqp_bytes_t queuename_bytes = amqp_cstring_bytes ( queuename );

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

    if ( amqp_socket_open ( socket, host, port ) )
    {
        die ( "opening TCP socket" );
    }

    die_on_amqp_error ( amqp_login ( conn, vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, username, password ),
                        "Logging in" );
    amqp_channel_open ( conn, 1 );
    die_on_amqp_error ( amqp_get_rpc_reply ( conn ), "Opening channel" );

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

    puts ( "\nSuccessfully connected to Rabbit MQ server! Ready for messages..." );

    run ( conn, log_fd , result_routing_key );

    close ( log_fd );
    lcfg_delete ( cfg );

    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;
}
Example #12
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;
}
Example #13
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;
}
Example #14
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;
}
int main(int argc, char const *const *argv)
{
  char const *hostname;
  int port, status;
  char const *exchange;
  char const *bindingkey;
  amqp_socket_t *socket;
  amqp_connection_state_t conn;
  amqp_bytes_t queuename;

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

  hostname = argv[1];
  port = atoi(argv[2]);
  exchange = "amq.direct"; /* argv[3]; */
  bindingkey = "test queue"; /* argv[4]; */

  conn = amqp_new_connection();

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

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

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

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

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

  run(conn);

  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;
}
Example #16
0
/* Transport implementation */
int janus_rabbitmq_init(janus_transport_callbacks *callback, const char *config_path) {
	if(g_atomic_int_get(&stopping)) {
		/* Still stopping from before */
		return -1;
	}
	if(callback == NULL || config_path == NULL) {
		/* Invalid arguments */
		return -1;
	}

	/* This is the callback we'll need to invoke to contact the Janus core */
	gateway = callback;

	/* Read configuration */
	char filename[255];
	g_snprintf(filename, 255, "%s/%s.jcfg", config_path, JANUS_RABBITMQ_PACKAGE);
	JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
	janus_config *config = janus_config_parse(filename);
	if(config == NULL) {
		JANUS_LOG(LOG_WARN, "Couldn't find .jcfg configuration file (%s), trying .cfg\n", JANUS_RABBITMQ_PACKAGE);
		g_snprintf(filename, 255, "%s/%s.cfg", config_path, JANUS_RABBITMQ_PACKAGE);
		JANUS_LOG(LOG_VERB, "Configuration file: %s\n", filename);
		config = janus_config_parse(filename);
	}
	if(config != NULL)
		janus_config_print(config);
	janus_config_category *config_general = janus_config_get_create(config, NULL, janus_config_type_category, "general");
	janus_config_category *config_admin = janus_config_get_create(config, NULL, janus_config_type_category, "admin");

	janus_config_item *item = janus_config_get(config, config_general, janus_config_type_item, "json");
	if(item && item->value) {
		/* Check how we need to format/serialize the JSON output */
		if(!strcasecmp(item->value, "indented")) {
			/* Default: indented, we use three spaces for that */
			json_format = JSON_INDENT(3) | JSON_PRESERVE_ORDER;
		} else if(!strcasecmp(item->value, "plain")) {
			/* Not indented and no new lines, but still readable */
			json_format = JSON_INDENT(0) | JSON_PRESERVE_ORDER;
		} else if(!strcasecmp(item->value, "compact")) {
			/* Compact, so no spaces between separators */
			json_format = JSON_COMPACT | JSON_PRESERVE_ORDER;
		} else {
			JANUS_LOG(LOG_WARN, "Unsupported JSON format option '%s', using default (indented)\n", item->value);
			json_format = JSON_INDENT(3) | JSON_PRESERVE_ORDER;
		}
	}

	/* Check if we need to send events to handlers */
	janus_config_item *events = janus_config_get(config, config_general, janus_config_type_item, "events");
	if(events != NULL && events->value != NULL)
		notify_events = janus_is_true(events->value);
	if(!notify_events && callback->events_is_enabled()) {
		JANUS_LOG(LOG_WARN, "Notification of events to handlers disabled for %s\n", JANUS_RABBITMQ_NAME);
	}

	/* Handle configuration, starting from the server details */
	item = janus_config_get(config, config_general, janus_config_type_item, "host");
	if(item && item->value)
		rmqhost = g_strdup(item->value);
	else
		rmqhost = g_strdup("localhost");
	int rmqport = AMQP_PROTOCOL_PORT;
	item = janus_config_get(config, config_general, janus_config_type_item, "port");
	if(item && item->value)
		rmqport = atoi(item->value);

	/* Credentials and Virtual Host */
	item = janus_config_get(config, config_general, janus_config_type_item, "vhost");
	if(item && item->value)
		vhost = g_strdup(item->value);
	else
		vhost = g_strdup("/");
	item = janus_config_get(config, config_general, janus_config_type_item, "username");
	if(item && item->value)
		username = g_strdup(item->value);
	else
		username = g_strdup("guest");
	item = janus_config_get(config, config_general, janus_config_type_item, "password");
	if(item && item->value)
		password = g_strdup(item->value);
	else
		password = g_strdup("guest");

	/* SSL config*/
	gboolean ssl_enabled = FALSE;
	gboolean ssl_verify_peer = FALSE;
	gboolean ssl_verify_hostname = FALSE;
	item = janus_config_get(config, config_general, janus_config_type_item, "ssl_enabled");
	if(item == NULL) {
		/* Try legacy property */
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_enable");
		if (item && item->value) {
			JANUS_LOG(LOG_WARN, "Found deprecated 'ssl_enable' property, please update it to 'ssl_enabled' instead\n");
		}
	}
	if(!item || !item->value || !janus_is_true(item->value)) {
		JANUS_LOG(LOG_INFO, "RabbitMQ SSL support disabled\n");
	} else {
		ssl_enabled = TRUE;
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_cacert");
		if(item && item->value)
			ssl_cacert_file = g_strdup(item->value);
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_cert");
		if(item && item->value)
			ssl_cert_file = g_strdup(item->value);
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_key");
		if(item && item->value)
			ssl_key_file = g_strdup(item->value);
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_verify_peer");
		if(item && item->value && janus_is_true(item->value))
			ssl_verify_peer = TRUE;
		item = janus_config_get(config, config_general, janus_config_type_item, "ssl_verify_hostname");
		if(item && item->value && janus_is_true(item->value))
			ssl_verify_hostname = TRUE;
	}

	/* Now check if the Janus API must be supported */
	item = janus_config_get(config, config_general, janus_config_type_item, "enabled");
	if(item == NULL) {
		/* Try legacy property */
		item = janus_config_get(config, config_general, janus_config_type_item, "enable");
		if (item && item->value) {
			JANUS_LOG(LOG_WARN, "Found deprecated 'enable' property, please update it to 'enabled' instead\n");
		}
	}
	if(!item || !item->value || !janus_is_true(item->value)) {
		JANUS_LOG(LOG_WARN, "RabbitMQ support disabled (Janus API)\n");
	} else {
		/* Parse configuration */
		item = janus_config_get(config, config_general, janus_config_type_item, "to_janus");
		if(!item || !item->value) {
			JANUS_LOG(LOG_FATAL, "Missing name of incoming queue for RabbitMQ integration...\n");
			goto error;
		}
		to_janus = g_strdup(item->value);
		item = janus_config_get(config, config_general, janus_config_type_item, "from_janus");
		if(!item || !item->value) {
			JANUS_LOG(LOG_FATAL, "Missing name of outgoing queue for RabbitMQ integration...\n");
			goto error;
		}
		from_janus = g_strdup(item->value);
		item = janus_config_get(config, config_general, janus_config_type_item, "janus_exchange");
		if(!item || !item->value) {
			JANUS_LOG(LOG_INFO, "Missing name of outgoing exchange for RabbitMQ integration, using default\n");
		} else {
			janus_exchange = g_strdup(item->value);
		}
		if (janus_exchange == NULL) {
			JANUS_LOG(LOG_INFO, "RabbitMQ support for Janus API enabled, %s:%d (%s/%s)\n", rmqhost, rmqport, to_janus, from_janus);
		} else {
			JANUS_LOG(LOG_INFO, "RabbitMQ support for Janus API enabled, %s:%d (%s/%s) exch: (%s)\n", rmqhost, rmqport, to_janus, from_janus, janus_exchange);
		}
		rmq_janus_api_enabled = TRUE;
	}
	/* Do the same for the admin API */
	item = janus_config_get(config, config_admin, janus_config_type_item, "admin_enabled");
	if(item == NULL) {
		/* Try legacy property */
		item = janus_config_get(config, config_general, janus_config_type_item, "admin_enable");
		if (item && item->value) {
			JANUS_LOG(LOG_WARN, "Found deprecated 'admin_enable' property, please update it to 'admin_enabled' instead\n");
		}
	}
	if(!item || !item->value || !janus_is_true(item->value)) {
		JANUS_LOG(LOG_WARN, "RabbitMQ support disabled (Admin API)\n");
	} else {
		/* Parse configuration */
		item = janus_config_get(config, config_admin, janus_config_type_item, "to_janus_admin");
		if(!item || !item->value) {
			JANUS_LOG(LOG_FATAL, "Missing name of incoming queue for RabbitMQ integration...\n");
			goto error;
		}
		to_janus_admin = g_strdup(item->value);
		item = janus_config_get(config, config_admin, janus_config_type_item, "from_janus_admin");
		if(!item || !item->value) {
			JANUS_LOG(LOG_FATAL, "Missing name of outgoing queue for RabbitMQ integration...\n");
			goto error;
		}
		from_janus_admin = g_strdup(item->value);
		JANUS_LOG(LOG_INFO, "RabbitMQ support for Admin API enabled, %s:%d (%s/%s)\n", rmqhost, rmqport, to_janus_admin, from_janus_admin);
		rmq_admin_api_enabled = TRUE;
	}
	if(!rmq_janus_api_enabled && !rmq_admin_api_enabled) {
		JANUS_LOG(LOG_WARN, "RabbitMQ support disabled for both Janus and Admin API, giving up\n");
		goto error;
	} else {
		/* FIXME We currently support a single application, create a new janus_rabbitmq_client instance */
		rmq_client = g_malloc0(sizeof(janus_rabbitmq_client));
		/* Connect */
		rmq_client->rmq_conn = amqp_new_connection();
		amqp_socket_t *socket = NULL;
		int status;
		JANUS_LOG(LOG_VERB, "Creating RabbitMQ socket...\n");
		if (ssl_enabled) {
			socket = amqp_ssl_socket_new(rmq_client->rmq_conn);
			if(socket == NULL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error creating socket...\n");
				goto error;
			}
			if(ssl_verify_peer) {
				amqp_ssl_socket_set_verify_peer(socket, 1);
			} else {
				amqp_ssl_socket_set_verify_peer(socket, 0);
			}
			if(ssl_verify_hostname) {
				amqp_ssl_socket_set_verify_hostname(socket, 1);
			} else {
				amqp_ssl_socket_set_verify_hostname(socket, 0);
			}
			if(ssl_cacert_file) {
				status = amqp_ssl_socket_set_cacert(socket, ssl_cacert_file);
				if(status != AMQP_STATUS_OK) {
					JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error setting CA certificate... (%s)\n", amqp_error_string2(status));
					goto error;
				}
			}
			if(ssl_cert_file && ssl_key_file) {
				status = amqp_ssl_socket_set_key(socket, ssl_cert_file, ssl_key_file);
				if(status != AMQP_STATUS_OK) {
					JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error setting key... (%s)\n", amqp_error_string2(status));
					goto error;
				}
			}
		} else {
			socket = amqp_tcp_socket_new(rmq_client->rmq_conn);
			if(socket == NULL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error creating socket...\n");
				goto error;
			}
		}
		JANUS_LOG(LOG_VERB, "Connecting to RabbitMQ server...\n");
		status = amqp_socket_open(socket, rmqhost, rmqport);
		if(status != AMQP_STATUS_OK) {
			JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error opening socket... (%s)\n", amqp_error_string2(status));
			goto error;
		}
		JANUS_LOG(LOG_VERB, "Logging in...\n");
		amqp_rpc_reply_t result = amqp_login(rmq_client->rmq_conn, vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, username, password);
		if(result.reply_type != AMQP_RESPONSE_NORMAL) {
			JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error logging in... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
			goto error;
		}
		rmq_client->rmq_channel = 1;
		JANUS_LOG(LOG_VERB, "Opening channel...\n");
		amqp_channel_open(rmq_client->rmq_conn, rmq_client->rmq_channel);
		result = amqp_get_rpc_reply(rmq_client->rmq_conn);
		if(result.reply_type != AMQP_RESPONSE_NORMAL) {
			JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error opening channel... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
			goto error;
		}
		rmq_client->janus_exchange = amqp_empty_bytes;
		if(janus_exchange != NULL) {
			JANUS_LOG(LOG_VERB, "Declaring exchange...\n");
			rmq_client->janus_exchange = amqp_cstring_bytes(janus_exchange);
			amqp_exchange_declare(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->janus_exchange, amqp_cstring_bytes(JANUS_RABBITMQ_EXCHANGE_TYPE), 0, 0, 0, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error diclaring exchange... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
		}
		rmq_client->janus_api_enabled = FALSE;
		if(rmq_janus_api_enabled) {
			rmq_client->janus_api_enabled = TRUE;
			JANUS_LOG(LOG_VERB, "Declaring incoming queue... (%s)\n", to_janus);
			rmq_client->to_janus_queue = amqp_cstring_bytes(to_janus);
			amqp_queue_declare(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->to_janus_queue, 0, 0, 0, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error declaring queue... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
			JANUS_LOG(LOG_VERB, "Declaring outgoing queue... (%s)\n", from_janus);
			rmq_client->from_janus_queue = amqp_cstring_bytes(from_janus);
			amqp_queue_declare(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->from_janus_queue, 0, 0, 0, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error declaring queue... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
			amqp_basic_consume(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->to_janus_queue, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error consuming... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
		}
		rmq_client->admin_api_enabled = FALSE;
		if(rmq_admin_api_enabled) {
			rmq_client->admin_api_enabled = TRUE;
			JANUS_LOG(LOG_VERB, "Declaring incoming queue... (%s)\n", to_janus_admin);
			rmq_client->to_janus_admin_queue = amqp_cstring_bytes(to_janus_admin);
			amqp_queue_declare(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->to_janus_admin_queue, 0, 0, 0, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error declaring queue... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
			JANUS_LOG(LOG_VERB, "Declaring outgoing queue... (%s)\n", from_janus_admin);
			rmq_client->from_janus_admin_queue = amqp_cstring_bytes(from_janus_admin);
			amqp_queue_declare(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->from_janus_admin_queue, 0, 0, 0, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error declaring queue... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
			amqp_basic_consume(rmq_client->rmq_conn, rmq_client->rmq_channel, rmq_client->to_janus_admin_queue, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
			result = amqp_get_rpc_reply(rmq_client->rmq_conn);
			if(result.reply_type != AMQP_RESPONSE_NORMAL) {
				JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error consuming... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id));
				goto error;
			}
		}
		rmq_client->messages = g_async_queue_new();
		rmq_client->destroy = 0;
		/* Prepare the transport session (again, just one) */
		rmq_session = janus_transport_session_create(rmq_client, NULL);
		/* Start the threads */
		GError *error = NULL;
		rmq_client->in_thread = g_thread_try_new("rmq_in_thread", &janus_rmq_in_thread, rmq_client, &error);
		if(error != NULL) {
			/* Something went wrong... */
			JANUS_LOG(LOG_FATAL, "Got error %d (%s) trying to launch the RabbitMQ incoming thread...\n", error->code, error->message ? error->message : "??");
			janus_transport_session_destroy(rmq_session);
			g_free(rmq_client);
			janus_config_destroy(config);
			return -1;
		}
		rmq_client->out_thread = g_thread_try_new("rmq_out_thread", &janus_rmq_out_thread, rmq_client, &error);
		if(error != NULL) {
			/* Something went wrong... */
			JANUS_LOG(LOG_FATAL, "Got error %d (%s) trying to launch the RabbitMQ outgoing thread...\n", error->code, error->message ? error->message : "??");
			janus_transport_session_destroy(rmq_session);
			g_free(rmq_client);
			janus_config_destroy(config);
			return -1;
		}
		janus_mutex_init(&rmq_client->mutex);
		/* Done */
		JANUS_LOG(LOG_INFO, "Setup of RabbitMQ integration completed\n");
		/* Notify handlers about this new transport */
		if(notify_events && gateway->events_is_enabled()) {
			json_t *info = json_object();
			json_object_set_new(info, "event", json_string("connected"));
			gateway->notify_event(&janus_rabbitmq_transport, rmq_session, info);
		}
	}
	janus_config_destroy(config);
	config = NULL;

	/* Done */
	g_atomic_int_set(&initialized, 1);
	JANUS_LOG(LOG_INFO, "%s initialized!\n", JANUS_RABBITMQ_NAME);
	return 0;

error:
	/* If we got here, something went wrong */
	g_free(rmq_client);
	g_free(rmqhost);
	g_free(vhost);
	g_free(username);
	g_free(password);
	g_free(janus_exchange);
	g_free(to_janus);
	g_free(from_janus);
	g_free(to_janus_admin);
	g_free(from_janus_admin);
	g_free(ssl_cacert_file);
	g_free(ssl_cert_file);
	g_free(ssl_key_file);
	if(config)
		janus_config_destroy(config);
	return -1;
}
Example #17
0
int createMsgClient(MsgServerConf_t *conf, MsgReceiver_t **receiver) {
    int status = 0;
    MsgReceiver_t *handle;
    amqp_rpc_reply_t reply;
    amqp_queue_declare_ok_t *queue_status;
    char queue_name[CREDENTIAL_MAX_LEN];
    
    status = _checkConf(conf);
    if(status != 0) {
        LOG4CXX_ERROR(logger, "createMsgClient: connection configuration check failed");
        return status;
    }
    
    if(receiver == NULL) {
        LOG4CXX_ERROR(logger, "createMsgClient: receiver is null");
        return EINVAL;
    }
    
    *receiver = NULL;
    
    handle = (MsgReceiver_t *)calloc(1, sizeof(MsgReceiver_t));
    if(handle == NULL) {
        LOG4CXX_ERROR(logger, "createMsgClient: not enough memory to allocate");
        return ENOMEM;
    }
    
    memcpy(&handle->conf, conf, sizeof(MsgServerConf_t));
    handle->thread_run = false;
    
    LOG4CXX_DEBUG(logger, "createMsgClient: creating a TCP connection to " << conf->hostname);
    
    // create a TCP connection
    handle->conn_state = amqp_new_connection();
    handle->socket = amqp_tcp_socket_new(handle->conn_state);
    if(handle->socket == NULL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to create a connection");
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    // open a socket
    status = amqp_socket_open(handle->socket, conf->hostname, conf->port);
    if(status != 0) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to create a TCP connection to " << conf->hostname);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    LOG4CXX_DEBUG(logger, "createMsgClient: logging in with " << conf->user_id);
    
    // login
    reply = amqp_login(handle->conn_state, conf->vhost, 0, AMQP_DEFAULT_FRAME_SIZE, 0, AMQP_SASL_METHOD_PLAIN, conf->user_id, conf->user_pwd);
    if(reply.reply_type != AMQP_RESPONSE_NORMAL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to login with " << conf->user_id << " - " << reply.reply_type);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    LOG4CXX_DEBUG(logger, "createMsgClient: opening a channel");
    
    // open a channel
    handle->channel = 1;
    amqp_channel_open(handle->conn_state, handle->channel);
    reply = amqp_get_rpc_reply(handle->conn_state);
    if(reply.reply_type != AMQP_RESPONSE_NORMAL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to open a channel - " << reply.reply_type);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    LOG4CXX_DEBUG(logger, "createMsgClient: declaring and binding a queue");
    
    // declare a queue
    memset(queue_name, 0, CREDENTIAL_MAX_LEN);
    sprintf(queue_name, "%s/%s", conf->user_id, conf->app_id);
    
    queue_status = amqp_queue_declare(handle->conn_state, handle->channel, amqp_cstring_bytes(queue_name), 0, 0, 1, 1, amqp_empty_table);
    reply = amqp_get_rpc_reply(handle->conn_state);
    if(reply.reply_type != AMQP_RESPONSE_NORMAL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to declare a queue - " << reply.reply_type);
        amqp_channel_close(handle->conn_state, handle->channel, AMQP_REPLY_SUCCESS);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    handle->queuename = amqp_bytes_malloc_dup(queue_status->queue);
    if(handle->queuename.bytes == NULL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to get a queue name");
        amqp_channel_close(handle->conn_state, handle->channel, AMQP_REPLY_SUCCESS);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }

    /*
     * no need to bind it when we use default exchange
    amqp_queue_bind(handle->conn_state, handle->channel, handle->queuename, amqp_cstring_bytes(conf->exchange), amqp_cstring_bytes("#"), amqp_empty_table);
    reply = amqp_get_rpc_reply(handle->conn_state);
    if(reply.reply_type != AMQP_RESPONSE_NORMAL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to bind a queue");
        amqp_channel_close(handle->conn_state, handle->channel, AMQP_REPLY_SUCCESS);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    */
    
    LOG4CXX_DEBUG(logger, "createMsgClient: starting consuming");
    
    // start consume
    amqp_basic_consume(handle->conn_state, handle->channel, handle->queuename, amqp_empty_bytes, 0, 0, 0, amqp_empty_table);
    reply = amqp_get_rpc_reply(handle->conn_state);
    if(reply.reply_type != AMQP_RESPONSE_NORMAL) {
        LOG4CXX_ERROR(logger, "createMsgClient: unable to start consuming - " << reply.reply_type);
        amqp_channel_close(handle->conn_state, handle->channel, AMQP_REPLY_SUCCESS);
        amqp_connection_close(handle->conn_state, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection(handle->conn_state);
        free(handle);
        return EIO;
    }
    
    *receiver = handle;
    return 0;
}
Example #18
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;
}
Example #19
0
int lc_bus_publish_unicast(const char *buf, int buf_len, uint32_t queue_id)
{
    amqp_connection_state_t *conn = NULL;
    amqp_bytes_t body = { len: buf_len, bytes: (void *)buf };
    amqp_basic_properties_t props;
    int res = 0;

    if (!buf || queue_id >= NUM_LC_BUS_QUEUE) {
        return LC_BUS_ERR;
    }

    conn = lc_bus_get_connection();
    if (!conn) {
        return LC_BUS_ERR;
    }

    memset(&props, 0, sizeof props);
    props._flags = AMQP_BASIC_DELIVERY_MODE_FLAG;
    props.delivery_mode = 2; /* persistent delivery mode */

    res = amqp_basic_publish(
            *conn,
            LC_BUS_CHANNEL,
            amqp_cstring_bytes(lc_bus_exchange[LC_BUS_EXCHANGE_DIRECT][0]),
            amqp_cstring_bytes(lc_bus_queue[queue_id]),
            0, /* mandatory */
            0, /* immediate */
            &props,
            body
            );
    if (res) {
        LB_SYSLOG(LOG_ERR, "failed channel=%u queue=%u ret=%d\n",
                LC_BUS_CHANNEL, queue_id, res);
        return LC_BUS_ERR;
    } else {
        LB_SYSLOG(LOG_INFO, "succeed channel=%u queue=%u\n",
                LC_BUS_CHANNEL, queue_id);
    }

    return LC_BUS_OK;
}

int lc_bus_publish_broadcast(const char *buf, int buf_len)
{
    /* TODO */
    return LC_BUS_OK;
}

int lc_bus_publish_multicast(const char *buf, int buf_len)
{
    /* TODO */
    return LC_BUS_OK;
}

static int consumer_queueids[NUM_LC_BUS_QUEUE];

static int lc_bus_init_consumer_atomic(amqp_connection_state_t *conn,
        uint32_t flag, uint32_t queue_id)
{
    amqp_basic_consume_ok_t *res_consume = NULL;
    amqp_rpc_reply_t ret;

    if (queue_id >= NUM_LC_BUS_QUEUE) {
        return LC_BUS_ERR;
    }

#if 0
    amqp_basic_qos_ok_t *res_qos = NULL;

    if (count > 0 && count <= 65535 &&
        !(res_qos = amqp_basic_qos(
            *conn,
            1,
            0,
            count,
            0
            ))) {
        die_rpc(amqp_get_rpc_reply(*conn), "basic.qos");
        return LC_BUS_ERR;
    }
#endif

    res_consume = amqp_basic_consume(
            *conn,
            LC_BUS_CHANNEL,
            amqp_cstring_bytes(lc_bus_queue[queue_id]),
            amqp_empty_bytes, /* consumer_tag */
            0,                /* no_local */
            (flag & LC_BUS_CONSUME_WITH_ACK) ? 0 : 1, /* no_ack */
            0,                /* exclusive */
            amqp_empty_table  /* arguments */
            );
    if (!res_consume) {
        ret = amqp_get_rpc_reply(*conn);
        if (ret.reply_type != AMQP_RESPONSE_NORMAL) {
            LB_SYSLOG(LOG_ERR, "[%s] failed, channel=%u %s\n",
                    lc_bus_queue[queue_id], LC_BUS_CHANNEL,
                    amqp_rpc_reply_string(&ret));
            return LC_BUS_ERR;
        }
    }

    consumer_queueids[queue_id] = 1;
    LB_SYSLOG(LOG_INFO, "[%s] succeed channel=%u.\n",
            lc_bus_queue[queue_id], LC_BUS_CHANNEL);
    return LC_BUS_OK;
}
Example #20
0
int main(int argc, char** argv)
{
  int channel = 1, status = AMQP_STATUS_OK, cnfnlen;
  amqp_socket_t *socket = NULL;
  amqp_connection_state_t conn;
  amqp_rpc_reply_t ret;
  amqp_message_t *reply = NULL;
  amqp_frame_t frame;
  struct timeval timeout;
  MYSQL db_inst;
  char ch, *cnfname = NULL, *cnfpath = NULL;
  static const char* fname = "consumer.cnf";

  if((c_inst = calloc(1,sizeof(CONSUMER))) == NULL){
    fprintf(stderr, "Fatal Error: Cannot allocate enough memory.\n");
    return 1;
  }

  if(signal(SIGINT,sighndl) == SIG_IGN){
    signal(SIGINT,SIG_IGN);
  }

  while((ch = getopt(argc,argv,"c:"))!= -1){
    switch(ch){
    case 'c':
      cnfnlen = strlen(optarg);
      cnfpath = strdup(optarg);
      break;
    default:

      break;
    }
  }

  cnfname = calloc(cnfnlen + strlen(fname) + 1,sizeof(char));

  if(cnfpath){

    /**Config file path as argument*/
    strcpy(cnfname,cnfpath);
    if(cnfpath[cnfnlen-1] != '/'){
      strcat(cnfname,"/");
    }

  }  
  
  strcat(cnfname,fname);

  timeout.tv_sec = 1;
  timeout.tv_usec = 0;
  all_ok = 1;
  out_fd = NULL;



  /**Parse the INI file*/
  if(ini_parse(cnfname,handler,NULL) < 0){
    
    /**Try to parse a config in the same directory*/
    if(ini_parse(fname,handler,NULL) < 0){
      fprintf(stderr, "Fatal Error: Error parsing configuration file!\n");
    goto fatal_error;

    }
  }

  if(out_fd == NULL){
    out_fd = stdout;
  }

  fprintf(out_fd,"\n--------------------------------------------------------------\n");
  
  /**Confirm that all parameters were in the configuration file*/
  if(!c_inst->hostname||!c_inst->vhost||!c_inst->user||
     !c_inst->passwd||!c_inst->dbpasswd||!c_inst->queue||
     !c_inst->dbserver||!c_inst->dbname||!c_inst->dbuser){
    fprintf(stderr, "Fatal Error: Inadequate configuration file!\n");
    goto fatal_error;    
  }

  connectToServer(&db_inst);

  if((conn = amqp_new_connection()) == NULL || 
     (socket = amqp_tcp_socket_new(conn)) == NULL){
    fprintf(stderr, "Fatal Error: Cannot create connection object or socket.\n");
    goto fatal_error;
  }
  
  if(amqp_socket_open(socket, c_inst->hostname, c_inst->port)){
    fprintf(stderr, "RabbitMQ Error: Cannot open socket.\n");
    goto error;
  }
  
  ret = amqp_login(conn, c_inst->vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, c_inst->user, c_inst->passwd);

  if(ret.reply_type != AMQP_RESPONSE_NORMAL){
    fprintf(stderr, "RabbitMQ Error: Cannot login to server.\n");
    goto error;
  }

  amqp_channel_open(conn, channel);
  ret = amqp_get_rpc_reply(conn);

  if(ret.reply_type != AMQP_RESPONSE_NORMAL){
    fprintf(stderr, "RabbitMQ Error: Cannot open channel.\n");
    goto error;
  }  

  reply = malloc(sizeof(amqp_message_t));
  if(!reply){
    fprintf(stderr, "Error: Cannot allocate enough memory.\n");
    goto error;
  }
  amqp_basic_consume(conn,channel,amqp_cstring_bytes(c_inst->queue),amqp_empty_bytes,0,0,0,amqp_empty_table);

  while(all_ok){
     
    status = amqp_simple_wait_frame_noblock(conn,&frame,&timeout);

    /**No frames to read from server, possibly out of messages*/
    if(status == AMQP_STATUS_TIMEOUT){ 
      sleep(timeout.tv_sec);
      continue;
    }

    if(frame.payload.method.id == AMQP_BASIC_DELIVER_METHOD){

      amqp_basic_deliver_t* decoded = (amqp_basic_deliver_t*)frame.payload.method.decoded;
	
      amqp_read_message(conn,channel,reply,0);

      if(sendMessage(&db_inst,reply)){

	fprintf(stderr,"RabbitMQ Error: Received malformed message.\n");
	amqp_basic_reject(conn,channel,decoded->delivery_tag,0);	
	amqp_destroy_message(reply);

      }else{

	amqp_basic_ack(conn,channel,decoded->delivery_tag,0);
	amqp_destroy_message(reply);	

      }
      
    }else{
      fprintf(stderr,"RabbitMQ Error: Received method from server: %s\n",amqp_method_name(frame.payload.method.id));
      all_ok = 0;
      goto error;
    }

  }

  fprintf(out_fd,"Shutting down...\n");
 error:

  mysql_close(&db_inst);
  mysql_library_end();
  if(c_inst && c_inst->query_stack){

    while(c_inst->query_stack){
      DELIVERY* d = c_inst->query_stack->next;
      amqp_destroy_message(c_inst->query_stack->message);
      free(c_inst->query_stack);
      c_inst->query_stack = d;
    }

  }
  
  amqp_channel_close(conn, channel, AMQP_REPLY_SUCCESS);
  amqp_connection_close(conn, AMQP_REPLY_SUCCESS);
  amqp_destroy_connection(conn);
 fatal_error:

  if(out_fd){
    fclose(out_fd);
  }

  
  if(c_inst){

    free(c_inst->hostname);
    free(c_inst->vhost);
    free(c_inst->user);
    free(c_inst->passwd);
    free(c_inst->queue);
    free(c_inst->dbserver);
    free(c_inst->dbname);
    free(c_inst->dbuser);
    free(c_inst->dbpasswd);    
    free(c_inst);
    
  }

  
  
  return all_ok;
}
Example #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;
}
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;
}
Example #23
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;
}
Example #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;
}
Example #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;
}
Example #26
0
/*************************************************************************
**************************************************************************
*
* Namn : rmq_connect
*
* Typ  : int
*
* Typ		Parameter	       IOGF	Beskrivning
*
* Beskrivning : Connect to RabbitMQ broker.
*
**************************************************************************
**************************************************************************/
int rmq_connect()
{
  int sts;
  amqp_rpc_reply_t rep;
  amqp_channel_open_ok_t* co;

  if (!ctx->conn) {
    ctx->conn = amqp_new_connection();
    // printf( "Connection : %u\n", (unsigned int)ctx->conn);
  }

  if (!ctx->socket) {
    ctx->socket = (amqp_socket_t*)amqp_tcp_socket_new(ctx->conn);
    if (!ctx->socket) {
      printf("Socket error\n");
      return 0;
    }

    sts = amqp_socket_open(ctx->socket, ctx->op->Server, ctx->op->Port);
    if (sts) {
      printf("Socket open error %d\n", sts);
      ctx->socket = 0;
      return 0;
    }
  }

  rep = amqp_login(ctx->conn, "/", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN,
      ctx->op->User, ctx->op->Password);
  if (rep.reply_type != AMQP_RESPONSE_NORMAL) {
    if (rep.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION)
      printf("Login failure, not authorized? %d\n", rep.reply_type);
    else
      printf("Login failure: %d\n", rep.reply_type);
    return 0;
  }

  if (!ctx->channel) {
    if (ctx->op->Channel == 0)
      ctx->channel = 1;
    else
      ctx->channel = ctx->op->Channel;

    co = amqp_channel_open(ctx->conn, ctx->channel);
    if (!co) {
      printf("Channel not open\n");
      ctx->channel = 0;
    } else {
      printf("Channel open %s\n", (char*)co->channel_id.bytes);
    }
  }

  /* Declare send queue */
  if (ctx->is_producer) {
    // 0 passive 0 durable 0 exclusive 0 auto-delete
    amqp_queue_declare_ok_t* qd = amqp_queue_declare(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->SendQueue), 0, ctx->op->Durable, 0, 0,
        amqp_empty_table);
    if (!qd) {
      printf("SendQueue not declared\n");
    } else {
      printf("SendQueue %s message cnt %d, consumer cnt %d\n",
          (char*)qd->queue.bytes, qd->message_count, qd->consumer_count);
    }
  }

  /* Declare receive queue */
  if (ctx->is_consumer) {
    // 0 passive 0 durable 0 exclusive 0 auto-delete
    amqp_queue_declare_ok_t* qd = amqp_queue_declare(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->ReceiveQueue), 0, ctx->op->Durable, 0, 0,
        amqp_empty_table);
    if (!qd) {
      printf("ReceiveQueue not declared\n");
    } else {
      printf("ReceiveQueue %s message cnt %d, consumer cnt %d\n",
          (char*)qd->queue.bytes, qd->message_count, qd->consumer_count);
    }
  }

  if (ctx->is_producer && !streq(ctx->op->Exchange, ""))
#if AMQP_VERSION_MAJOR == 0 && AMQP_VERSION_MINOR < 6
    amqp_exchange_declare(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->Exchange), amqp_cstring_bytes("fanout"), 0,
        ctx->op->Durable, amqp_empty_table);
#else
    amqp_exchange_declare(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->Exchange), amqp_cstring_bytes("fanout"), 0,
        ctx->op->Durable, 0, 0, amqp_empty_table);
#endif

  if (ctx->is_producer && !streq(ctx->op->Exchange, ""))
    amqp_queue_bind(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->SendQueue),
        amqp_cstring_bytes(ctx->op->Exchange),
        amqp_cstring_bytes("exchange-key"), amqp_empty_table);

  amqp_basic_consume_ok_t* bc;
  // 0 no-local 1 no-ack 0 exclusive
  if (ctx->is_consumer) {
    bc = amqp_basic_consume(ctx->conn, ctx->channel,
        amqp_cstring_bytes(ctx->op->ReceiveQueue), amqp_empty_bytes, 0,
        !ctx->op->Acknowledge, 0, amqp_empty_table);
    if (!bc)
      printf("Consumer error\n");
    else
      printf("Consumer tag: %s\n", (char*)bc->consumer_tag.bytes);
  }

  return 1;
}
Example #27
0
static int camqp_setup_queue (camqp_config_t *conf) /* {{{ */
{
    amqp_queue_declare_ok_t *qd_ret;
    amqp_basic_consume_ok_t *cm_ret;

    qd_ret = amqp_queue_declare (conf->connection,
            /* channel     = */ CAMQP_CHANNEL,
            /* queue       = */ (conf->queue != NULL)
            ? amqp_cstring_bytes (conf->queue)
            : AMQP_EMPTY_BYTES,
            /* passive     = */ 0,
            /* durable     = */ 0,
            /* exclusive   = */ 0,
            /* auto_delete = */ 1,
            /* arguments   = */ AMQP_EMPTY_TABLE);
    if (qd_ret == NULL)
    {
        ERROR ("amqp plugin: amqp_queue_declare failed.");
        camqp_close_connection (conf);
        return (-1);
    }

    if (conf->queue == NULL)
    {
        conf->queue = camqp_bytes_cstring (&qd_ret->queue);
        if (conf->queue == NULL)
        {
            ERROR ("amqp plugin: camqp_bytes_cstring failed.");
            camqp_close_connection (conf);
            return (-1);
        }

        INFO ("amqp plugin: Created queue \"%s\".", conf->queue);
    }
    DEBUG ("amqp plugin: Successfully created queue \"%s\".", conf->queue);

    /* bind to an exchange */
    if (conf->exchange != NULL)
    {
        amqp_queue_bind_ok_t *qb_ret;

        assert (conf->queue != NULL);
        qb_ret = amqp_queue_bind (conf->connection,
                /* channel     = */ CAMQP_CHANNEL,
                /* queue       = */ amqp_cstring_bytes (conf->queue),
                /* exchange    = */ amqp_cstring_bytes (conf->exchange),
                /* routing_key = */ (conf->routing_key != NULL)
                ? amqp_cstring_bytes (conf->routing_key)
                : AMQP_EMPTY_BYTES,
                /* arguments   = */ AMQP_EMPTY_TABLE);
        if ((qb_ret == NULL) && camqp_is_error (conf))
        {
            char errbuf[1024];
            ERROR ("amqp plugin: amqp_queue_bind failed: %s",
                    camqp_strerror (conf, errbuf, sizeof (errbuf)));
            camqp_close_connection (conf);
            return (-1);
        }

        DEBUG ("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".",
                conf->queue, conf->exchange);
    } /* if (conf->exchange != NULL) */

    cm_ret = amqp_basic_consume (conf->connection,
            /* channel      = */ CAMQP_CHANNEL,
            /* queue        = */ amqp_cstring_bytes (conf->queue),
            /* consumer_tag = */ AMQP_EMPTY_BYTES,
            /* no_local     = */ 0,
            /* no_ack       = */ 1,
            /* exclusive    = */ 0,
            /* arguments    = */ AMQP_EMPTY_TABLE
        );
    if ((cm_ret == NULL) && camqp_is_error (conf))
    {
        char errbuf[1024];
        ERROR ("amqp plugin: amqp_basic_consume failed: %s",
                    camqp_strerror (conf, errbuf, sizeof (errbuf)));
        camqp_close_connection (conf);
        return (-1);
    }

    return (0);
} /* }}} int camqp_setup_queue */
Example #28
0
static
void rabbitmq_add_queue(amqp_connection_state_t conn, amqp_channel_t* channel_ref, const char *stream)
{
    size_t n = strlen(stream) + 1;
    char app[n], env[n];
    memset(app, 0, n);
    memset(env, 0, n);
    sscanf(stream, "%[^-]-%[^-]", app, env);
    if (strcmp(env, rabbit_env)) {
        printf("[I] skipping: %s-%s\n", app, env);
        return;
    }
    // printf("[D] processing stream %s-%s\n", app, env);

    char exchange[n+16];
    memset(exchange, 0, n+16);
    sprintf(exchange, "request-stream-%s-%s", app, env);
    // printf("[D] exchange: %s\n", exchange);

    char queue[n+15];
    memset(queue, 0, n+15);
    sprintf(queue, "logjam-device-%s-%s", app, env);
    // printf("[D] queue: %s\n", queue);

    printf("[I] binding: %s ==> %s\n", exchange, queue);

    amqp_channel_t channel = ++(*channel_ref);
    if (channel > 1) {
        // printf("[D] opening channel %d\n", channel);
        amqp_channel_open(conn, channel);
        die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening AMQP channel");
    }

    // amqp_exchange_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t exchange,
    //                       amqp_bytes_t type, amqp_boolean_t passive, amqp_boolean_t durable,
    //                       amqp_boolean_t auto_delete, amqp_boolean_t internal, amqp_table_t arguments);
    amqp_exchange_declare(conn, channel, amqp_cstring_bytes(exchange), amqp_cstring_bytes("topic"),
                          0, 1, 0, 0, amqp_empty_table);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "declaring exchange");

    amqp_bytes_t queuename = amqp_cstring_bytes(queue);

    struct amqp_table_entry_t_ queue_arg_table_entries[1] = {
        { amqp_cstring_bytes("x-message-ttl"), { AMQP_FIELD_KIND_I32, { 60 * 1000 } } }
    };
    amqp_table_t queue_argument_table = {1, queue_arg_table_entries};

    // amqp_queue_declare(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue,
    //                    amqp_boolean_t passive, amqp_boolean_t durable, amqp_boolean_t exclusive, amqp_boolean_t auto_delete,
    //                    amqp_table_t arguments);
    amqp_queue_declare(conn, channel, queuename, 0, 0, 0, 1, queue_argument_table);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "declaring queue");

    // amqp_queue_bind(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue,
    //                 amqp_bytes_t exchange, amqp_bytes_t routing_key, amqp_table_t arguments)
    const char *routing_key = "#";
    amqp_queue_bind(conn, channel, queuename, amqp_cstring_bytes(exchange), amqp_cstring_bytes(routing_key), amqp_empty_table);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "binding queue");

    // amqp_basic_consume(amqp_connection_state_t state, amqp_channel_t channel, amqp_bytes_t queue, amqp_bytes_t consumer_tag,
    // amqp_boolean_t no_local, amqp_boolean_t no_ack, amqp_boolean_t exclusive, amqp_table_t arguments)
    amqp_basic_consume(conn, channel, queuename, amqp_empty_bytes, 0, 1, 0, amqp_empty_table);
    die_on_amqp_error(amqp_get_rpc_reply(conn), "consuming");
}