コード例 #1
0
void amqp_destroy_envelope(amqp_envelope_t *envelope)
{
  amqp_destroy_message(&envelope->message);
  amqp_bytes_free(envelope->routing_key);
  amqp_bytes_free(envelope->exchange);
  amqp_bytes_free(envelope->consumer_tag);
}
コード例 #2
0
ファイル: test_basic.c プロジェクト: mkpurcell/rabbitmq-c
char *basic_get(amqp_connection_state_t connection_state_,
                const char *queue_name_, uint64_t *out_body_size_) {
  amqp_rpc_reply_t rpc_reply;
  amqp_time_t deadline;
  struct timeval timeout = { 5, 0 };
  int time_rc = amqp_time_from_now(&deadline, &timeout);
  assert(time_rc == AMQP_STATUS_OK);

  do {
    rpc_reply = amqp_basic_get(connection_state_, fixed_channel_id,
                               amqp_cstring_bytes(queue_name_), /*no_ack*/ 1);
  } while (rpc_reply.reply_type == AMQP_RESPONSE_NORMAL &&
           rpc_reply.reply.id == AMQP_BASIC_GET_EMPTY_METHOD &&
           amqp_time_has_past(deadline) == AMQP_STATUS_OK);

  assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL);
  assert(rpc_reply.reply.id == AMQP_BASIC_GET_OK_METHOD);

  amqp_message_t message;
  rpc_reply = amqp_read_message(connection_state_, fixed_channel_id, &message, 0);
  assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL);
  
  char *body = malloc(message.body.len);
  memcpy(body, message.body.bytes, message.body.len);
  *out_body_size_ = message.body.len;
  amqp_destroy_message(&message);

  return body;
}
コード例 #3
0
ファイル: rpc.c プロジェクト: AJStubzy/zentyal
void rpc_run(struct status *status)
{
    int ret;

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

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

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

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

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

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

        DEBUG(2, ("Delivery %u, exchange %.*s routingkey %.*s\n",
              (unsigned) envelope.delivery_tag,
              (int) envelope.exchange.len, (char *) envelope.exchange.bytes,
              (int) envelope.routing_key.len, (char *) envelope.routing_key.bytes));

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

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

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

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

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

    /* Clean up control */
    control_free(status);
}
コード例 #4
0
static void run(amqp_connection_state_t conn)
{
  uint64_t start_time = now_microseconds();
  int received = 0;
  int previous_received = 0;
  uint64_t previous_report_time = start_time;
  uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;

  amqp_frame_t frame;

  uint64_t now;

  while (1) {
    amqp_rpc_reply_t ret;
    amqp_envelope_t envelope;

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

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

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

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

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

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

                amqp_destroy_message(&message);
              }

              break;

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

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

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

    } else {
      amqp_destroy_envelope(&envelope);
    }

    received++;
  }
}
コード例 #5
0
ファイル: murano-agent.c プロジェクト: Bloomie/murano-agent
static void run ( amqp_connection_state_t conn, int log_fd , const char *result_routing_key )
{
    int received = 0;
    amqp_frame_t frame;

    while ( 1 )
    {
        amqp_rpc_reply_t ret;
        amqp_envelope_t envelope;

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

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

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

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

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

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

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

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

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

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

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

                        amqp_destroy_message ( &message );
                    }

                    break;

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

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

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

        }

        received++;
    }
}
コード例 #6
0
ファイル: consumer.c プロジェクト: balsdorf/MaxScale
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;
}