use of org.apache.qpid.qmf2.console.Agent in project qpid by apache.
the class Agent method raiseEvent.
/**
* Cause the agent to raise the given event.
*
* @param event the QmfEvent to be raised
*/
public final void raiseEvent(final QmfEvent event) {
try {
String packageKey = event.getSchemaClassId().getPackageName().replace(".", "_");
String nameKey = event.getSchemaClassId().getClassName().replace(".", "_");
String severity = event.getSeverity();
String vendorKey = _vendor.replace(".", "_");
String productKey = _product.replace(".", "_");
String instanceKey = _instance.replace(".", "_");
String subject = "agent.ind.event." + packageKey + "." + nameKey + "." + severity + "." + vendorKey + "." + productKey + "." + instanceKey;
Message response = AMQPMessage.createListMessage(_syncSession);
response.setStringProperty("x-amqp-0-10.app-id", "qmf2");
response.setStringProperty("method", "indication");
response.setStringProperty("qmf.opcode", "_data_indication");
response.setStringProperty("qmf.content", "_event");
response.setStringProperty("qmf.agent", _name);
response.setStringProperty("qpid.subject", subject);
List<Map> results = new ArrayList<Map>();
results.add(event.mapEncode());
AMQPMessage.setList(response, results);
_producer.send(_topicAddress, response);
} catch (JMSException jmse) {
_log.info("JMSException {} caught in raiseEvent()", jmse.getMessage());
}
}
use of org.apache.qpid.qmf2.console.Agent in project qpid by apache.
the class Agent method handleQueryRequest.
/**
* Handle the query request and send the response back to the Console.
* @param handle the reply handle that contains the replyTo Address.
* @param query the inbound query from the Console.
*/
@SuppressWarnings("unchecked")
private final void handleQueryRequest(final Handle handle, final QmfQuery query) {
QmfQueryTarget target = query.getTarget();
if (target == QmfQueryTarget.SCHEMA_ID) {
List<Map> results = new ArrayList<Map>(_schemaCache.size());
// Look up all SchemaClassId objects
for (SchemaClassId classId : _schemaCache.keySet()) {
results.add(classId.mapEncode());
}
// Send the response back to the Console.
queryResponse(handle, results, "_schema_id");
} else if (target == QmfQueryTarget.SCHEMA) {
List<Map> results = new ArrayList<Map>(1);
// Look up a SchemaClass object by the SchemaClassId obtained from the query
SchemaClassId classId = query.getSchemaClassId();
SchemaClass schema = _schemaCache.get(classId);
if (schema != null) {
results.add(schema.mapEncode());
}
// Send the response back to the Console.
queryResponse(handle, results, "_schema");
} else if (target == QmfQueryTarget.OBJECT_ID) {
List<Map> results = new ArrayList<Map>(_objectIndex.size());
// Look up all ObjectId objects
for (ObjectId objectId : _objectIndex.keySet()) {
results.add(objectId.mapEncode());
}
// Send the response back to the Console.
queryResponse(handle, results, "_object_id");
} else if (target == QmfQueryTarget.OBJECT) {
// If this is implementing the AgentExternal model we pass the QmfQuery on in a QueryWorkItem
if (this instanceof AgentExternal) {
_eventListener.onEvent(new QueryWorkItem(handle, query));
return;
} else {
// qmfContentType = "_data";
if (query.getObjectId() != null) {
List<Map> results = new ArrayList<Map>(1);
// Look up a QmfAgentData object by the ObjectId obtained from the query
ObjectId objectId = query.getObjectId();
QmfAgentData object = _objectIndex.get(objectId);
if (object != null && !object.isDeleted()) {
results.add(object.mapEncode());
}
// Send the response back to the Console.
queryResponse(handle, results, "_data");
} else {
// Look up QmfAgentData objects by the SchemaClassId obtained from the query
// This is implemented by a linear search and allows searches with only the className specified.
// Linear searches clearly don't scale brilliantly, but the number of QmfAgentData objects managed
// by an Agent is generally fairly small, so it should be OK. Note that this is the same approach
// taken by the C++ broker ManagementAgent, so if it's a problem here........
// N.B. the results list declared here is a generic List of Objects. We *must* only pass a List of
// Map to queryResponse(), but conversely if the response items are sortable we need to sort them
// before doing mapEncode(). Unfortunately we don't know if the items are sortable a priori so
// we either add a Map or we add a QmfAgentData, then sort then mapEncode() each item. I'm not
// sure of a more elegant way to do this without creating two lists, which might not be so bad
// but we don't know the size of the list a priori either.
List results = new ArrayList(_objectIndex.size());
// It's unlikely that evaluating this query will return a mixture of sortable and notSortable
// QmfAgentData objects, but it's best to check if that has occurred as accidentally passing a
// List of QmfAgentData instead of a List of Map to queryResponse() will break things.
boolean sortable = false;
boolean notSortable = false;
for (QmfAgentData object : _objectIndex.values()) {
if (!object.isDeleted() && query.evaluate(object)) {
if (object.isSortable()) {
// If QmfAgentData is marked sortable we add the QmfAgentData object to the List
// so we can sort first before mapEncoding.
results.add(object);
sortable = true;
} else {
// If QmfAgentData is not marked sortable we mapEncode immediately and add the Map to List.
results.add(object.mapEncode());
notSortable = true;
}
}
}
// results List to avoid sending unconvertable data. Hopefully this condition should never occur.
if (sortable && notSortable) {
_log.info("Query resulted in inconsistent mixture of sortable and non-sortable data.");
results.clear();
} else if (sortable) {
Collections.sort(results);
int length = results.size();
for (int i = 0; i < length; i++) {
QmfAgentData object = (QmfAgentData) results.get(i);
results.set(i, object.mapEncode());
}
}
// Send the response back to the Console.
queryResponse(handle, results, "_data");
}
}
} else {
raiseException(handle, "Query for _what => '" + target + "' not supported");
return;
}
}
use of org.apache.qpid.qmf2.console.Agent in project qpid by apache.
the class Agent method registerObjectClass.
/**
* Register a schema for an object class with the Agent.
* <p>
* The Agent must have a registered schema for an object class before it can handle objects of that class.
*
* @param schema the SchemaObjectClass to be registered
*/
public final void registerObjectClass(final SchemaObjectClass schema) {
SchemaClassId classId = schema.getClassId();
_schemaCache.put(classId, schema);
}
use of org.apache.qpid.qmf2.console.Agent in project qpid by apache.
the class Agent method registerEventClass.
/**
* Register a schema for an event class with the Agent.
* <p>
* The Agent must have a registered schema for an event class before it can handle events of that class.
*
* @param schema the SchemaEventClass to be registered
*/
public final void registerEventClass(final SchemaEventClass schema) {
SchemaClassId classId = schema.getClassId();
_schemaCache.put(classId, schema);
}
use of org.apache.qpid.qmf2.console.Agent in project qpid by apache.
the class Console method getObjects.
/**
* Perform a query for QmfConsoleData objects. Returns a list (possibly empty) of matching objects.
* If replyHandle is null this method will block until the agent replies, or the timeout expires.
* Once the timeout expires, all data retrieved to date is returned. If replyHandle is non-null an
* asynchronous request is performed
*
* @param agent the Agent being queried
* @param query the ObjectId or SchemaClassId being queried for.
* @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 a List of QMF Objects describing that class
*/
private List<QmfConsoleData> getObjects(final Agent agent, final QmfData query, final String replyHandle, int timeout) {
String agentName = agent.getName();
timeout = (timeout < 1) ? _replyTimeout : timeout;
List<QmfConsoleData> results = Collections.emptyList();
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", "_query_request");
request.setStringProperty("qpid.subject", agentName);
// Create a QMF Query for an "OBJECT" target using either a schema ID or object ID
String queryType = (query instanceof SchemaClassId) ? "_schema_id" : "_object_id";
request.setObject("_what", "OBJECT");
request.setObject(queryType, query.mapEncode());
// it would be somewhat unfortunate if their response got interleaved with ours!!
synchronized (this) {
_requester.send(request);
if (replyHandle == null) {
boolean lastResult = true;
ArrayList<QmfConsoleData> partials = new ArrayList<QmfConsoleData>();
do {
// Wrap in a do/while loop to cater for the case where the Agent may send partial results.
Message response = _responder.receive(timeout * 1000);
if (response == null) {
_log.info("No response received in getObjects()");
return partials;
}
lastResult = !response.propertyExists("partial");
if (AMQPMessage.isAMQPList(response)) {
List<Map> mapResults = AMQPMessage.getList(response);
partials.ensureCapacity(partials.size() + mapResults.size());
for (Map content : mapResults) {
partials.add(new QmfConsoleData(content, agent));
}
} else if (AMQPMessage.isAMQPMap(response)) {
// Error responses are returned as MapMessages, though they are being ignored here.
// QmfData exception = new QmfData(AMQPMessage.getMap(response));
// System.out.println(agentName + " " + exception.getStringValue("error_text"));
} else {
_log.info("getObjects() Received response message in incorrect format");
}
} while (!lastResult);
results = partials;
}
}
} catch (JMSException jmse) {
_log.info("JMSException {} caught in getObjects()", jmse.getMessage());
}
return results;
}
Aggregations