static int exit_amqp_connection_atomic() { int res = LC_BUS_OK; amqp_rpc_reply_t ret; int i; for (i = 0; i < LC_BUS_MAX_CONNECTION; ++i) { if (connection_tid[i]) { ret = amqp_channel_close(lc_conn[i], LC_BUS_CHANNEL, AMQP_REPLY_SUCCESS); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "error in closing channel: %s\n", amqp_rpc_reply_string(&ret)); } ret = amqp_connection_close(lc_conn[i], AMQP_REPLY_SUCCESS); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "error in closing connection, %s\n", amqp_rpc_reply_string(&ret)); } res = amqp_destroy_connection(lc_conn[i]); if (res) { LB_SYSLOG(LOG_ERR, "error in destroy connection ret=%d\n", res); } connection_tid[i] = 0; } } return LC_BUS_OK; }
static int lc_bus_queue_init(amqp_connection_state_t *conn, uint32_t queue_id) { amqp_queue_declare_ok_t *res = NULL; amqp_rpc_reply_t ret; if (queue_id >= NUM_LC_BUS_QUEUE) { return LC_BUS_ERR; } res = amqp_queue_declare( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_queue[queue_id]), 0, /* passive */ 1, /* durable */ 0, /* exclusive */ 0, /* auto_delete */ amqp_empty_table /* arguments */ ); if (!res) { ret = amqp_get_rpc_reply(*conn); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "[%s] failed, channel=%u %s\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL, amqp_rpc_reply_string(&ret)); return LC_BUS_ERR; } } LB_SYSLOG(LOG_INFO, "[%s] succeed channel=%u.\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL); return LC_BUS_OK; }
void die_rpc(amqp_rpc_reply_t r, const char *fmt, ...) { va_list ap; if (r.reply_type == AMQP_RESPONSE_NORMAL) { return; } va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, ": %s\n", amqp_rpc_reply_string(r)); exit(1); }
static amqp_connection_state_t *lc_bus_get_connection_atomic() { pthread_t t = pthread_self(); amqp_rpc_reply_t ret; int res; int i; for (i = 0; i < LC_BUS_MAX_CONNECTION; ++i) { if (!connection_tid[i] || pthread_equal(connection_tid[i], t)) { break; } } if (i < LC_BUS_MAX_CHANNEL) { if (!connection_tid[i]) { res = init_amqp_connection(lc_conn + i); if (res == LC_BUS_OK) { LB_SYSLOG(LOG_INFO, "init_amqp_connection ret=%d\n", res); } else { LB_SYSLOG(LOG_ERR, "init_amqp_connection ret=%d\n", res); return NULL; } if (!amqp_channel_open(lc_conn[i], LC_BUS_CHANNEL)) { ret = amqp_get_rpc_reply(lc_conn[i]); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "error in opening channel %u, %s\n", LC_BUS_CHANNEL, amqp_rpc_reply_string(&ret)); return NULL; } } connection_tid[i] = t; } } else { LB_SYSLOG(LOG_ERR, "connection is not enough, maximal=%u.\n", LC_BUS_MAX_CONNECTION); return NULL; } return lc_conn + i; }
static int lc_bus_binding_init(amqp_connection_state_t *conn, uint32_t binding_id) { uint32_t exchange_id, queue_id; amqp_queue_bind_ok_t *res = NULL; amqp_rpc_reply_t ret; if (binding_id >= NUM_LC_BUS_BINDING) { return LC_BUS_ERR; } exchange_id = lc_bus_binding[binding_id][0]; queue_id = lc_bus_binding[binding_id][1]; res = amqp_queue_bind( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_queue[queue_id]), amqp_cstring_bytes(lc_bus_exchange[exchange_id][0]), amqp_cstring_bytes(lc_bus_binding_key[binding_id]), amqp_empty_table /* arguments */ ); if (!res) { ret = amqp_get_rpc_reply(*conn); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "[%s,%s,%s] failed, channel=%u %s\n", lc_bus_exchange[exchange_id][0], lc_bus_queue[queue_id], lc_bus_binding_key[binding_id], LC_BUS_CHANNEL, amqp_rpc_reply_string(&ret)); return LC_BUS_ERR; } } LB_SYSLOG(LOG_INFO, "[%s,%s,%s] succeed channel=%u.\n", lc_bus_exchange[exchange_id][0], lc_bus_queue[queue_id], lc_bus_binding_key[binding_id], LC_BUS_CHANNEL); return LC_BUS_OK; }
static int init_amqp_connection(amqp_connection_state_t *conn) { int status; amqp_socket_t *socket = NULL; struct amqp_connection_info ci; amqp_rpc_reply_t ret; ci.user = "******"; ci.password = "******"; ci.host = "localhost"; ci.vhost = "/"; ci.port = 20001; ci.ssl = 0; *conn = amqp_new_connection(); if (ci.ssl) { #ifdef WITH_SSL socket = amqp_ssl_socket_new(*conn); if (!socket) { LB_SYSLOG(LOG_ERR, "creating SSL/TLS socket\n"); return LC_BUS_ERR; } if (amqp_cacert) { amqp_ssl_socket_set_cacert(socket, amqp_cacert); } if (amqp_key) { amqp_ssl_socket_set_key(socket, amqp_cert, amqp_key); } #else LB_SYSLOG(LOG_ERR, "librabbitmq was not built with SSL/TLS support\n"); return LC_BUS_ERR; #endif } else { socket = amqp_tcp_socket_new(*conn); if (!socket) { LB_SYSLOG(LOG_ERR, "creating TCP socket (out of memory)\n"); return LC_BUS_ERR; } } status = amqp_socket_open(socket, ci.host, ci.port); if (status) { LB_SYSLOG(LOG_ERR, "opening socket to %s:%d, status=%d, errno=%s.\n", ci.host, ci.port, status, strerror(errno)); return LC_BUS_ERR; } ret = amqp_login( *conn, ci.vhost, LC_BUS_MAX_CHANNEL, /* channel max */ LC_BUS_MAX_FRAME_SIZE, 0, /* heartbeat */ AMQP_SASL_METHOD_PLAIN, ci.user, ci.password ); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "error in logging AMQP server, %s\n", amqp_rpc_reply_string(&ret)); return LC_BUS_ERR; } return LC_BUS_OK; }
int lc_bus_publish_unicast(const char *buf, int buf_len, uint32_t queue_id) { amqp_connection_state_t *conn = NULL; amqp_bytes_t body = { len: buf_len, bytes: (void *)buf }; amqp_basic_properties_t props; int res = 0; if (!buf || queue_id >= NUM_LC_BUS_QUEUE) { return LC_BUS_ERR; } conn = lc_bus_get_connection(); if (!conn) { return LC_BUS_ERR; } memset(&props, 0, sizeof props); props._flags = AMQP_BASIC_DELIVERY_MODE_FLAG; props.delivery_mode = 2; /* persistent delivery mode */ res = amqp_basic_publish( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_exchange[LC_BUS_EXCHANGE_DIRECT][0]), amqp_cstring_bytes(lc_bus_queue[queue_id]), 0, /* mandatory */ 0, /* immediate */ &props, body ); if (res) { LB_SYSLOG(LOG_ERR, "failed channel=%u queue=%u ret=%d\n", LC_BUS_CHANNEL, queue_id, res); return LC_BUS_ERR; } else { LB_SYSLOG(LOG_INFO, "succeed channel=%u queue=%u\n", LC_BUS_CHANNEL, queue_id); } return LC_BUS_OK; } int lc_bus_publish_broadcast(const char *buf, int buf_len) { /* TODO */ return LC_BUS_OK; } int lc_bus_publish_multicast(const char *buf, int buf_len) { /* TODO */ return LC_BUS_OK; } static int consumer_queueids[NUM_LC_BUS_QUEUE]; static int lc_bus_init_consumer_atomic(amqp_connection_state_t *conn, uint32_t flag, uint32_t queue_id) { amqp_basic_consume_ok_t *res_consume = NULL; amqp_rpc_reply_t ret; if (queue_id >= NUM_LC_BUS_QUEUE) { return LC_BUS_ERR; } #if 0 amqp_basic_qos_ok_t *res_qos = NULL; if (count > 0 && count <= 65535 && !(res_qos = amqp_basic_qos( *conn, 1, 0, count, 0 ))) { die_rpc(amqp_get_rpc_reply(*conn), "basic.qos"); return LC_BUS_ERR; } #endif res_consume = amqp_basic_consume( *conn, LC_BUS_CHANNEL, amqp_cstring_bytes(lc_bus_queue[queue_id]), amqp_empty_bytes, /* consumer_tag */ 0, /* no_local */ (flag & LC_BUS_CONSUME_WITH_ACK) ? 0 : 1, /* no_ack */ 0, /* exclusive */ amqp_empty_table /* arguments */ ); if (!res_consume) { ret = amqp_get_rpc_reply(*conn); if (ret.reply_type != AMQP_RESPONSE_NORMAL) { LB_SYSLOG(LOG_ERR, "[%s] failed, channel=%u %s\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL, amqp_rpc_reply_string(&ret)); return LC_BUS_ERR; } } consumer_queueids[queue_id] = 1; LB_SYSLOG(LOG_INFO, "[%s] succeed channel=%u.\n", lc_bus_queue[queue_id], LC_BUS_CHANNEL); return LC_BUS_OK; }