ConsoleEvent AgentImpl::query(const Query& query, Duration timeout) { boost::shared_ptr<SyncContext> context(new SyncContext()); uint32_t correlator(session.correlator()); ConsoleEvent result; { qpid::sys::Mutex::ScopedLock l(lock); contextMap[correlator] = context; } try { sendQuery(query, correlator); { uint64_t milliseconds = timeout.getMilliseconds(); qpid::sys::Mutex::ScopedLock cl(context->lock); if (!context->response.isValid() || !context->response.isFinal()) context->cond.wait(context->lock, qpid::sys::AbsTime(qpid::sys::now(), qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC))); if (context->response.isValid() && ((context->response.getType() == CONSOLE_QUERY_RESPONSE && context->response.isFinal()) || (context->response.getType() == CONSOLE_EXCEPTION))) result = context->response; else { auto_ptr<ConsoleEventImpl> impl(new ConsoleEventImpl(CONSOLE_EXCEPTION)); Data exception(new DataImpl()); exception.setProperty("error_text", "Timed out waiting for the agent to respond"); impl->addData(exception); result = ConsoleEvent(impl.release()); } } } catch (qpid::types::Exception&) { } { qpid::sys::Mutex::ScopedLock l(lock); contextMap.erase(correlator); } return result; }
ConsoleEvent AgentImpl::callMethod(const string& method, const Variant::Map& args, const DataAddr& addr, Duration timeout) { boost::shared_ptr<SyncContext> context(new SyncContext()); uint32_t correlator(session.correlator()); ConsoleEvent result; { qpid::sys::Mutex::ScopedLock l(lock); contextMap[correlator] = context; } try { sendMethod(method, args, addr, correlator); { uint64_t milliseconds = timeout.getMilliseconds(); qpid::sys::Mutex::ScopedLock cl(context->lock); if (!context->response.isValid()) context->cond.wait(context->lock, qpid::sys::AbsTime(qpid::sys::now(), qpid::sys::Duration(milliseconds * qpid::sys::TIME_MSEC))); if (context->response.isValid()) result = context->response; else { auto_ptr<ConsoleEventImpl> impl(new ConsoleEventImpl(CONSOLE_EXCEPTION)); Data exception(new DataImpl()); exception.setProperty("error_text", "Timed out waiting for the agent to respond"); impl->addData(exception); result = ConsoleEvent(impl.release()); } } } catch (qpid::types::Exception&) { } { qpid::sys::Mutex::ScopedLock l(lock); contextMap.erase(correlator); } return result; }
bool operator!=(const Duration& a, const Duration& b) { return a.getMilliseconds() != b.getMilliseconds(); }
void RequestResponse::run() { const char *options[] = {"", "--log-enable", "trace+", "--log-to-stdout", "on", "--log-time", "on", "--log-level", "on"}; Logger::configure(9, options); std::string url = "amqp:ssl:" + _options.getHost() + ":" + std::to_string(_options.getPort()); Connection connection(url, "{ protocol: amqp1.0 }"); connection.setOption("sasl_mechanisms", "EXTERNAL"); connection.setOption("heartbeat", "30"); Address reply(_replyAddress); Address request(_requestAddress); Address response(_responseAddress); Duration timeout = Duration::SECOND * _options.getTimeout(); try { connection.open(); Session session = connection.createSession(); std::cout << "-I- Connection opened, session created" << std::endl; Sender sender = session.createSender(request); sender.setCapacity(_capacity); std::cout << "-I- Sender created " << sender.getName() << std::endl; Receiver receiver = session.createReceiver(response); receiver.setCapacity(_capacity); std::cout << "-I- Receiver created " << receiver.getName() << std::endl; Message requestMsg("<FIXML>...</FIXML>"); requestMsg.setDurable(false); requestMsg.setReplyTo(reply); sender.send(requestMsg, true); std::cout << "-I- Request message sent" << std::endl; try { Message responseMsg = receiver.fetch(timeout); std::cout << "-I- Received message with content: " << responseMsg.getContent() << std::endl; session.acknowledge(true); _messageCounter++; } catch (NoMessageAvailable noMessage) { std::cout << "-I- No message received for " << timeout.getMilliseconds()/1000 << " seconds" << std::endl; } session.sync(true); sender.close(); receiver.close(); session.close(); connection.close(); } catch (const std::exception &error) { connection.close(); std::cerr << "-E- Caught exception: " << error.what() << std::endl; throw error; } }
Duration operator*(uint64_t multiplier, const Duration& duration) { return Duration(duration.getMilliseconds() * multiplier); }