Exemple #1
0
/**
 * Internal function used to initialize the connection to 
 * the RabbitMQ server. Also used to reconnect to the server
 * in case the connection fails and to redeclare exchanges
 * and queues if they are lost
 * 
 */
static int 
init_conn(MQ_INSTANCE *my_instance)
{ 
  int rval = 0;
  int amqp_ok = AMQP_STATUS_OK;

  if(my_instance->use_ssl){

    if((my_instance->sock = amqp_ssl_socket_new(my_instance->conn)) != NULL){

      if((amqp_ok = amqp_ssl_socket_set_cacert(my_instance->sock,my_instance->ssl_CA_cert)) != AMQP_STATUS_OK){
	skygw_log_write(LOGFILE_ERROR,
			"Error : Failed to set CA certificate: %s", amqp_error_string2(amqp_ok));
	goto cleanup;
      }
      if((amqp_ok = amqp_ssl_socket_set_key(my_instance->sock,
					    my_instance->ssl_client_cert,
					    my_instance->ssl_client_key)) != AMQP_STATUS_OK){
	skygw_log_write(LOGFILE_ERROR,
			"Error : Failed to set client certificate and key: %s", amqp_error_string2(amqp_ok));
	goto cleanup;
      }
    }else{

      amqp_ok = AMQP_STATUS_SSL_CONNECTION_FAILED;
      skygw_log_write(LOGFILE_ERROR,
		      "Error : SSL socket creation failed.");
      goto cleanup;
    }

    /**SSL is not used, falling back to TCP*/
  }else if((my_instance->sock = amqp_tcp_socket_new(my_instance->conn)) == NULL){
    skygw_log_write(LOGFILE_ERROR,
		    "Error : TCP socket creation failed.");
    goto cleanup;    

  }

  /**Socket creation was successful, trying to open the socket*/
  if((amqp_ok = amqp_socket_open(my_instance->sock,my_instance->hostname,my_instance->port)) != AMQP_STATUS_OK){
    skygw_log_write(LOGFILE_ERROR,
		    "Error : Failed to open socket: %s", amqp_error_string2(amqp_ok));
    goto cleanup;
  }
  amqp_rpc_reply_t reply;
  reply = amqp_login(my_instance->conn,my_instance->vhost,0,AMQP_DEFAULT_FRAME_SIZE,0,AMQP_SASL_METHOD_PLAIN,my_instance->username,my_instance->password);
  if(reply.reply_type != AMQP_RESPONSE_NORMAL){
    skygw_log_write(LOGFILE_ERROR,
		    "Error : Login to RabbitMQ server failed.");
    
    goto cleanup;
  }
  amqp_channel_open(my_instance->conn,my_instance->channel);
  reply = amqp_get_rpc_reply(my_instance->conn);  
  if(reply.reply_type != AMQP_RESPONSE_NORMAL){
    skygw_log_write(LOGFILE_ERROR,
		    "Error : Channel creation failed.");
    goto cleanup;
  }

  amqp_exchange_declare(my_instance->conn,my_instance->channel,
			amqp_cstring_bytes(my_instance->exchange),
			amqp_cstring_bytes(my_instance->exchange_type),
			0, 1,
			amqp_empty_table);

  reply = amqp_get_rpc_reply(my_instance->conn);  

  if(reply.reply_type != AMQP_RESPONSE_NORMAL){
    skygw_log_write(LOGFILE_ERROR,
		    "Error : Exchange declaration failed,trying to redeclare the exchange.");
    if(reply.reply_type == AMQP_RESPONSE_SERVER_EXCEPTION){
      if(reply.reply.id == AMQP_CHANNEL_CLOSE_METHOD){
	amqp_send_method(my_instance->conn,my_instance->channel,AMQP_CHANNEL_CLOSE_OK_METHOD,NULL);
      }else if(reply.reply.id == AMQP_CONNECTION_CLOSE_METHOD){
	amqp_send_method(my_instance->conn,my_instance->channel,AMQP_CONNECTION_CLOSE_OK_METHOD,NULL);
      }
      
      my_instance->channel++;
      amqp_channel_open(my_instance->conn,my_instance->channel);
    
      amqp_exchange_delete(my_instance->conn,my_instance->channel,amqp_cstring_bytes(my_instance->exchange),0);
      amqp_exchange_declare(my_instance->conn,my_instance->channel,
			    amqp_cstring_bytes(my_instance->exchange),
			    amqp_cstring_bytes(my_instance->exchange_type),
			    0, 1,
			    amqp_empty_table);
      reply = amqp_get_rpc_reply(my_instance->conn);  
    }
    if(reply.reply_type != AMQP_RESPONSE_NORMAL){
      skygw_log_write(LOGFILE_ERROR,
		      "Error : Exchange redeclaration failed.");
      goto cleanup;
    }
  }

  if(my_instance->queue){

    

    amqp_queue_declare(my_instance->conn,my_instance->channel,
		       amqp_cstring_bytes(my_instance->queue),
		       0, 1, 0, 0,
		       amqp_empty_table);
    reply = amqp_get_rpc_reply(my_instance->conn);  
    if(reply.reply_type != AMQP_RESPONSE_NORMAL){
      skygw_log_write(LOGFILE_ERROR,
		      "Error : Queue declaration failed.");
      goto cleanup;
    }

 
    amqp_queue_bind(my_instance->conn,my_instance->channel,
		    amqp_cstring_bytes(my_instance->queue),
		    amqp_cstring_bytes(my_instance->exchange),
		    amqp_cstring_bytes(my_instance->key),
		    amqp_empty_table);
    reply = amqp_get_rpc_reply(my_instance->conn);  
    if(reply.reply_type != AMQP_RESPONSE_NORMAL){
      skygw_log_write(LOGFILE_ERROR,
		      "Error : Failed to bind queue to exchange.");
      goto cleanup;
    }
  }
  rval = 1;

 cleanup:

  return rval;
 
}
Exemple #2
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;
}
Exemple #3
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;
}
Exemple #4
0
int amqpsend(const char *msg) {
  int amqp_channel = 1; // TODO: handle dynamic channel number
  int status;
  amqp_socket_t *socket = NULL;
  amqp_connection_state_t conn;
  amqp_bytes_t messagebody;

  // build the message body
  messagebody = amqp_cstring_bytes(msg);

  // open a connection to the server
  debug_print(2, "Connecting to AMQP Broker");
  conn = amqp_new_connection();
  socket = amqp_tcp_socket_new(conn);
  if (!socket) { 
    debug_print(2, "ERROR creating TCP socket");
    return 1;
  }
  status = amqp_socket_open(socket, amqp_hostname, amqp_port);
  if (status) {
    debug_print(2, "ERROR opening TCP socket");
    return 1;
  }

  // authenticate
  debug_print(2, "Authenticating");
  die_on_amqp_error(
      amqp_login(
        conn, amqp_vhost, 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, amqp_username, amqp_password
        ),
      "Authenticating");

  // open a channel
  debug_print(3, "Opening a channel");
  amqp_channel_open(conn, amqp_channel);
  die_on_amqp_error(amqp_get_rpc_reply(conn), "Opening channel");

  // build the message frame
  debug_print(3, "Building AMQP Message Frame");
  amqp_basic_properties_t props;
  props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
  props.content_type = amqp_cstring_bytes("text/plain");
  props.delivery_mode = AMQP_PERSISTENT;

  // send the message frame
  debug_print(2, "Publishing message to exchange/routing key");
  debug_print(2, amqp_exchange);
  debug_print(2, amqp_routingkey);
  die_on_error(amqp_basic_publish(conn,
                                  amqp_channel,
                                  amqp_cstring_bytes(amqp_exchange),
                                  amqp_cstring_bytes(amqp_routingkey),
                                  0,
                                  0,
                                  &props,
                                  messagebody),
                "Sending message");

  // cleanup by closing all our connections
  debug_print(4, "Cleaning up AMQP Connection");
  //debug_print(5, "Closing connection");
  //die_on_amqp_error(
  //    amqp_connection_close(conn, AMQP_REPLY_SUCCESS),
  //    "Closing connection");
  debug_print(5, "Ending connection");
  die_on_error(
      amqp_destroy_connection(conn),
      "Ending connection");

  return 0;
}
Exemple #5
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;
}
Exemple #6
0
static int camqp_connect (camqp_config_t *conf) /* {{{ */
{
    static time_t last_connect_time = 0;

    amqp_rpc_reply_t reply;
    int status;
#ifdef HAVE_AMQP_TCP_SOCKET
    amqp_socket_t *socket;
#else
    int sockfd;
#endif

    if (conf->connection != NULL)
        return (0);

    time_t now = time(NULL);
    if (now < (last_connect_time + conf->connection_retry_delay))
    {
        DEBUG("amqp plugin: skipping connection retry, "
            "ConnectionRetryDelay: %d", conf->connection_retry_delay);
        return(1);
    }
    else
    {
        DEBUG ("amqp plugin: retrying connection");
        last_connect_time = now;
    }

    conf->connection = amqp_new_connection ();
    if (conf->connection == NULL)
    {
        ERROR ("amqp plugin: amqp_new_connection failed.");
        return (ENOMEM);
    }

#ifdef HAVE_AMQP_TCP_SOCKET
# define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us */
    /* TODO: add support for SSL using amqp_ssl_socket_new
     *       and related functions */
    socket = amqp_tcp_socket_new (conf->connection);
    if (! socket)
    {
        ERROR ("amqp plugin: amqp_tcp_socket_new failed.");
        amqp_destroy_connection (conf->connection);
        conf->connection = NULL;
        return (ENOMEM);
    }

    status = amqp_socket_open (socket, CONF(conf, host), conf->port);
    if (status < 0)
    {
        char errbuf[1024];
        status *= -1;
        ERROR ("amqp plugin: amqp_socket_open failed: %s",
                sstrerror (status, errbuf, sizeof (errbuf)));
        amqp_destroy_connection (conf->connection);
        conf->connection = NULL;
        return (status);
    }
#else /* HAVE_AMQP_TCP_SOCKET */
# define CLOSE_SOCKET() close(sockfd)
    /* this interface is deprecated as of rabbitmq-c 0.4 */
    sockfd = amqp_open_socket (CONF(conf, host), conf->port);
    if (sockfd < 0)
    {
        char errbuf[1024];
        status = (-1) * sockfd;
        ERROR ("amqp plugin: amqp_open_socket failed: %s",
                sstrerror (status, errbuf, sizeof (errbuf)));
        amqp_destroy_connection (conf->connection);
        conf->connection = NULL;
        return (status);
    }
    amqp_set_sockfd (conf->connection, sockfd);
#endif

    reply = amqp_login (conf->connection, CONF(conf, vhost),
            /* channel max = */      0,
            /* frame max   = */ 131072,
            /* heartbeat   = */      0,
            /* authentication = */ AMQP_SASL_METHOD_PLAIN,
            CONF(conf, user), CONF(conf, password));
    if (reply.reply_type != AMQP_RESPONSE_NORMAL)
    {
        ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.",
                CONF(conf, vhost), CONF(conf, user));
        amqp_destroy_connection (conf->connection);
        CLOSE_SOCKET ();
        conf->connection = NULL;
        return (1);
    }

    amqp_channel_open (conf->connection, /* channel = */ 1);
    /* FIXME: Is checking "reply.reply_type" really correct here? How does
     * it get set? --octo */
    if (reply.reply_type != AMQP_RESPONSE_NORMAL)
    {
        ERROR ("amqp plugin: amqp_channel_open failed.");
        amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS);
        amqp_destroy_connection (conf->connection);
        CLOSE_SOCKET ();
        conf->connection = NULL;
        return (1);
    }

    INFO ("amqp plugin: Successfully opened connection to vhost \"%s\" "
            "on %s:%i.", CONF(conf, vhost), CONF(conf, host), conf->port);

    status = camqp_create_exchange (conf);
    if (status != 0)
        return (status);

    if (!conf->publish)
        return (camqp_setup_queue (conf));
    return (0);
} /* }}} int camqp_connect */
Exemple #7
0
eSquere* eSquere::NewSocket(amqp_connection_state_t conn){
    this->socket = amqp_tcp_socket_new(conn);
    if(!this->socket) return this->ErrorOn("Error creating TCP socket");
    if(amqp_socket_open(this->socket, this->hostname.c_str(), this->port)) return this->ErrorOn("Error opening TCP socket");
    return this;
}
Exemple #8
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;
}
/* 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;
}