use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class Console method createSubscription.
/**
* Creates a subscription to the agent using the given Query.
* <p>
* The consoleHandle is an application-provided handle that will accompany each subscription update sent from
* the Agent. Subscription updates will appear as SUBSCRIPTION_INDICATION WorkItems on the Console's work queue.
* <p>
* The publishInterval is the requested time interval in seconds on which the Agent should publish updates.
* <p>
* The lifetime parameter is the requested time interval in seconds for which this subscription should remain in
* effect. Both the requested lifetime and publishInterval may be overridden by the Agent, as indicated in the
* subscription response.
* <p>
* This method may be called asynchronously by providing a replyHandle argument. When called
* asynchronously, the result of this method call is returned in a SUBSCRIBE_RESPONSE WorkItem with a
* handle matching the value of replyHandle.
* <p>
* Timeout can be used to override the console's default reply timeout.
* <p>
* When called synchronously, this method returns a SubscribeParams object containing the result of the
* subscription request.
*
* @param agent the Agent on which to create the subscription.
* @param query the Query to perform on the Agent
* @param consoleHandle an application-provided handle that will accompany each subscription update sent
* from the Agent.
* @param options a String representation of a Map containing the options in the form
* <pre>"{lifetime:<value>, publishInterval:<value>, replyHandle:<value>, timeout:<value>}"</pre>
* they are optional and may appear in any order.
* <pre>
* <b>lifetime</b> the requested time interval in seconds for which this subscription should remain in effect.
* <b>publishInterval</b> the requested time interval in seconds on which the Agent should publish updates
* <b>replyHandle</b> the correlation handle used to tie asynchronous method requests with responses.
* <b>timeout</b> the time to wait for a reply from the Agent.
* </pre>
*/
public synchronized SubscribeParams createSubscription(final Agent agent, final QmfQuery query, final String consoleHandle, final String options) throws QmfException {
if (consoleHandle == null) {
throw new QmfException("Called createSubscription() with null consoleHandle");
}
if (_subscriptionByHandle.get(consoleHandle) != null) {
throw new QmfException("Called createSubscription() with a consoleHandle that is already in use");
}
if (agent == null) {
throw new QmfException("Called createSubscription() with null agent");
}
if (!agent.isActive()) {
throw new QmfException("Called createSubscription() with inactive agent");
}
String agentName = agent.getName();
// Initialise optional values to defaults;
long lifetime = _subscriptionDuration;
long publishInterval = 10000;
long timeout = _replyTimeout;
String replyHandle = null;
if (options != null) {
// We wrap the Map in a QmfData object to avoid potential class cast issues with the parsed options
QmfData optMap = new QmfData(new AddressParser(options).map());
if (optMap.hasValue("lifetime")) {
lifetime = optMap.getLongValue("lifetime");
}
if (optMap.hasValue("publishInterval")) {
// Multiply publishInterval by 1000 because the QMF2 protocol spec says interval is
// "The request time (in milliseconds) between periodic updates of data in this subscription"
publishInterval = 1000 * optMap.getLongValue("publishInterval");
}
if (optMap.hasValue("timeout")) {
timeout = optMap.getLongValue("timeout");
}
if (optMap.hasValue("replyHandle")) {
replyHandle = optMap.getStringValue("replyHandle");
}
}
try {
MapMessage request = _syncSession.createMapMessage();
// Deliberately forcing all replies to the _asyncReplyAddress
request.setJMSReplyTo(_asyncReplyAddress);
// Deliberately using consoleHandle not replyHandle here
request.setJMSCorrelationID(consoleHandle);
request.setStringProperty("x-amqp-0-10.app-id", "qmf2");
request.setStringProperty("method", "request");
request.setStringProperty("qmf.opcode", "_subscribe_request");
request.setStringProperty("qpid.subject", agentName);
request.setObject("_query", query.mapEncode());
request.setObject("_interval", publishInterval);
request.setObject("_duration", lifetime);
SubscriptionManager subscription = new SubscriptionManager(agent, query, consoleHandle, replyHandle, publishInterval, lifetime);
_subscriptionByHandle.put(consoleHandle, subscription);
_timer.schedule(subscription, 0, publishInterval);
if (_subscriptionEmulationEnabled && agentName.equals(_brokerAgentName)) {
// If the Agent is the broker Agent we emulate the Subscription on the Console
String subscriptionId = UUID.randomUUID().toString();
_subscriptionById.put(subscriptionId, subscription);
subscription.setSubscriptionId(subscriptionId);
final SubscribeParams params = new SubscribeParams(consoleHandle, subscription.mapEncode());
if (replyHandle == null) {
return params;
} else {
final String handle = replyHandle;
Thread thread = new Thread() {
public void run() {
_eventListener.onEvent(new SubscribeResponseWorkItem(new Handle(handle), params));
}
};
thread.start();
}
return null;
}
_requester.send(request);
if (replyHandle == null) {
// If this is an synchronous request get the response
subscription.await(timeout * 1000);
if (subscription.getSubscriptionId() == null) {
_log.info("No response received in createSubscription()");
throw new QmfException("No response received for Console.createSubscription()");
}
return new SubscribeParams(consoleHandle, subscription.mapEncode());
}
// If this is an asynchronous request return without waiting for a response
return null;
} catch (JMSException jmse) {
_log.info("JMSException {} caught in createSubscription()", jmse.getMessage());
throw new QmfException(jmse.getMessage());
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class QmfManagementAgent method childAdded.
/**
* ConfigurationChangeListener method called when a child ConfiguredObject is added.
* <p>
* This method checks the type of the child ConfiguredObject that has been added and creates the equivalent
* QMF2 Management Object if one doesn't already exist. In most cases it's a one-to-one mapping, but for
* Binding for example the Binding child is added to both Queue and Exchange so we only create the Binding
* QMF2 Management Object once and add the queueRef and exchangeRef reference properties referencing the Queue
* and Exchange parent Objects respectively, Similarly for Consumer (AKA Subscription).
* <p>
* This method is also responsible for raising the appropriate QMF2 Events when Management Objects are created.
* @param object the parent object that the child is being added to.
* @param child the child object being added.
*/
@Override
public void childAdded(final ConfiguredObject object, final ConfiguredObject child) {
if (_log.isDebugEnabled()) {
_log.debug("childAdded: " + child.getClass().getSimpleName() + "." + child.getName());
}
QmfAgentData data = null;
if (child instanceof Broker) {
data = new org.apache.qpid.server.qmf2.agentdata.Broker((Broker) child);
} else if (child instanceof Connection) {
if (!agentConnection && !_objects.containsKey(child)) {
// If the parent object is the default vhost set it to null so that the Connection ignores it.
VirtualHost vhost = (object.getName().equals(_defaultVirtualHost)) ? null : (VirtualHost) object;
data = new org.apache.qpid.server.qmf2.agentdata.Connection(vhost, (Connection) child);
_objects.put(child, data);
// Raise a Client Connect Event.
_agent.raiseEvent(((org.apache.qpid.server.qmf2.agentdata.Connection) data).createClientConnectEvent());
}
// Only ignore the first Connection, which is the one from the Agent.
agentConnection = false;
} else if (child instanceof Session) {
if (!_objects.containsKey(child)) {
// Get the Connection QmfAgentData so we can get connectionRef.
QmfAgentData ref = _objects.get(object);
if (ref != null) {
data = new org.apache.qpid.server.qmf2.agentdata.Session((Session) child, ref.getObjectId());
_objects.put(child, data);
}
}
} else if (child instanceof Exchange) {
if (!_objects.containsKey(child)) {
// If the parent object is the default vhost set it to null so that the Connection ignores it.
VirtualHost vhost = (object.getName().equals(_defaultVirtualHost)) ? null : (VirtualHost) object;
data = new org.apache.qpid.server.qmf2.agentdata.Exchange(vhost, (Exchange) child);
_objects.put(child, data);
// Raise an Exchange Declare Event.
_agent.raiseEvent(((org.apache.qpid.server.qmf2.agentdata.Exchange) data).createExchangeDeclareEvent());
}
} else if (child instanceof Queue) {
if (!_objects.containsKey(child)) {
// If the parent object is the default vhost set it to null so that the Connection ignores it.
VirtualHost vhost = (object.getName().equals(_defaultVirtualHost)) ? null : (VirtualHost) object;
data = new org.apache.qpid.server.qmf2.agentdata.Queue(vhost, (Queue) child);
_objects.put(child, data);
// Raise a Queue Declare Event.
_agent.raiseEvent(((org.apache.qpid.server.qmf2.agentdata.Queue) data).createQueueDeclareEvent());
}
} else if (child instanceof Binding) {
// depending on whether Queue or Exchange was the parent of this addChild() call.
if (!_objects.containsKey(child)) {
data = new org.apache.qpid.server.qmf2.agentdata.Binding((Binding) child);
_objects.put(child, data);
String eName = ((Binding) child).getExchange().getName();
if (// Don't send Event for Binding to default direct.
!eName.equals("<<default>>")) {
// Raise a Bind Event.
_agent.raiseEvent(((org.apache.qpid.server.qmf2.agentdata.Binding) data).createBindEvent());
}
}
org.apache.qpid.server.qmf2.agentdata.Binding binding = (org.apache.qpid.server.qmf2.agentdata.Binding) _objects.get(child);
QmfAgentData ref = _objects.get(object);
if (ref != null) {
if (object instanceof Queue) {
binding.setQueueRef(ref.getObjectId());
} else if (object instanceof Exchange) {
binding.setExchangeRef(ref.getObjectId());
}
}
} else if (// AKA Subscription
child instanceof Consumer) {
// Session reference depending on whether Queue or Session was the parent of this addChild() call.
if (!_objects.containsKey(child)) {
data = new org.apache.qpid.server.qmf2.agentdata.Subscription((Consumer) child);
_objects.put(child, data);
}
org.apache.qpid.server.qmf2.agentdata.Subscription subscription = (org.apache.qpid.server.qmf2.agentdata.Subscription) _objects.get(child);
QmfAgentData ref = _objects.get(object);
if (ref != null) {
if (object instanceof Queue) {
subscription.setQueueRef(ref.getObjectId(), (Queue) object);
// Raise a Subscribe Event - N.B. Need to do it *after* we've set the queueRef.
_agent.raiseEvent(subscription.createSubscribeEvent());
} else if (object instanceof Session) {
subscription.setSessionRef(ref.getObjectId());
}
}
}
try {
// If we've created new QmfAgentData we register it with the Agent.
if (data != null) {
_agent.addObject(data);
}
} catch (QmfException qmfe) {
_log.error("QmfException caught in QmfManagementAgent.addObject()", qmfe);
}
child.addChangeListener(this);
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class QpidServer method doPost.
/**
* Called by the Web Server to allow a Server to handle a POST request.
* <pre>
* POST: <host>:<port>/qpid/connection/<name>/object/<ObjectId>
* HTTP body: {"_method_name":<method>,"_arguments":<inArgs>}
* <method>: A string containing the QMF2 method name e.g. "getLogLevel", "setLogLevel", "create", "delete".
* <inArgs>: A JSON string containing the method arguments e.g. {"level":"debug+:Broker"} for setLogLevel.
* HTTP response: A JSON string containing the response e.g. {"level":"notice+"} for getLogLevel (may be empty).
*
* This method invokes the QMF2 method <method> with arguments <inArgs> on the object <ObjectId>
* </pre>
* @param tx the HttpTransaction containing the request from the client and used to send the response.
*/
@SuppressWarnings("unchecked")
public void doPost(final HttpTransaction tx) throws IOException {
String path = tx.getRequestURI();
if (path.startsWith("/qpid/connection/")) {
path = path.substring(17);
String user = tx.getPrincipal();
String connectionName = path;
int i = path.indexOf("/");
if (// Can use > rather than >= as we've already tested for "/qpid/connection/" above.
i > 0) {
connectionName = user + "." + path.substring(0, i);
path = path.substring(i + 1);
// Find the Connection with the name extracted from the URI.
ConnectionProxy connection = _connections.get(connectionName);
if (connection == null) {
_log.info("QpidServer.doPost path: {} Connection not found.", tx.getRequestURI());
tx.sendResponse(HTTP_NOT_FOUND, "text/plain", "404 Not Found.");
} else if (!connection.isConnected()) {
tx.sendResponse(HTTP_INTERNAL_ERROR, "text/plain", "500 Broker Disconnected.");
} else {
// If we get this far we should have found a Qpid Connection so retrieve the QMF2 Console Object.
Console console = connection.getConsole();
if (path.startsWith("object/")) {
path = path.substring(7);
// The ObjectId has been passed in the URI create an ObjectId and retrieve the Agent Name.
ObjectId oid = new ObjectId(path);
String agentName = oid.getAgentName();
// The qpidd ManagementAgent doesn't populate AgentName, if it's empty assume it's the broker.
agentName = agentName.equals("") ? "broker" : agentName;
// Find the Agent we got the QmfData from.
Agent agent = console.getAgent(agentName);
if (agent == null) {
_log.info("QpidServer.doPost path: {} Agent: {} not found.", tx.getRequestURI(), agentName);
tx.sendResponse(HTTP_NOT_FOUND, "text/plain", "404 Not Found.");
} else {
// If we get this far we can create the Object and invoke the method.
// We can create a QmfConsoleData with nothing but an ObjectId and the agent.
QmfConsoleData object = new QmfConsoleData(Collections.EMPTY_MAP, agent);
object.setObjectId(oid);
String request = tx.getRequestString();
_log.info("QpidServer.doPost path: {} body: {}", tx.getRequestURI(), request);
// System.out.println(request);
String method = "";
try {
Map<String, Object> reqMap = JSON.toMap(request);
method = (String) reqMap.get("_method_name");
Object arguments = reqMap.get("_arguments");
Map args = (arguments instanceof Map) ? (Map) arguments : null;
// System.out.println("method: " + method + ", args: " + args);
// Parse the args if present into a QmfData (needed by invokeMethod).
QmfData inArgs = (args == null) ? new QmfData() : new QmfData(args);
// Invoke the specified method on the QmfConsoleData we've created.
MethodResult results = null;
_log.info("invokeMethod: {}", request);
results = object.invokeMethod(method, inArgs);
tx.sendResponse(HTTP_OK, "application/json", JSON.fromObject(results));
} catch (QmfException qmfe) {
_log.info("QpidServer.doPost() caught Exception {}", qmfe.getMessage());
tx.sendResponse(HTTP_INTERNAL_ERROR, "text/plain", "invokeMethod(" + method + ") -> " + qmfe.getMessage());
} catch (Exception e) {
_log.info("QpidServer.doPost() caught Exception {}", e.getMessage());
tx.sendResponse(HTTP_INTERNAL_ERROR, "text/plain", "500 " + e.getMessage());
}
}
} else {
tx.sendResponse(HTTP_NOT_FOUND, "text/plain", "404 Not Found.");
}
}
} else {
tx.sendResponse(HTTP_NOT_FOUND, "text/plain", "404 Not Found.");
}
} else {
tx.sendResponse(HTTP_NOT_FOUND, "text/plain", "404 Not Found.");
}
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class QpidConfig method addExchange.
/**
* Add an exchange using the QMF "create" method.
* @param args the exchange type is the first argument and the exchange name is the second argument.
* The remaining QMF method properties are populated form config parsed from the command line.
*/
private void addExchange(final String[] args) {
if (args.length < 2) {
usage();
}
Map<String, Object> properties = new HashMap<String, Object>();
if (_durable) {
properties.put("durable", true);
}
properties.put("exchange-type", args[0]);
if (_msgSequence) {
properties.put(MSG_SEQUENCE, 1l);
}
if (_ive) {
properties.put(IVE, 1l);
}
if (_altExchange != null) {
properties.put("alternate-exchange", _altExchange);
}
QmfData arguments = new QmfData();
arguments.setValue("type", "exchange");
arguments.setValue("name", args[1]);
arguments.setValue("properties", properties);
try {
_broker.invokeMethod("create", arguments);
} catch (QmfException e) {
System.out.println(e.getMessage());
}
// passive exchange creation not implemented yet (not sure how to do it using QMF2)
}
use of org.apache.qpid.qmf2.common.QmfException in project qpid by apache.
the class QpidConfig method unbind.
/**
* Remove a binding using the QMF "delete" method.
* @param args the exchange name is the first argument, the queue name is the second argument and the binding key
* is the third argument.
* The remaining QMF method properties are populated form config parsed from the command line.
*/
private void unbind(final String[] args) {
if (args.length < 2) {
usage();
}
String bindingIdentifier = args[0] + "/" + args[1];
if (args.length > 2) {
bindingIdentifier = bindingIdentifier + "/" + args[2];
}
QmfData arguments = new QmfData();
arguments.setValue("type", "binding");
arguments.setValue("name", bindingIdentifier);
try {
_broker.invokeMethod("delete", arguments);
} catch (QmfException e) {
System.out.println(e.getMessage());
}
}
Aggregations