00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <config.h>
00026
00027 #include <drizzled/gettext.h>
00028
00029 #include "rabbitmq_handler.h"
00030
00031 using namespace std;
00032
00033 namespace drizzle_plugin
00034 {
00035
00036 RabbitMQHandler::RabbitMQHandler(const std::string &rabbitMQHost,
00037 const in_port_t rabbitMQPort,
00038 const std::string &rabbitMQUsername,
00039 const std::string &rabbitMQPassword,
00040 const std::string &rabbitMQVirtualhost,
00041 const std::string &rabbitMQExchange,
00042 const std::string &rabbitMQRoutingKey)
00043 throw(rabbitmq_handler_exception) :
00044 rabbitmqConnection(amqp_new_connection()),
00045 hostname(rabbitMQHost),
00046 port(rabbitMQPort),
00047 username(rabbitMQUsername),
00048 password(rabbitMQPassword),
00049 virtualhost(rabbitMQVirtualhost),
00050 exchange(rabbitMQExchange),
00051 routingKey(rabbitMQRoutingKey)
00052 {
00053 pthread_mutex_init(&publishLock, NULL);
00054 connect();
00055 }
00056
00057 RabbitMQHandler::~RabbitMQHandler()
00058 {
00059 pthread_mutex_destroy(&publishLock);
00060 disconnect();
00061 }
00062
00063 void RabbitMQHandler::publish(void *message,
00064 const int length)
00065 throw(rabbitmq_handler_exception)
00066 {
00067 pthread_mutex_lock(&publishLock);
00068 amqp_bytes_t b;
00069 b.bytes= message;
00070 b.len= length;
00071
00072 if (amqp_basic_publish(rabbitmqConnection,
00073 1,
00074 amqp_cstring_bytes(exchange.c_str()),
00075 amqp_cstring_bytes(routingKey.c_str()),
00076 0,
00077 0,
00078 NULL,
00079 b) < 0)
00080 {
00081 pthread_mutex_unlock(&publishLock);
00082 throw rabbitmq_handler_exception("Could not publish message");
00083 }
00084 pthread_mutex_unlock(&publishLock);
00085
00086 }
00087
00088 void RabbitMQHandler::reconnect() throw(rabbitmq_handler_exception)
00089 {
00090 disconnect();
00091 connect();
00092 }
00093
00094 void RabbitMQHandler::disconnect() throw(rabbitmq_handler_exception)
00095 {
00096 try
00097 {
00098 handleAMQPError(amqp_channel_close(rabbitmqConnection,
00099 1,
00100 AMQP_REPLY_SUCCESS),
00101 "close channel");
00102 handleAMQPError(amqp_connection_close(rabbitmqConnection,
00103 AMQP_REPLY_SUCCESS),
00104 "close connection");
00105 amqp_destroy_connection(rabbitmqConnection);
00106 }
00107 catch(exception& e) {}
00108 close(sockfd);
00109 }
00110
00111 void RabbitMQHandler::connect() throw(rabbitmq_handler_exception) {
00112 sockfd = amqp_open_socket(hostname.c_str(), port);
00113 if(sockfd < 0)
00114 {
00115 throw rabbitmq_handler_exception(_("Could not open socket, is rabbitmq running?"));
00116 }
00117 amqp_set_sockfd(rabbitmqConnection, sockfd);
00118
00119 handleAMQPError(amqp_login(rabbitmqConnection,
00120 virtualhost.c_str(),
00121 0,
00122 131072,
00123 0,
00124 AMQP_SASL_METHOD_PLAIN,
00125 username.c_str(),
00126 password.c_str()),
00127 "rabbitmq login");
00128
00129 amqp_channel_open(rabbitmqConnection, 1);
00130 handleAMQPError(amqp_get_rpc_reply(rabbitmqConnection), "RPC Reply");
00131 amqp_table_t empty_table = { 0, NULL };
00132 amqp_exchange_declare(rabbitmqConnection, 1, amqp_cstring_bytes(exchange.c_str()), amqp_cstring_bytes("fanout"), 0, 0, empty_table);
00133 handleAMQPError(amqp_get_rpc_reply(rabbitmqConnection), "RPC Reply");
00134 }
00135
00136 void RabbitMQHandler::handleAMQPError(amqp_rpc_reply_t x, string context) throw(rabbitmq_handler_exception)
00137 {
00138 string errorMessage("");
00139 switch (x.reply_type) {
00140 case AMQP_RESPONSE_NORMAL:
00141 break;
00142 case AMQP_RESPONSE_NONE:
00143 errorMessage.assign("No response in ");
00144 errorMessage.append(context);
00145 throw rabbitmq_handler_exception(errorMessage);
00146 case AMQP_RESPONSE_LIBRARY_EXCEPTION:
00147 case AMQP_RESPONSE_SERVER_EXCEPTION:
00148 switch (x.reply.id) {
00149 case AMQP_CONNECTION_CLOSE_METHOD:
00150 errorMessage.assign("Connection closed in ");
00151 errorMessage.append(context);
00152 throw rabbitmq_handler_exception(errorMessage);
00153 case AMQP_CHANNEL_CLOSE_METHOD:
00154 errorMessage.assign("Channel closed in ");
00155 errorMessage.append(context);
00156 throw rabbitmq_handler_exception(errorMessage);
00157 default:
00158 errorMessage.assign("Unknown error in ");
00159 errorMessage.append(context);
00160 throw rabbitmq_handler_exception(errorMessage);
00161 }
00162 }
00163 }
00164
00165 }