use of org.apache.qpid.qmf2.agent.Subscription 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.agent.Subscription 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.agent.Subscription 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.agent.Subscription in project qpid by apache.
the class Agent method addObject.
/**
* Passes a reference to an instance of a managed QMF object to the Agent.
* <p>
* The object's name must uniquely identify this object among all objects known to this Agent.
* <p>
* This method creates an ObjectId for the QmfAgentData being added, it does this by first checking
* the schema.
* <p>
* If an associated schema exists we look for the set of property names that have been
* specified as idNames. If idNames exists we look for their values within the object and use that
* to create the objectName. If we can't create a sensible name we use a randomUUID.
* @param object the QmfAgentData object to be added
*/
public void addObject(final QmfAgentData object) throws QmfException {
// There are some cases where a QmfAgentData Object might have already set its ObjectId, for example where
// it may need to have a "well known" ObjectId. This is the case with the Java Broker Management Agent
// where tools such as qpid-config might have made assumptions about its ObjectId rather than doing "discovery".
ObjectId addr = object.getObjectId();
if (addr == null) {
SchemaClassId classId = object.getSchemaClassId();
SchemaClass schema = _schemaCache.get(classId);
// Try to create an objectName using the property names that have been specified as idNames in the schema
StringBuilder buf = new StringBuilder();
// Initialise idNames as an empty array as we want to check if a key has been used to construct the name.
String[] idNames = {};
if (schema != null && schema instanceof SchemaObjectClass) {
idNames = ((SchemaObjectClass) schema).getIdNames();
for (String property : idNames) {
buf.append(object.getStringValue(property));
}
}
String objectName = buf.toString();
// exchange has name == "")
if (objectName.length() == 0 && idNames.length == 0)
objectName = UUID.randomUUID().toString();
// Finish up the name by incorporating package and class names
objectName = classId.getPackageName() + ":" + classId.getClassName() + ":" + objectName;
// Now we've got a good name for the object we create its ObjectId and add that to the object
addr = new ObjectId(_name, objectName, _epoch);
object.setObjectId(addr);
}
QmfAgentData foundObject = _objectIndex.get(addr);
if (foundObject != null) {
// If a duplicate object has actually been Deleted we can reuse the address.
if (!foundObject.isDeleted()) {
throw new QmfException("Duplicate QmfAgentData Address");
}
}
_objectIndex.put(addr, object);
// Does the new object match any Subscriptions? If so add a reference to the matching Subscription and publish.
for (Subscription subscription : _subscriptions.values()) {
QmfQuery query = subscription.getQuery();
if (query.getObjectId() != null) {
if (query.getObjectId().equals(addr)) {
object.addSubscription(subscription.getSubscriptionId(), subscription);
object.publish();
}
} else if (query.evaluate(object)) {
object.addSubscription(subscription.getSubscriptionId(), subscription);
object.publish();
}
}
}
use of org.apache.qpid.qmf2.agent.Subscription in project qpid by apache.
the class AgentExternalTest method addObject.
public void addObject(QmfAgentData object) throws QmfException {
ObjectId addr = _agent.allocObjectId(UUID.randomUUID().toString());
object.setObjectId(addr);
_objectIndex.put(addr, object);
// Does the new object match any Subscriptions? If so add a reference to the matching Subscription and publish.
for (Subscription subscription : _subscriptions.values()) {
QmfQuery query = subscription.getQuery();
if (query.getObjectId() != null) {
if (query.getObjectId().equals(addr)) {
object.addSubscription(subscription.getSubscriptionId(), subscription);
object.publish();
}
} else if (query.evaluate(object)) {
object.addSubscription(subscription.getSubscriptionId(), subscription);
object.publish();
}
}
}
Aggregations