TEST(table, convert_to_rabbitmq) { Table table_in; table_in.insert(TableEntry("void_key", TableValue())); table_in.insert(TableEntry("bool_key", true)); table_in.insert(TableEntry("int8_key", int8_t(8))); table_in.insert(TableEntry("int16_key", int16_t(16))); table_in.insert(TableEntry("int32_key", int32_t(32))); table_in.insert(TableEntry("int64_key", int64_t(64))); table_in.insert(TableEntry("float_key", float(1.5))); table_in.insert(TableEntry("double_key", double(2.25))); table_in.insert(TableEntry("string_key", "A string!")); std::vector<TableValue> array_in; array_in.push_back(TableValue(false)); array_in.push_back(TableValue(int32_t(10))); array_in.push_back(TableValue(std::string("Another string"))); table_in.insert(TableEntry("array_key", array_in)); Table table_inner; table_inner.insert(TableEntry("inner_string", "An inner table")); table_inner.insert(TableEntry("inner array", array_in)); table_in.insert(TableEntry("table_key", table_inner)); BasicMessage::ptr_t message = BasicMessage::Create(); message->HeaderTable(table_in); EXPECT_TRUE(message->HeaderTableIsSet()); Table table_out = message->HeaderTable(); EXPECT_EQ(table_in.size(), table_out.size()); EXPECT_TRUE(std::equal(table_in.begin(), table_in.end(), table_out.begin())); }
std::string SimpleRpcClient::Call(const std::string &message) { BasicMessage::ptr_t outgoing_msg = BasicMessage::Create(); outgoing_msg->Body(message); BasicMessage::ptr_t reply = Call(outgoing_msg); return reply->Body(); }
TEST(table, convert_to_rabbitmq_empty) { Table table_in; BasicMessage::ptr_t message = BasicMessage::Create(); message->HeaderTable(table_in); Table table_out = message->HeaderTable(); EXPECT_EQ(0, table_out.size()); }
TEST_F(connected_test, get_ok) { BasicMessage::ptr_t message = BasicMessage::Create("Message Body"); std::string queue = channel->DeclareQueue(""); channel->BasicPublish("", queue, message, true); Envelope::ptr_t new_message; EXPECT_TRUE(channel->BasicGet(new_message, queue)); EXPECT_EQ(message->Body(), new_message->Message()->Body()); }
set<uint> ServiceClient::receive(const set<uint>& ids, const uint& timeout) { using namespace chrono; auto end = high_resolution_clock::now() + milliseconds(timeout); set<uint> received; // check if we have not received the reply already for (auto& id : ids) { auto iterator = replies.find(id); if (iterator != replies.end()) { received.insert(id); } } if (received.size() == ids.size()) { return received; // all packets arrived, return } while (1) { Envelope::ptr_t envelope; BasicMessage::ptr_t message; do { auto now = high_resolution_clock::now(); int delta = duration_cast<milliseconds>(end-now).count(); if (delta <= 0) { return received; // we are out of time already, leave! } bool newmsg = channel->BasicConsumeMessage(envelope, delta); if (newmsg == false) { return received; // timeout reached and nothing was received } message = envelope->Message(); } while (message->ContentType() != "application/msgpack" || message->CorrelationIdIsSet() == false); uint id = stoi(message->CorrelationId()); replies.emplace(id, message); auto iterator = ids.find(id); if (iterator != ids.end()) { // we were waiting for this message received.insert(id); if (received.size() == ids.size()) { return received; // all packets arrived, return } } } }
TEST(test_get, get_big) { // Smallest frame size allowed by AMQP Channel::ptr_t channel = Channel::Create(connected_test::GetBrokerHost(), 5672, "guest", "guest", "/", 4096); // Create a message with a body larger than a single frame BasicMessage::ptr_t message = BasicMessage::Create(std::string(4099, 'a')); std::string queue = channel->DeclareQueue(""); channel->BasicPublish("", queue, message); Envelope::ptr_t new_message; EXPECT_TRUE(channel->BasicGet(new_message, queue)); EXPECT_EQ(message->Body(), new_message->Message()->Body()); }
void Channel::BasicPublish(const std::string &exchange_name, const std::string &routing_key, const BasicMessage::ptr_t message, bool mandatory, bool immediate) { m_impl->CheckIsConnected(); amqp_channel_t channel = m_impl->GetChannel(); m_impl->CheckForError(amqp_basic_publish( m_impl->m_connection, channel, amqp_cstring_bytes(exchange_name.c_str()), amqp_cstring_bytes(routing_key.c_str()), mandatory, immediate, message->getAmqpProperties(), message->getAmqpBody())); // If we've done things correctly we can get one of 4 things back from the // broker // - basic.ack - our channel is in confirm mode, messsage was 'dealt with' by // the broker // - basic.return then basic.ack - the message wasn't delievered, but was // dealt with // - channel.close - probably tried to publish to a non-existant exchange, in // any case error! // - connection.clsoe - something really bad happened const boost::array<boost::uint32_t, 2> PUBLISH_ACK = { {AMQP_BASIC_ACK_METHOD, AMQP_BASIC_RETURN_METHOD}}; amqp_frame_t response; boost::array<amqp_channel_t, 1> channels = {{channel}}; m_impl->GetMethodOnChannel(channels, response, PUBLISH_ACK); if (AMQP_BASIC_RETURN_METHOD == response.payload.method.id) { MessageReturnedException message_returned = m_impl->CreateMessageReturnedException( *(reinterpret_cast<amqp_basic_return_t *>( response.payload.method.decoded)), channel); const boost::array<boost::uint32_t, 1> BASIC_ACK = { {AMQP_BASIC_ACK_METHOD}}; m_impl->GetMethodOnChannel(channels, response, BASIC_ACK); m_impl->ReturnChannel(channel); m_impl->MaybeReleaseBuffersOnChannel(channel); throw message_returned; } m_impl->ReturnChannel(channel); m_impl->MaybeReleaseBuffersOnChannel(channel); }
BasicMessage::ptr_t SimpleRpcClient::Call(BasicMessage::ptr_t message) { message->ReplyTo(m_incoming_tag); m_channel->BasicPublish("amq.direct", m_outgoing_tag, message); BasicMessage::ptr_t incoming_msg = m_channel->BasicConsumeMessage(m_incoming_tag)->Message(); return incoming_msg; }
std::string SimpleSubscriber::WaitForMessageString() { BasicMessage::ptr_t incoming = WaitForMessage(); return incoming->Body(); }