use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class QueueFuse method purgeQueue.
/**
* Look up a queue object with the given name and if it's not a ring queue invoke the queue's purge method.
* @param queueName the name of the queue to purge
* @param msgDepth the number of messages on the queue, used to determine how many messages to purge.
*/
private void purgeQueue(final String queueName, long msgDepth) {
QmfConsoleData queue = _queueCache.get(queueName);
if (queue == null) {
System.out.printf("%s ERROR QueueFuse.disconnectQueue() %s reference couldn't be found\n", new Date().toString(), queueName);
} else {
// If we've found a queue called queueName we then find the bindings that reference it.
Map args = (Map) queue.getValue("arguments");
String policyType = (String) args.get("qpid.policy_type");
if (policyType != null && policyType.equals("ring")) {
// If qpid.policy_type=ring we return.
return;
}
try {
QmfData arguments = new QmfData();
arguments.setValue("request", (long) (_purge * msgDepth));
queue.invokeMethod("purge", arguments);
} catch (QmfException e) {
System.out.println(e.getMessage());
}
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class Agent method onMessage.
// MessageListener
// ********************************************************************************************************
/**
* MessageListener for QMF2 Console requests.
*
* @param message the JMS Message passed to the listener.
*/
public final void onMessage(final Message message) {
try {
String agentName = QmfData.getString(message.getObjectProperty("qmf.agent"));
String content = QmfData.getString(message.getObjectProperty("qmf.content"));
String opcode = QmfData.getString(message.getObjectProperty("qmf.opcode"));
// String routingKey = ((javax.jms.Topic)message.getJMSDestination()).getTopicName();
// String contentType = ((org.apache.qpid.client.message.AbstractJMSMessage)message).getContentType();
// System.out.println();
// System.out.println("agentName = " + agentName);
// System.out.println("content = " + content);
// System.out.println("opcode = " + opcode);
// System.out.println("routingKey = " + routingKey);
// System.out.println("contentType = " + contentType);
Handle handle = new Handle(message.getJMSCorrelationID(), message.getJMSReplyTo());
if (opcode.equals("_agent_locate_request")) {
handleLocateRequest(handle);
} else if (opcode.equals("_method_request")) {
if (AMQPMessage.isAMQPMap(message)) {
_eventListener.onEvent(new MethodCallWorkItem(handle, new MethodCallParams(AMQPMessage.getMap(message))));
} else {
_log.info("onMessage() Received Method Request message in incorrect format");
}
} else if (opcode.equals("_query_request")) {
if (AMQPMessage.isAMQPMap(message)) {
try {
QmfQuery query = new QmfQuery(AMQPMessage.getMap(message));
handleQueryRequest(handle, query);
} catch (QmfException qmfe) {
raiseException(handle, "Query Request failed, invalid Query: " + qmfe.getMessage());
}
} else {
_log.info("onMessage() Received Query Request message in incorrect format");
}
} else if (opcode.equals("_subscribe_request")) {
if (AMQPMessage.isAMQPMap(message)) {
try {
SubscriptionParams subscriptionParams = new SubscriptionParams(handle, AMQPMessage.getMap(message));
if (this instanceof AgentExternal) {
_eventListener.onEvent(new SubscribeRequestWorkItem(handle, subscriptionParams));
} else {
Subscription subscription = new Subscription(this, subscriptionParams);
String subscriptionId = subscription.getSubscriptionId();
_subscriptions.put(subscriptionId, subscription);
_timer.schedule(subscription, 0, subscriptionParams.getPublishInterval());
subscriptionResponse(handle, subscription.getConsoleHandle(), subscriptionId, subscription.getDuration(), subscription.getInterval(), null);
}
} catch (QmfException qmfe) {
raiseException(handle, "Subscribe Request failed, invalid Query: " + qmfe.getMessage());
}
} else {
_log.info("onMessage() Received Subscribe Request message in incorrect format");
}
} else if (opcode.equals("_subscribe_refresh_indication")) {
if (AMQPMessage.isAMQPMap(message)) {
ResubscribeParams resubscribeParams = new ResubscribeParams(AMQPMessage.getMap(message));
if (this instanceof AgentExternal) {
_eventListener.onEvent(new ResubscribeRequestWorkItem(handle, resubscribeParams));
} else {
String subscriptionId = resubscribeParams.getSubscriptionId();
Subscription subscription = _subscriptions.get(subscriptionId);
if (subscription != null) {
subscription.refresh(resubscribeParams);
subscriptionResponse(handle, subscription.getConsoleHandle(), subscription.getSubscriptionId(), subscription.getDuration(), subscription.getInterval(), null);
}
}
} else {
_log.info("onMessage() Received Resubscribe Request message in incorrect format");
}
} else if (opcode.equals("_subscribe_cancel_indication")) {
if (AMQPMessage.isAMQPMap(message)) {
QmfData qmfSubscribe = new QmfData(AMQPMessage.getMap(message));
String subscriptionId = qmfSubscribe.getStringValue("_subscription_id");
if (this instanceof AgentExternal) {
_eventListener.onEvent(new UnsubscribeRequestWorkItem(subscriptionId));
} else {
Subscription subscription = _subscriptions.get(subscriptionId);
if (subscription != null) {
subscription.cancel();
}
}
} else {
_log.info("onMessage() Received Subscribe Cancel Request message in incorrect format");
}
}
} catch (JMSException jmse) {
_log.info("JMSException {} caught in onMessage()", jmse.getMessage());
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class Agent method setConnection.
/**
* Connect the Agent to the AMQP cloud.
* <p>
* This is an extension to the standard QMF2 API allowing the user to specify address options in order to allow
* finer control over the Agent's ingest queue, such as an explicit name, non-default size or durability.
*
* @param conn a javax.jms.Connection.
* @param addressOptions options String giving finer grained control of the receiver queue.
* <p>
* As an example the following gives the Agent's ingest queue the name test-agent, size = 500000000 and ring policy.
* <pre>
* " ; {link: {name:'test-agent', x-declare: {arguments: {'qpid.policy_type': ring, 'qpid.max_size': 500000000}}}}"
* </pre>
*/
public final void setConnection(final Connection conn, final String addressOptions) throws QmfException {
// to the same Agent instance at the same time.
synchronized (this) {
if (_connection != null) {
throw new QmfException("Multiple connections per Agent is not supported");
}
_connection = conn;
}
if (_name == null || _vendor == null || _product == null) {
throw new QmfException("The vendor, product or name is not set");
}
setValue("_epoch", _epoch);
setValue("_heartbeat_interval", _heartbeatInterval);
setValue("_name", _name);
setValue("_product", _product);
setValue("_vendor", _vendor);
setValue("_instance", _instance);
try {
_asyncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
_syncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create a Destination for the QMF direct address, mainly used for request/response
String directBase = "qmf." + _domain + ".direct";
_quotedDirectBase = "'" + directBase + "'";
_directAddress = _syncSession.createQueue(directBase);
// Create a Destination for the QMF topic address used to broadcast Events & Heartbeats.
String topicBase = "qmf." + _domain + ".topic";
_quotedTopicBase = "'" + topicBase + "'";
_topicAddress = _syncSession.createQueue(topicBase);
// Create an unidentified MessageProducer for sending to various destinations.
_producer = _syncSession.createProducer(null);
// TODO it should be possible to bind _locateConsumer, _mainConsumer and _aliasConsumer to the
// same queue if I can figure out the correct AddressString to use, probably not a big deal though.
// Set up MessageListener on the Agent Locate Address
Destination locateAddress = _asyncSession.createQueue(topicBase + "/console.request.agent_locate");
_locateConsumer = _asyncSession.createConsumer(locateAddress);
_locateConsumer.setMessageListener(this);
// Set up MessageListener on the Agent address
String address = directBase + "/" + _name + addressOptions;
Destination agentAddress = _asyncSession.createQueue(address);
_mainConsumer = _asyncSession.createConsumer(agentAddress);
_mainConsumer.setMessageListener(this);
// alias address rather than the discovered address when talking to the broker ManagementAgent.
if (_product.equals("qpidd")) {
String alias = directBase + "/broker";
_log.info("Creating address {} as an alias address for the broker Agent", alias);
Destination aliasAddress = _asyncSession.createQueue(alias);
_aliasConsumer = _asyncSession.createConsumer(aliasAddress);
_aliasConsumer.setMessageListener(this);
}
_connection.start();
// Schedule a Heartbeat every _heartbeatInterval seconds sending the first one immediately
_timer = new Timer(true);
_timer.schedule(new Heartbeat(), 0, _heartbeatInterval * 1000);
} catch (JMSException jmse) {
// If we can't create the QMF Destinations there's not much else we can do
_log.info("JMSException {} caught in setConnection()", jmse.getMessage());
throw new QmfException("Failed to create sessions or destinations " + jmse.getMessage());
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class Console method invokeMethod.
/**
* Invoke the named method on the named Agent.
* <p>
* Intended to by called by the AgentProxy. Shouldn't generally be called directly by Console applications.
*
* @param agent the Agent to invoke the method on.
* @param content an unordered set of key/value pairs comprising the method arguments.
* @param replyHandle the correlation handle used to tie asynchronous method requests with responses
* @param timeout the time to wait for a reply from the Agent, a value of -1 means use the default timeout
* @return the method response Arguments in Map form
*/
public MethodResult invokeMethod(final Agent agent, final Map<String, Object> content, final String replyHandle, int timeout) throws QmfException {
if (!agent.isActive()) {
throw new QmfException("Called invokeMethod() with inactive agent");
}
String agentName = agent.getName();
timeout = (timeout < 1) ? _replyTimeout : timeout;
try {
Destination destination = (replyHandle == null) ? _replyAddress : _asyncReplyAddress;
MapMessage request = _syncSession.createMapMessage();
request.setJMSReplyTo(destination);
request.setJMSCorrelationID(replyHandle);
request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
request.setStringProperty("method", "request");
request.setStringProperty("qmf.opcode", "_method_request");
request.setStringProperty("qpid.subject", agentName);
for (Map.Entry<String, Object> entry : content.entrySet()) {
request.setObject(entry.getKey(), entry.getValue());
}
// it would be somewhat unfortunate if their response got interleaved with ours!!
synchronized (this) {
_requester.send(request);
if (replyHandle == null) {
// If this is a synchronous request get the response
Message response = _responder.receive(timeout * 1000);
if (response == null) {
_log.info("No response received in invokeMethod()");
throw new QmfException("No response received for Console.invokeMethod()");
}
MethodResult result = new MethodResult(AMQPMessage.getMap(response));
QmfException exception = result.getQmfException();
if (exception != null) {
throw exception;
}
return result;
}
}
// If this is an asynchronous request return without waiting for a response
return null;
} catch (JMSException jmse) {
_log.info("JMSException {} caught in invokeMethod()", jmse.getMessage());
throw new QmfException(jmse.getMessage());
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class Console method addConnection.
/**
* Connect the console to the AMQP cloud.
* <p>
* This is an extension to the standard QMF2 API allowing the user to specify address options in order to allow
* finer control over the Console's request and reply queues, e.g. explicit name, non-default size or durability.
*
* @param conn a javax.jms.Connection
* @param addressOptions options String giving finer grained control of the receiver queue.
* <p>
* As an example the following gives the Console's queues the name test-console, size = 500000000 and ring policy.
* <pre>
* " ; {link: {name:'test-console', x-declare: {arguments: {'qpid.policy_type': ring, 'qpid.max_size': 500000000}}}}"
* </pre>
* Note that the Console uses several queues so this will actually create a test-console queue plus a
* test-console-async queue and a test-console-event queue.
* <p>
* If a name parameter is not present temporary queues will be created, but the other options will still be applied.
*/
public void addConnection(final Connection conn, final String addressOptions) throws QmfException {
// to the same Console instance at the same time.
synchronized (this) {
if (_connection != null) {
throw new QmfException("Multiple connections per Console is not supported");
}
_connection = conn;
}
try {
String syncReplyAddressOptions = addressOptions;
String asyncReplyAddressOptions = addressOptions;
String eventAddressOptions = addressOptions;
if (!addressOptions.equals("")) {
// If there are address options supplied we need to check if a name parameter is present.
String[] split = addressOptions.split("name");
if (split.length == 2) {
// If options contains a name parameter we extract it and create variants for async and event queues.
// Look for the end of the key/value block
split = split[1].split("[,}]");
// Remove initial colon, space any any quotes.
String nameValue = split[0].replaceAll("[ :'\"]", "");
// Hopefully at this point nameValue is actually the value of the name parameter.
asyncReplyAddressOptions = asyncReplyAddressOptions.replace(nameValue, nameValue + "-async");
eventAddressOptions = eventAddressOptions.replace(nameValue, nameValue + "-event");
}
}
String topicBase = "qmf." + _domain + ".topic";
_syncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Create a MessageProducer for the QMF topic address used to broadcast requests
Destination topicAddress = _syncSession.createQueue(topicBase);
_broadcaster = _syncSession.createProducer(topicAddress);
// Data Indications, QMF Events, Heartbeats etc. from the broker (or other Agents).
if (!_disableEvents) {
// TODO it should be possible to bind _eventConsumer and _asyncResponder to the same queue
// if I can figure out the correct AddressString to use, probably not a big deal though.
_asyncSession = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
// Set up MessageListener on the Event Address
Destination eventAddress = _asyncSession.createQueue(topicBase + "/agent.ind.#" + eventAddressOptions);
_eventConsumer = _asyncSession.createConsumer(eventAddress);
_eventConsumer.setMessageListener(this);
// Create the asynchronous JMSReplyTo _replyAddress and MessageConsumer
_asyncReplyAddress = _asyncSession.createQueue(_address + ".async" + asyncReplyAddressOptions);
_asyncResponder = _asyncSession.createConsumer(_asyncReplyAddress);
_asyncResponder.setMessageListener(this);
}
// so makes sense if only to get that warm and fuzzy feeling of keeping findbugs happy :-)
synchronized (this) {
// Create a MessageProducer for the QMF direct address, mainly used for request/response
Destination directAddress = _syncSession.createQueue("qmf." + _domain + ".direct");
_requester = _syncSession.createProducer(directAddress);
// Create the JMSReplyTo _replyAddress and MessageConsumer
_replyAddress = _syncSession.createQueue(_address + syncReplyAddressOptions);
_responder = _syncSession.createConsumer(_replyAddress);
_connection.start();
// we've any received *real* Agent updates or not.
if (_disableEvents) {
_brokerAgentName = "broker";
Map<String, String> map = new HashMap<String, String>();
map.put("_name", _brokerAgentName);
Agent agent = new Agent(map, this);
_agents.put(_brokerAgentName, agent);
_agentAvailable = true;
} else {
// If Asynchronous Behaviour is enabled Broadcast an Agent Locate message to get Agent info quickly.
broadcastAgentLocate();
}
// Wait until the Broker Agent has been located (this should generally be pretty quick)
while (!_agentAvailable) {
long startTime = System.currentTimeMillis();
try {
wait(_replyTimeout * 1000);
} catch (InterruptedException ie) {
continue;
}
// Measure elapsed time to test against spurious wakeups and ensure we really have timed out
long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;
if (!_agentAvailable && elapsedTime >= _replyTimeout) {
_log.info("Broker Agent not found");
throw new QmfException("Broker Agent not found");
}
}
// Timer used for tidying up Subscriptions.
_timer = new Timer(true);
}
} catch (JMSException jmse) {
// If we can't create the QMF Destinations there's not much else we can do
_log.info("JMSException {} caught in addConnection()", jmse.getMessage());
throw new QmfException("Failed to create sessions or destinations " + jmse.getMessage());
}
}
Aggregations