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

				amqp_maybe_release_buffers(_conn);

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

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

				return 0;
			}
void
RabbitMQMessage::ack()
{
  amqp_basic_ack (connection->conn, 1,
                  envelope.delivery_tag, /* multiple */ false);

  acked = true;
}
Beispiel #3
0
static void* _receiveThread(void* param) {
    MsgReceiver_t *receiver = (MsgReceiver_t *)param;
    amqp_envelope_t envelope;
    amqp_rpc_reply_t reply;
    amqp_frame_t *frame;
    time_t curtime;
    
    assert(receiver != NULL);
    
    LOG4CXX_DEBUG(logger, "_receiveThread: event receiver thread started");
    
    sendLeaseRequest(receiver);
    curtime = getCurrentTime();
    
    while(receiver->thread_run) {
        amqp_maybe_release_buffers(receiver->conn_state);
        
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        
        if(getElapsedSecond(curtime, getCurrentTime()) > 60*5) {
            sendLeaseRequest(receiver);
            curtime = getCurrentTime();
        }
        
        reply = amqp_consume_message(receiver->conn_state, &envelope, NULL, 0);
        if(reply.reply_type == AMQP_RESPONSE_NORMAL) {
            // call handler
            MsgClientCallback_t callback = receiver->callback;

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

            amqp_destroy_envelope(&envelope);
        } else {
            LOG4CXX_INFO(logger, "_receiveThread: an exception occurred");
        }
        
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    }
    
    receiver->thread_run = false;
}
Beispiel #4
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);
    }
}
Beispiel #5
0
void Channel::BasicAck(const Envelope::DeliveryInfo &info, bool multiple) {
  m_impl->CheckIsConnected();
  // Delivery tag is local to the channel, so its important to use
  // that channel, sadly this can cause the channel to throw an exception
  // which will show up as an unrelated exception in a different method
  // that actually waits for a response from the broker
  amqp_channel_t channel = info.delivery_channel;
  if (!m_impl->IsChannelOpen(channel)) {
    throw std::runtime_error(
        "The channel that the message was delivered on has been closed");
  }

  m_impl->CheckForError(
      amqp_basic_ack(m_impl->m_connection, channel, info.delivery_tag, multiple));
}
Beispiel #6
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;
}
Beispiel #7
0
static int lc_bus_consume_message_atomic(amqp_connection_state_t *conn,
        uint32_t flag, amqp_envelope_t *envelope,
        amqp_frame_t *frame, amqp_message_t *message, char *buf, int buf_len)
{
    static struct timeval timeout = { tv_sec: RECV_TIMEOUT, tv_usec: 0 };
    size_t body_remaining = 0, offset = 0;
    int res = LC_BUS_OK;
    amqp_basic_deliver_t *deliver = NULL;

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

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

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

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

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

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

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

    if (buf_len == offset) {
        /* buffer is not enough */
        return 0;
    }
    return offset;
}
Beispiel #8
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;
}
Beispiel #9
0
unsigned int rmq_receive()
{
  pwr_tStatus sts;
  int search_remtrans = 0;
  remtrans_item* remtrans;
  amqp_rpc_reply_t ret;
  amqp_envelope_t envelope;
  struct timeval t = { 2, 0 };
  rabbit_header header;
  int msg_received = 0;

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

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

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

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

    remtrans = rn.remtrans;
    search_remtrans = 1;

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

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

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

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

  return sts;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #13
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;
}