diff options
Diffstat (limited to 'qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache')
15 files changed, 3213 insertions, 0 deletions
diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentExternalTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentExternalTest.java new file mode 100644 index 0000000000..3094ba406f --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentExternalTest.java @@ -0,0 +1,558 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +// QMF2 Imports +import org.apache.qpid.qmf2.agent.AgentExternal; +import org.apache.qpid.qmf2.agent.MethodCallParams; +import org.apache.qpid.qmf2.agent.MethodCallWorkItem; +import org.apache.qpid.qmf2.agent.ResubscribeParams; +import org.apache.qpid.qmf2.agent.ResubscribeRequestWorkItem; +import org.apache.qpid.qmf2.agent.SubscribeRequestWorkItem; +import org.apache.qpid.qmf2.agent.SubscribableAgent; +import org.apache.qpid.qmf2.agent.Subscription; +import org.apache.qpid.qmf2.agent.SubscriptionParams; +import org.apache.qpid.qmf2.agent.UnsubscribeRequestWorkItem; +import org.apache.qpid.qmf2.agent.QueryWorkItem; +import org.apache.qpid.qmf2.agent.QmfAgentData; +import org.apache.qpid.qmf2.common.Handle; +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfQuery; +import org.apache.qpid.qmf2.common.QmfQueryTarget; +import org.apache.qpid.qmf2.common.QmfType; +import org.apache.qpid.qmf2.common.SchemaEventClass; +import org.apache.qpid.qmf2.common.SchemaMethod; +import org.apache.qpid.qmf2.common.SchemaObjectClass; +import org.apache.qpid.qmf2.common.SchemaProperty; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * Class used to test the AgentExternal. + * This class provides a demo of all of the features available on the AgentExternal model including Subscriptions. + * It provides essentially the same behaviour as the AgentTest class though requires a lot more code. + * + * The AgentExternal class and this demo are largely provided for completeness (although they do behave correctly) + * as the author isn't convinced that there's a good reason for using AgentExternal rather than Agent. + * + * @author Fraser Adams + */ +public final class AgentExternalTest implements QmfEventListener, SubscribableAgent +{ + /** + * This TimerTask causes the Agent to Reap any objects marked as deleted when it gets scheduled + */ + private final class Reaper extends TimerTask + { + public void run() + { + // Reap any QmfAgentData Objects that have been marked as Deleted + // Use the iterator approach rather than foreach as we may want to call iterator.remove() to zap an entry + Iterator<QmfAgentData> i = _objectIndex.values().iterator(); + while (i.hasNext()) + { + QmfAgentData object = i.next(); + if (object.isDeleted()) + { +System.out.println("****** Removing deleted Object *******"); + i.remove(); + } + } + } + } + + private AgentExternal _agent; + private QmfAgentData _control; + private SchemaObjectClass _exceptionSchema; + private SchemaObjectClass _controlSchema; + private SchemaObjectClass _childSchema; + private SchemaEventClass _eventSchema; + + /** + * objectIndex is the global index of QmfAgentData objects registered with this Agent + */ + private Map<ObjectId, QmfAgentData> _objectIndex = new ConcurrentHashMap<ObjectId, QmfAgentData>(); + + /** + * This Map is used to look up Subscriptions by SubscriptionId + */ + private Map<String, Subscription> _subscriptions = new ConcurrentHashMap<String, Subscription>(); + + private Timer _timer; + + public AgentExternalTest(String url) + { + try + { + System.out.println("** Starting AgentExternalTest a test of basic AgentExternal class functions **"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _agent = new AgentExternal(this); + _agent.setVendor("profitron.com"); + _agent.setProduct("gizmo"); + _agent.setValue("attr1", 2000); + + System.out.println("Agent name: " + _agent.getName()); + + // Schedule a Reap every 10 seconds sending the first one immediately + _timer = new Timer(true); + _timer.schedule(new Reaper(), 0, 10000); + + setupSchema(); + populateData(); + + _agent.setConnection(connection); + + for (int i = 0; i < 100; i++) + { + _control.setValue("offset", i); + //control.update(); // Send data indication to the Subscriber on the next Subscription interval + _control.publish(); // Send data indication to the Subscriber immediately + try + { + Thread.sleep(1000); + } + catch (InterruptedException ie) + { + } + } + + _control.destroy(); + + + // A getObjects call seems necessary to enable automatic reconnection when broker restarts + // I've got no idea why this is the case though!!! + //List<QmfConsoleData> connections = console.getObjects("broker"); + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: AgentExternalTest failed"); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == METHOD_CALL) + { + _control.incValue("methodCount", 1); + + MethodCallWorkItem item = (MethodCallWorkItem)wi; + MethodCallParams methodCallParams = item.getMethodCallParams(); + String methodName = methodCallParams.getName(); + ObjectId objectId = methodCallParams.getObjectId(); + String userId = methodCallParams.getUserId(); + QmfData inArgs = methodCallParams.getArgs(); + ObjectId controlAddress = _control.getObjectId(); + + System.out.println("Method Call User ID = " + userId); + + try + { + if (objectId == null) + { + // Method invoked directly on Agent + if (methodName.equals("toString")) + { + QmfData outArgs = new QmfData(); + outArgs.setValue("string", _agent.toString()); + _agent.methodResponse(methodName, item.getHandle(), outArgs, null); + } + } + else if (objectId.equals(controlAddress)) + { + if (methodName.equals("stop")) + { + System.out.println("Invoked stop method"); + String message = inArgs.getStringValue("message"); + System.out.println("Stopping: message = " + message); + _agent.methodResponse(methodName, item.getHandle(), null, null); + _agent.destroy(); + System.exit(1); + } + else if (methodName.equals("echo")) + { + System.out.println("Invoked echo method"); + _agent.methodResponse(methodName, item.getHandle(), inArgs, null); + } + else if (methodName.equals("event")) + { + System.out.println("Invoked event method"); + QmfEvent event = new QmfEvent(_eventSchema); + event.setSeverity((int)inArgs.getLongValue("severity")); + event.setValue("text", inArgs.getStringValue("text")); + _agent.raiseEvent(event); + _agent.methodResponse(methodName, item.getHandle(), null, null); + } + else if (methodName.equals("fail")) + { + System.out.println("Invoked fail method"); + QmfData error = new QmfData(); + if (inArgs.getBooleanValue("useString")) + { + error.setValue("error_text", inArgs.getStringValue("stringVal")); + } + else + { + error.setValue("whatHappened", "It Failed"); + error.setValue("howBad", 75); + error.setValue("details", inArgs.getValue("details")); + } + _agent.methodResponse(methodName, item.getHandle(), null, error); + } + else if (methodName.equals("create_child")) + { + System.out.println("Invoked create_child method"); + String childName = inArgs.getStringValue("name"); + System.out.println("childName = " + childName); + QmfAgentData child = new QmfAgentData(_childSchema); + child.setValue("name", childName); + addObject(child); + QmfData outArgs = new QmfData(); + outArgs.setRefValue("childAddr", child.getObjectId(), "reference"); // Set suptype just to test + _agent.methodResponse(methodName, item.getHandle(), outArgs, null); + } + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: AgentExternalTest failed"); + QmfData error = new QmfData(); + error.setValue("error_text", qmfe.getMessage()); + _agent.methodResponse(methodName, item.getHandle(), null, error); + } + } + + if (wi.getType() == QUERY) + { + QueryWorkItem item = (QueryWorkItem)wi; + QmfQuery query = item.getQmfQuery(); + + System.out.println("Query User ID = " + item.getUserId()); + + if (query.getObjectId() != null) + { + // 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()) + { + _agent.queryResponse(item.getHandle(), object); + } + _agent.queryComplete(item.getHandle(), 0); + } + 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........ + for (QmfAgentData object : _objectIndex.values()) + { + if (!object.isDeleted() && query.evaluate(object)) + { + _agent.queryResponse(item.getHandle(), object); + } + } + _agent.queryComplete(item.getHandle(), 0); + } + } + + if (wi.getType() == SUBSCRIBE_REQUEST) + { + SubscribeRequestWorkItem item = (SubscribeRequestWorkItem)wi; + SubscriptionParams params = item.getSubscriptionParams(); + Handle handle = item.getHandle(); + + System.out.println("Subscribe Request User ID = " + params.getUserId()); + + try + { + Subscription subscription = new Subscription(this, params); + _subscriptions.put(subscription.getSubscriptionId(), subscription); + _timer.schedule(subscription, 0, params.getPublishInterval()); + + if (subscription == null) + { +System.out.println("Requested Subscription has already expired or been cancelled"); + QmfData error = new QmfData(); + error.setValue("error_text", "Requested Subscription has already expired or been cancelled"); + _agent.subscriptionResponse(handle, subscription.getConsoleHandle(), null, 0, 0, error); + } + else + { + _agent.subscriptionResponse(handle, subscription.getConsoleHandle(), subscription.getSubscriptionId(), + subscription.getDuration(), subscription.getInterval(), null); + } + } + catch (QmfException qmfe) + { + _agent.raiseException(handle, "Subscribe Request failed, invalid Query: " + qmfe.getMessage()); + } + } + + if (wi.getType() == RESUBSCRIBE_REQUEST) + { + ResubscribeRequestWorkItem item = (ResubscribeRequestWorkItem)wi; + ResubscribeParams params = item.getResubscribeParams(); + Handle handle = item.getHandle(); + + System.out.println("Resubscribe Request User ID = " + params.getUserId()); + + String subscriptionId = params.getSubscriptionId(); + Subscription subscription = _subscriptions.get(subscriptionId); + if (subscription != null) + { + subscription.refresh(params); + _agent.subscriptionResponse(handle, subscription.getConsoleHandle(), subscription.getSubscriptionId(), + subscription.getDuration(), subscription.getInterval(), null); + } + else + { +System.out.println("Requested Subscription has already expired or been cancelled"); + QmfData error = new QmfData(); + error.setValue("error_text", "Requested Subscription has already expired or been cancelled"); + _agent.subscriptionResponse(handle, subscription.getConsoleHandle(), null, 0, 0, error); + } + } + + if (wi.getType() == UNSUBSCRIBE_REQUEST) + { + UnsubscribeRequestWorkItem item = (UnsubscribeRequestWorkItem)wi; + String subscriptionId = item.getSubscriptionId(); +System.out.println("Received cancellation request for " + subscriptionId); + Subscription subscription = _subscriptions.get(subscriptionId); + if (subscription != null) + { + subscription.cancel(); + } + } + + } + + public void setupSchema() throws QmfException + { + System.out.println("*** AgentExternalTest initialising the various Schema classes ***"); + + // Create and register schema for this agent. + String packageName = "com.profitron.gizmo"; + + // Declare a schema for a structured exception that can be used in failed method invocations. + _exceptionSchema = new SchemaObjectClass(packageName, "exception"); + _exceptionSchema.addProperty(new SchemaProperty("whatHappened", QmfType.TYPE_STRING)); + _exceptionSchema.addProperty(new SchemaProperty("howBad", QmfType.TYPE_INT)); + _exceptionSchema.addProperty(new SchemaProperty("details", QmfType.TYPE_MAP)); + + // Declare a control object to test methods against. + _controlSchema = new SchemaObjectClass(packageName, "control"); + _controlSchema.addProperty(new SchemaProperty("state", QmfType.TYPE_STRING)); + _controlSchema.addProperty(new SchemaProperty("methodCount", QmfType.TYPE_INT)); + _controlSchema.addProperty(new SchemaProperty("offset", QmfType.TYPE_INT)); + _controlSchema.setIdNames("state"); + + SchemaMethod stopMethod = new SchemaMethod("stop", "Stop Agent"); + stopMethod.addArgument(new SchemaProperty("message", QmfType.TYPE_STRING, "{dir:IN}")); + _controlSchema.addMethod(stopMethod); + + SchemaMethod echoMethod = new SchemaMethod("echo", "Echo Arguments"); + echoMethod.addArgument(new SchemaProperty("message", QmfType.TYPE_STRING, "{dir:INOUT}")); + _controlSchema.addMethod(echoMethod); + + SchemaMethod eventMethod = new SchemaMethod("event", "Raise an Event"); + eventMethod.addArgument(new SchemaProperty("text", QmfType.TYPE_STRING, "{dir:IN}")); + eventMethod.addArgument(new SchemaProperty("severity", QmfType.TYPE_INT, "{dir:IN}")); + _controlSchema.addMethod(eventMethod); + + SchemaMethod failMethod = new SchemaMethod("fail", "Expected to Fail"); + failMethod.addArgument(new SchemaProperty("useString", QmfType.TYPE_BOOL, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("stringVal", QmfType.TYPE_STRING, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("details", QmfType.TYPE_MAP, "{dir:IN}")); + _controlSchema.addMethod(failMethod); + + SchemaMethod createMethod = new SchemaMethod("create_child", "Create Child Object"); + createMethod.addArgument(new SchemaProperty("name", QmfType.TYPE_STRING, "{dir:IN}")); + createMethod.addArgument(new SchemaProperty("childAddr", QmfType.TYPE_MAP, "{dir:OUT}")); + _controlSchema.addMethod(createMethod); + + // Declare the child class + _childSchema = new SchemaObjectClass(packageName, "child"); + _childSchema.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + _childSchema.setIdNames("name"); + + // Declare the event class + _eventSchema = new SchemaEventClass(packageName, "event"); + _eventSchema.addProperty(new SchemaProperty("text", QmfType.TYPE_STRING)); + + System.out.println("AgentExternalTest Schema classes initialised OK"); + + _agent.registerObjectClass(_exceptionSchema); + _agent.registerObjectClass(_controlSchema); + _agent.registerObjectClass(_childSchema); + _agent.registerEventClass(_eventSchema); + + System.out.println("AgentExternalTest Schema classes registered OK"); + } + + public void populateData() throws QmfException + { + System.out.println("*** AgentExternalTest creating a control object ***"); + + _control = new QmfAgentData(_controlSchema); + _control.setValue("state", "OPERATIONAL"); + _control.setValue("methodCount", 0); + + addObject(_control); + System.out.println("AgentExternalTest Schema control object added OK"); + } + + 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(); + } + } + } + + + + // methods implementing SubscriberProxy interface + // ******************************************************************************************************** + + /** + * Send a list of updated subscribed data to the Console. + * + * @param handle the console reply handle + * @param results a list of subscribed data in Map encoded form + */ + public void sendSubscriptionIndicate(Handle handle, List<Map> results) + { + _agent.sendSubscriptionIndicate(handle, results); + } + + /** + * This method evaluates a QmfQuery over the Agent's data on behalf of a Subscription + * + * @param query the QmfQuery that the Subscription wants to be evaluated over the Agent's data + * @return a List of QmfAgentData objects that match the specified QmfQuery + */ + public List<QmfAgentData> evaluateQuery(QmfQuery query) + { + List<QmfAgentData> results = new ArrayList<QmfAgentData>(_objectIndex.size()); + if (query.getTarget() == QmfQueryTarget.OBJECT) + { + if (query.getObjectId() != null) + { + // 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); + } + } + else + { + // Look up QmfAgentData objects evaluating the query + for (QmfAgentData object : _objectIndex.values()) + { + if (!object.isDeleted() && query.evaluate(object)) + { + results.add(object); + } + } + } + } + return results; + } + + /** + * This method is called by the Subscription to tell the SubscriberProxy that the Subscription has been cancelled. + * + * @param subscription the Subscription that has been cancelled and is requesting removal. + */ + public void removeSubscription(Subscription subscription) + { + _subscriptions.remove(subscription.getSubscriptionId()); + } + + + public static void main(String[] args) + { + //System.out.println("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + AgentExternalTest test1 = new AgentExternalTest(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("ConnectionAudit main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending AgentExternalTest ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentSubscriptionTestConsole.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentSubscriptionTestConsole.java new file mode 100644 index 0000000000..3bc84e1ee9 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentSubscriptionTestConsole.java @@ -0,0 +1,224 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfQuery; +import org.apache.qpid.qmf2.common.QmfQueryTarget; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.AgentHeartbeatWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.EventReceivedWorkItem; +import org.apache.qpid.qmf2.console.MethodResult; +import org.apache.qpid.qmf2.console.MethodResponseWorkItem; +import org.apache.qpid.qmf2.console.ObjectUpdateWorkItem; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.console.SubscribeIndication; +import org.apache.qpid.qmf2.console.SubscribeParams; +import org.apache.qpid.qmf2.console.SubscribeResponseWorkItem; +import org.apache.qpid.qmf2.console.SubscriptionIndicationWorkItem; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * This class is the Console part of AgentTest which together provide a test of subscription behaviour + * + * N.B. AgentTest needs to be running for this test to behave as expected. + * + * @author Fraser Adams + */ +public final class AgentSubscriptionTestConsole implements QmfEventListener +{ + private Console _console; + private Agent _gizmo; + + public AgentSubscriptionTestConsole(String url) + { + try + { + System.out.println("** Starting AgentSubscriptionTestConsole used to test subscription behaviour **"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + // Wait until the gizmo Agent has been discovered + _gizmo = _console.findAgent("gizmo"); + if (_gizmo == null) + { + System.out.println("gizmo Agent not found, you probably need to run AgentTest1"); + System.exit(1); + } + + System.out.println("Creating Query for objects whose state property has a value that starts with 'OP'"); + + SubscribeParams params; + QmfQuery query = new QmfQuery(QmfQueryTarget.OBJECT, "['re_match', 'state', ['quote', '^OP']]"); + + // Create a subscription, response returned synchronously + params = _console.createSubscription(_gizmo, query, "consoleHandle1", "{publishInterval:5}"); + System.out.println("duration = " + params.getLifetime()); + System.out.println("interval = " + params.getPublishInterval()); + System.out.println("subscriptionId = " + params.getSubscriptionId()); + System.out.println("consoleHandle = " + params.getConsoleHandle()); + + // Sleep a while, getting query result as they become available + try + { + Thread.sleep(20000); + } + catch (InterruptedException ie) + { + } + + // Refresh the subscription getting results asynchronously, just for variety + System.out.println("Calling refreshSubscription on " + params.getSubscriptionId()); + _console.refreshSubscription(params.getSubscriptionId(), "{replyHandle:ignored}"); + + + // Sleep a bit more + try + { + Thread.sleep(350000); + } + catch (InterruptedException ie) + { + } + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": AgentSubscriptionTestConsole failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == AGENT_HEARTBEAT) + { + AgentHeartbeatWorkItem item = (AgentHeartbeatWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println(agent.getName()); + } + + if (wi.getType() == EVENT_RECEIVED) + { + EventReceivedWorkItem item = (EventReceivedWorkItem)wi; + Agent agent = item.getAgent(); + QmfEvent event = item.getEvent(); + + String className = event.getSchemaClassId().getClassName(); + System.out.println("Event: " + className); +//event.listValues(); + } + + if (wi.getType() == METHOD_RESPONSE) + { + MethodResponseWorkItem item = (MethodResponseWorkItem)wi; + MethodResult result = item.getMethodResult(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println(result.getStringValue("message")); + } + + if (wi.getType() == OBJECT_UPDATE) + { + ObjectUpdateWorkItem item = (ObjectUpdateWorkItem)wi; + QmfConsoleData object = item.getQmfConsoleData(); + ObjectId objectId = object.getObjectId(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println("objectId = " + objectId); + System.out.println("MethodCount = " + object.getLongValue("methodCount")); + } + + if (wi.getType() == SUBSCRIBE_RESPONSE) + { + SubscribeResponseWorkItem item = (SubscribeResponseWorkItem)wi; + SubscribeParams params = item.getSubscribeParams(); + System.out.println("duration = " + params.getLifetime()); + System.out.println("interval = " + params.getPublishInterval()); + System.out.println("subscriptionId = " + params.getSubscriptionId()); + System.out.println("consoleHandle = " + params.getConsoleHandle()); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + } + + if (wi.getType() == SUBSCRIPTION_INDICATION) + { + SubscriptionIndicationWorkItem item = (SubscriptionIndicationWorkItem)wi; + SubscribeIndication indication = item.getSubscribeIndication(); + String correlationId = indication.getConsoleHandle(); + System.out.println("correlationId = " + correlationId); + + List<QmfConsoleData> objects = indication.getData(); + for (QmfConsoleData object : objects) + { + if (object.isDeleted()) + { + System.out.println("object has been deleted"); + } + System.out.println("offset = " + object.getValue("offset")); + } + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + AgentSubscriptionTestConsole test = new AgentSubscriptionTestConsole(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("AgentSubscriptionTestConsole main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending AgentSubscriptionTestConsole ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTest.java new file mode 100644 index 0000000000..8aebe76937 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTest.java @@ -0,0 +1,298 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.agent.Agent; +import org.apache.qpid.qmf2.agent.MethodCallParams; +import org.apache.qpid.qmf2.agent.MethodCallWorkItem; +import org.apache.qpid.qmf2.agent.QmfAgentData; +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfType; +import org.apache.qpid.qmf2.common.SchemaEventClass; +import org.apache.qpid.qmf2.common.SchemaMethod; +import org.apache.qpid.qmf2.common.SchemaObjectClass; +import org.apache.qpid.qmf2.common.SchemaProperty; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * A class used to test the Agent API functionality. + * + * @author Fraser Adams + */ +public final class AgentTest implements QmfEventListener +{ + private Agent _agent; + private QmfAgentData _control; + private SchemaObjectClass _exceptionSchema; + private SchemaObjectClass _controlSchema; + private SchemaObjectClass _childSchema; + private SchemaEventClass _eventSchema; + + public AgentTest(String url) + { + try + { + System.out.println("** Starting AgentTest a test of basic Agent class functions **"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _agent = new Agent(this); + _agent.setVendor("profitron.com"); + _agent.setProduct("gizmo"); + _agent.setValue("attr1", 2000); + + System.out.println("Agent name: " + _agent.getName()); + + setupSchema(); + populateData(); + + _agent.setConnection(connection); + + for (int i = 0; i < 100; i++) + { + _control.setValue("offset", i); + //control.update(); // Send data indication to the Subscriber on the next Subscription interval + _control.publish(); // Send data indication to the Subscriber immediately + try + { + Thread.sleep(1000); + } + catch (InterruptedException ie) + { + } + } + + _control.destroy(); + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: AgentTest failed"); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + _control.incValue("methodCount", 1); + + if (wi.getType() == METHOD_CALL) + { + MethodCallWorkItem item = (MethodCallWorkItem)wi; + MethodCallParams methodCallParams = item.getMethodCallParams(); + String methodName = methodCallParams.getName(); + ObjectId objectId = methodCallParams.getObjectId(); + String userId = methodCallParams.getUserId(); + userId = userId.equals("") ? "anonymous" : userId; + QmfData inArgs = methodCallParams.getArgs(); + ObjectId controlAddress = _control.getObjectId(); + + System.out.println("Method Call User ID = " + userId); + + try + { + if (objectId == null) + { + // Method invoked directly on Agent + if (methodName.equals("toString")) + { + QmfData outArgs = new QmfData(); + outArgs.setValue("string", _agent.toString()); + _agent.methodResponse(methodName, item.getHandle(), outArgs, null); + } + } + else if (objectId.equals(controlAddress)) + { + if (methodName.equals("stop")) + { + System.out.println("Invoked stop method"); + String message = inArgs.getStringValue("message"); + System.out.println("Stopping: message = " + message); + _agent.methodResponse(methodName, item.getHandle(), null, null); + _agent.destroy(); + System.exit(1); + } + else if (methodName.equals("echo")) + { + System.out.println("Invoked echo method"); + _agent.methodResponse(methodName, item.getHandle(), inArgs, null); + } + else if (methodName.equals("event")) + { + System.out.println("Invoked event method"); + QmfEvent event = new QmfEvent(_eventSchema); + event.setSeverity((int)inArgs.getLongValue("severity")); + event.setValue("text", inArgs.getStringValue("text")); + _agent.raiseEvent(event); + _agent.methodResponse(methodName, item.getHandle(), null, null); + } + else if (methodName.equals("fail")) + { + System.out.println("Invoked fail method"); + QmfData error = new QmfData(); + if (inArgs.getBooleanValue("useString")) + { + error.setValue("error_text", inArgs.getStringValue("stringVal")); + } + else + { + error.setValue("whatHappened", "It Failed"); + error.setValue("howBad", 75); + error.setValue("details", inArgs.getValue("details")); + } + _agent.methodResponse(methodName, item.getHandle(), null, error); + } + else if (methodName.equals("create_child")) + { + System.out.println("Invoked create_child method"); + String childName = inArgs.getStringValue("name"); + System.out.println("childName = " + childName); + QmfAgentData child = new QmfAgentData(_childSchema); + child.setValue("name", childName); + _agent.addObject(child); + QmfData outArgs = new QmfData(); + outArgs.setRefValue("childAddr", child.getObjectId(), "reference"); // Set subtype just to test + _agent.methodResponse(methodName, item.getHandle(), outArgs, null); + } + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: AgentTest failed"); + QmfData error = new QmfData(); + error.setValue("error_text", qmfe.getMessage()); + _agent.methodResponse(methodName, item.getHandle(), null, error); + } + } + } + + public void setupSchema() throws QmfException + { + System.out.println("*** AgentTest initialising the various Schema classes ***"); + + // Create and register schema for this agent. + String packageName = "com.profitron.gizmo"; + + // Declare a schema for a structured exception that can be used in failed method invocations. + _exceptionSchema = new SchemaObjectClass(packageName, "exception"); + _exceptionSchema.addProperty(new SchemaProperty("whatHappened", QmfType.TYPE_STRING)); + _exceptionSchema.addProperty(new SchemaProperty("howBad", QmfType.TYPE_INT)); + _exceptionSchema.addProperty(new SchemaProperty("details", QmfType.TYPE_MAP)); + + // Declare a control object to test methods against. + _controlSchema = new SchemaObjectClass(packageName, "control"); + _controlSchema.addProperty(new SchemaProperty("state", QmfType.TYPE_STRING)); + _controlSchema.addProperty(new SchemaProperty("methodCount", QmfType.TYPE_INT)); + _controlSchema.addProperty(new SchemaProperty("offset", QmfType.TYPE_INT)); + _controlSchema.setIdNames("state"); + + SchemaMethod stopMethod = new SchemaMethod("stop", "Stop Agent"); + stopMethod.addArgument(new SchemaProperty("message", QmfType.TYPE_STRING, "{dir:IN}")); + _controlSchema.addMethod(stopMethod); + + SchemaMethod echoMethod = new SchemaMethod("echo", "Echo Arguments"); + echoMethod.addArgument(new SchemaProperty("message", QmfType.TYPE_STRING, "{dir:INOUT}")); + _controlSchema.addMethod(echoMethod); + + SchemaMethod eventMethod = new SchemaMethod("event", "Raise an Event"); + eventMethod.addArgument(new SchemaProperty("text", QmfType.TYPE_STRING, "{dir:IN}")); + eventMethod.addArgument(new SchemaProperty("severity", QmfType.TYPE_INT, "{dir:IN}")); + _controlSchema.addMethod(eventMethod); + + SchemaMethod failMethod = new SchemaMethod("fail", "Expected to Fail"); + failMethod.addArgument(new SchemaProperty("useString", QmfType.TYPE_BOOL, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("stringVal", QmfType.TYPE_STRING, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("details", QmfType.TYPE_MAP, "{dir:IN}")); + _controlSchema.addMethod(failMethod); + + SchemaMethod createMethod = new SchemaMethod("create_child", "Create Child Object"); + createMethod.addArgument(new SchemaProperty("name", QmfType.TYPE_STRING, "{dir:IN}")); + createMethod.addArgument(new SchemaProperty("childAddr", QmfType.TYPE_MAP, "{dir:OUT}")); + _controlSchema.addMethod(createMethod); + + // Declare the child class + _childSchema = new SchemaObjectClass(packageName, "child"); + _childSchema.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + _childSchema.setIdNames("name"); + + // Declare the event class + _eventSchema = new SchemaEventClass(packageName, "event"); + _eventSchema.addProperty(new SchemaProperty("text", QmfType.TYPE_STRING)); + + System.out.println("AgentTest Schema classes initialised OK"); + + _agent.registerObjectClass(_exceptionSchema); + _agent.registerObjectClass(_controlSchema); + _agent.registerObjectClass(_childSchema); + _agent.registerEventClass(_eventSchema); + + System.out.println("AgentTest Schema classes registered OK"); + } + + public void populateData() throws QmfException + { + System.out.println("*** AgentTest creating a control object ***"); + + _control = new QmfAgentData(_controlSchema); + _control.setValue("state", "OPERATIONAL"); + _control.setValue("methodCount", 0); + _agent.addObject(_control); + System.out.println("AgentTest Schema control object added OK"); + } + + + public static void main(String[] args) + { + //System.out.println("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + AgentTest test1 = new AgentTest(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("ConnectionAudit main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending AgentTest ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTestConsole.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTestConsole.java new file mode 100644 index 0000000000..edae41bcf4 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/AgentTestConsole.java @@ -0,0 +1,308 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.AgentHeartbeatWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.EventReceivedWorkItem; +import org.apache.qpid.qmf2.console.MethodResult; +import org.apache.qpid.qmf2.console.MethodResponseWorkItem; +import org.apache.qpid.qmf2.console.ObjectUpdateWorkItem; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * This class is the Console part of AgentTest which together provide a test of a number of core Console and + * Agent behaviours such as Schema creation, registration and lookup, Object lookup, method invocation on Objects + * Object refreshing (updating state of local proxy objects from the real Agent). + * + * N.B. AgentTest needs to be running for this test to behave as expected. + * + * @author Fraser Adams + */ +public final class AgentTestConsole implements QmfEventListener +{ + private Console _console; + private Agent _gizmo; + + public AgentTestConsole(String url) + { + try + { + System.out.println("*** Starting AgentTestConsole used to test basic Console and Agent behaviour ***"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + // Wait until the gizmo Agent has been discovered + synchronized(this) + { + while (_gizmo == null) + { + long startTime = System.currentTimeMillis(); + try + { + wait(10*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 (_gizmo == null && elapsedTime >= 10) + { + System.out.println("gizmo Agent not found, you probably need to run AgentTest"); + System.exit(1); + } + } + } + + System.out.println("Testing lookup of control objects by name"); + List<QmfConsoleData> controls = _console.getObjects("com.profitron.gizmo", "control"); + if (controls.size() > 0) + { + System.out.println("control object found"); + QmfConsoleData control = controls.get(0); + //control.listValues(); + + ObjectId oid = control.getObjectId(); + //System.out.println("Agent Name = " + oid.getAgentName()); + //System.out.println("Agent Epoch = " + oid.getAgentEpoch()); + //System.out.println("Object Name = " + oid.getObjectName()); + + System.out.println("Testing lookup of object by ObjectId"); + controls = _console.getObjects(oid); + + if (controls.size() == 0) + { + System.out.println("No objects returned from ObjectId lookup: AgentTestConsole failed"); + System.exit(1); + } + + System.out.println("MethodCount = " + control.getLongValue("methodCount")); + QmfData inArgs; + QmfData outArgs; + MethodResult results; + +/* + System.out.println("Testing invokeMethod(toString, args) - method called directly on Agent"); + results = _gizmo.invokeMethod("toString", null); + System.out.println("gizmo.toString() = " + results.getArguments().getStringValue("string")); +*/ + + // ********** Invoke create_child nethod ********** + System.out.println("Testing invokeMethod(create_child, args)"); + inArgs = new QmfData(); + inArgs.setValue("name", "child 1"); + + results = control.invokeMethod("create_child", inArgs); + if (!results.succeeded()) + { + System.out.println("create_child returned an exception object"); + System.exit(1); + } + + if (!results.hasValue("childAddr")) + { + System.out.println("create_child returned an unexpected value"); + System.exit(1); + } + + ObjectId childId = results.getRefValue("childAddr"); + System.out.println("childId = " + childId); + System.out.println("childAddr subtype = " + results.getSubtype("childAddr")); + QmfConsoleData child1 = _console.getObjects(childId).get(0); + System.out.println("child1 name = " + child1.getStringValue("name")); + + + // Update and display state of control object + control.refresh(); + System.out.println("MethodCount = " + control.getLongValue("methodCount")); + + + // ********** Invoke event nethod ********** + System.out.println("Testing invokeMethod(event, args) "); + inArgs = new QmfData(); + inArgs.setValue("text", "Attention Will Robinson!! Aliens have just invaded"); + inArgs.setValue("severity", 0); + control.invokeMethod("event", inArgs); + + + // Update and display state of control object + control.refresh(); + System.out.println("MethodCount = " + control.getLongValue("methodCount")); + + + // ********** Invoke fail nethod ********** + System.out.println("Testing invokeMethod(fail, args) "); + QmfData details = new QmfData(); + details.setValue("detail1", "something bad"); + details.setValue("detail2", "something even badder"); + inArgs = new QmfData(); + inArgs.setValue("details", details.mapEncode()); + results = control.invokeMethod("fail", inArgs); + System.out.println("whatHappened: " + results.getStringValue("whatHappened")); + System.out.println("howBad: " + results.getLongValue("howBad")); + + // Update and display state of control object + control.refresh(); + System.out.println("MethodCount = " + control.getLongValue("methodCount")); + + + // ********** Invoke echo nethod asynchronously ********** + System.out.println("Testing asynchronous call of invokeMethod(echo, args) "); + inArgs = new QmfData(); + inArgs.setValue("message", "This message should be echoed by the Agent"); + control.invokeMethod("echo", inArgs, "echoMethodCorrelationId"); + + + // Asynchronous update and display state of control object. The state here should be the same as + // the last time it was called as this is an asynchronous refresh. The ObjectUpdateWorkItem in + // the event handler contains the new state + control.refresh("echoMethodCorrelationId"); + System.out.println("MethodCount = " + control.getLongValue("methodCount") + " (should be same as last value)"); + + + + // ********** Invoke stop nethod, this will stop the Agent ********** + System.out.println("Testing invokeMethod(stop, args) "); + inArgs = new QmfData(); + inArgs.setValue("message", "Ladies and gentlemen Elvis has just left the building"); + control.invokeMethod("stop", inArgs); + + + } + else + { + System.out.println("No control objects returned: AgentTestConsole failed"); + System.exit(1); + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": AgentTestConsole failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == AGENT_ADDED) + { + AgentAddedWorkItem item = (AgentAddedWorkItem)wi; + Agent agent = item.getAgent(); + + // If this is the gizmo Agent we notify the main thread so processing can continue. + if (agent.getProduct().equals("gizmo")) + { + synchronized(this) + { + _gizmo = agent; + notify(); + } + } + } + + if (wi.getType() == AGENT_HEARTBEAT) + { + AgentHeartbeatWorkItem item = (AgentHeartbeatWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println(agent.getName()); + } + + if (wi.getType() == EVENT_RECEIVED) + { + EventReceivedWorkItem item = (EventReceivedWorkItem)wi; + Agent agent = item.getAgent(); + QmfEvent event = item.getEvent(); + + String className = event.getSchemaClassId().getClassName(); + System.out.println("Event: " + className); +//event.listValues(); + } + + if (wi.getType() == METHOD_RESPONSE) + { + MethodResponseWorkItem item = (MethodResponseWorkItem)wi; + MethodResult result = item.getMethodResult(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println(result.getStringValue("message")); + } + + if (wi.getType() == OBJECT_UPDATE) + { + ObjectUpdateWorkItem item = (ObjectUpdateWorkItem)wi; + QmfConsoleData object = item.getQmfConsoleData(); + ObjectId objectId = object.getObjectId(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println("objectId = " + objectId); + System.out.println("MethodCount = " + object.getLongValue("methodCount")); + } + + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + AgentTestConsole test = new AgentTestConsole(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("AgentTestConsole main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending AgentTestConsole ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTest.java new file mode 100644 index 0000000000..a6613464b5 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTest.java @@ -0,0 +1,174 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.agent.Agent; +import org.apache.qpid.qmf2.agent.MethodCallParams; +import org.apache.qpid.qmf2.agent.MethodCallWorkItem; +import org.apache.qpid.qmf2.agent.QmfAgentData; +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfType; +import org.apache.qpid.qmf2.common.SchemaEventClass; +import org.apache.qpid.qmf2.common.SchemaMethod; +import org.apache.qpid.qmf2.common.SchemaObjectClass; +import org.apache.qpid.qmf2.common.SchemaProperty; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * A class used to test the Agent API functionality. This Agent specifies an explicit queue name and a larger than + * default queue size so that it can receive large payloads on its methods. + * + * @author Fraser Adams + */ +public final class BigPayloadAgentTest implements QmfEventListener +{ + private Agent _agent; + private QmfAgentData _control; + private SchemaObjectClass _controlSchema; + + public BigPayloadAgentTest(String url) + { + try + { + System.out.println("** Starting BigPayloadAgentTest a test of basic Agent class functions **"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _agent = new Agent(this); + _agent.setVendor("test.com"); + _agent.setProduct("big-payload-agent"); + + System.out.println("Agent name: " + _agent.getName()); + + setupSchema(); + populateData(); + _agent.setConnection(connection, " ; {link: {name:'big-payload-agent', x-declare: {arguments: {'qpid.policy_type': ring, 'qpid.max_size': 500000000}}}}"); + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: BigPayloadAgentTest failed"); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == METHOD_CALL) + { + MethodCallWorkItem item = (MethodCallWorkItem)wi; + MethodCallParams methodCallParams = item.getMethodCallParams(); + String methodName = methodCallParams.getName(); + ObjectId objectId = methodCallParams.getObjectId(); + + QmfData inArgs = methodCallParams.getArgs(); + ObjectId controlAddress = _control.getObjectId(); + + if (objectId.equals(controlAddress)) + { + if (methodName.equals("processPayload")) + { + System.out.println("Invoked processPayload method"); + + byte[] parameter = inArgs.getValue("parameter"); + System.out.println("payload size = " + parameter.length); + + QmfData outArgs = new QmfData(); + outArgs.setValue("return", parameter); + _agent.methodResponse(methodName, item.getHandle(), outArgs, null); + } + } + } + } + + public void setupSchema() throws QmfException + { + System.out.println("*** BigPayloadAgentTest initialising the various Schema classes ***"); + + // Create and register schema for this agent. + String packageName = "com.test.bigagent"; + + // Declare a control object to test methods against. + _controlSchema = new SchemaObjectClass(packageName, "control"); + _controlSchema.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + _controlSchema.setIdNames("name"); + + SchemaMethod createMethod = new SchemaMethod("processPayload", "Process a large payload"); + createMethod.addArgument(new SchemaProperty("parameter", QmfType.TYPE_STRING, "{dir:IN}")); + createMethod.addArgument(new SchemaProperty("return", QmfType.TYPE_STRING, "{dir:OUT}")); + _controlSchema.addMethod(createMethod); + + System.out.println("BigPayloadAgentTest Schema classes initialised OK"); + + _agent.registerObjectClass(_controlSchema); + + System.out.println("BigPayloadAgentTest Schema classes registered OK"); + } + + public void populateData() throws QmfException + { + System.out.println("*** BigPayloadAgentTest creating a control object ***"); + + _control = new QmfAgentData(_controlSchema); + _control.setValue("name", "controller"); + _agent.addObject(_control); + System.out.println("BigPayloadAgentTest Schema control object added OK"); + } + + + public static void main(String[] args) + { + //System.out.println("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + BigPayloadAgentTest test1 = new BigPayloadAgentTest(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("ConnectionAudit main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending BigPayloadAgentTest ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTestConsole.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTestConsole.java new file mode 100644 index 0000000000..4457dea5e5 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BigPayloadAgentTestConsole.java @@ -0,0 +1,155 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.AgentHeartbeatWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.EventReceivedWorkItem; +import org.apache.qpid.qmf2.console.MethodResult; +import org.apache.qpid.qmf2.console.MethodResponseWorkItem; +import org.apache.qpid.qmf2.console.ObjectUpdateWorkItem; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * This class is the Console part of AgentTest which together provide a test of a number of core Console and + * Agent behaviours such as Schema creation, registration and lookup, Object lookup, method invocation on Objects + * Object refreshing (updating state of local proxy objects from the real Agent). + * + * N.B. AgentTest needs to be running for this test to behave as expected. + * + * @author Fraser Adams + */ +public final class BigPayloadAgentTestConsole implements QmfEventListener +{ + private Console _console; + private Agent _agent; + + public BigPayloadAgentTestConsole(String url) + { + try + { + System.out.println("*** Starting BigPayloadAgentTestConsole used to test basic Console and Agent behaviour ***"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection, " ; {link: {name:'big-payload-console', x-declare: {arguments: {'qpid.policy_type': ring, 'qpid.max_size': 500000000}}}}"); + + // Wait until the broker Agent has been discovered + _agent = _console.findAgent("big-payload-agent"); + if (_agent == null) + { + System.out.println("Big Payload Agent not found"); + System.exit(1); + } + + List<QmfConsoleData> controls = _console.getObjects("com.test.bigagent", "control"); + if (controls.size() > 0) + { + QmfConsoleData control = controls.get(0); + + // ********** Invoke processPayload nethod ********** + System.out.println("Testing invokeMethod(processPayload, args)"); + QmfData inArgs = new QmfData(); + inArgs.setValue("parameter", new byte[150000000]); + + MethodResult results = control.invokeMethod("processPayload", inArgs); + if (!results.succeeded()) + { + System.out.println("processPayload returned an exception object"); + System.exit(1); + } + + if (!results.hasValue("return")) + { + System.out.println("processPayload returned an unexpected value"); + System.exit(1); + } + + byte[] returnVal = results.getValue("return"); + System.out.println("returnVal size = " + returnVal.length); + } + else + { + System.out.println("No control objects returned: BigPayloadAgentTestConsole failed"); + System.exit(1); + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": BigPayloadAgentTestConsole failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + //System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == AGENT_HEARTBEAT) + { + AgentHeartbeatWorkItem item = (AgentHeartbeatWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println(agent.getName()); + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + BigPayloadAgentTestConsole test = new BigPayloadAgentTestConsole(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("BigPayloadAgentTestConsole main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending BigPayloadAgentTestConsole ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BrokerSubscriptionTestConsole.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BrokerSubscriptionTestConsole.java new file mode 100644 index 0000000000..27eadbaac8 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/BrokerSubscriptionTestConsole.java @@ -0,0 +1,262 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfQuery; +import org.apache.qpid.qmf2.common.QmfQueryTarget; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.AgentHeartbeatWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.EventReceivedWorkItem; +import org.apache.qpid.qmf2.console.MethodResult; +import org.apache.qpid.qmf2.console.MethodResponseWorkItem; +import org.apache.qpid.qmf2.console.ObjectUpdateWorkItem; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.console.SubscribeIndication; +import org.apache.qpid.qmf2.console.SubscribeParams; +import org.apache.qpid.qmf2.console.SubscribeResponseWorkItem; +import org.apache.qpid.qmf2.console.SubscriptionIndicationWorkItem; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * This class provides a test of broker subscription behaviour. + * <p> + * N.B. That the 0.12 C++ broker does not *actually* support subscriptions however it does periodically "push" + * QmfConsoleData Object updates as _data indications. The Console class uses these to provide client side + * emulation of broker subscriptions. One slightly subtle thing to bear in mind however is that the broker + * ManagementAgent separates "properties" and "statistics" so for example a subscription query on say a queue's + * name property will only evaluate true for a properties push and not a statistics push. The most useful usage + * pattern is likely to be a getObjects() call to return all queues, followed by a search for the queue of interest + * then a subscription with a query using the ObjectId of the wanted queue. + * + * @author Fraser Adams + */ +public final class BrokerSubscriptionTestConsole implements QmfEventListener +{ + private Console _console; + private Agent _broker; + private ObjectId _objectId; // Used to test ObjectId Query + + public BrokerSubscriptionTestConsole(String url) + { + try + { + System.out.println("** Starting BrokerSubscriptionTestConsole used to test subscription behaviour **"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + // Wait until the broker Agent has been discovered + _broker = _console.findAgent("broker"); + if (_broker == null) + { + System.out.println("broker Agent not found"); + System.exit(1); + } + + System.out.println("Creating Query for objects whose name property has a value that starts with 'a'"); + + SubscribeParams params; + QmfQuery query = new QmfQuery(QmfQueryTarget.OBJECT, "['re_match', 'name', ['quote', '^a']]"); + + // Create a subscription, response returned synchronously + params = _console.createSubscription(_broker, query, "consoleHandle1", "{publishInterval:5}"); + System.out.println("duration = " + params.getLifetime()); + System.out.println("interval = " + params.getPublishInterval()); + System.out.println("subscriptionId = " + params.getSubscriptionId()); + System.out.println("consoleHandle = " + params.getConsoleHandle()); + + // Sleep a while, getting query result as they become available + try + { + Thread.sleep(20000); + } + catch (InterruptedException ie) + { + } + + // Refresh the subscription getting results asynchronously, just for variety + System.out.println("Calling refreshSubscription on " + params.getSubscriptionId()); + _console.refreshSubscription(params.getSubscriptionId(), "{replyHandle:ignoredReplyHandle}"); + + + // Create a subscription for _class_name = queue + System.out.println("Creating Query for all queue objects"); + query = new QmfQuery(QmfQueryTarget.OBJECT, "['eq', '_class_name', ['quote', 'queue']]"); + params = _console.createSubscription(_broker, query, "queues"); + + while (_objectId == null) + { + System.out.println("Waiting for ObjectId to be set"); + try + { + Thread.sleep(1000); + } + catch (InterruptedException ie) + { + } + } + + // Cancel the query for all queue objects + System.out.println("Cancelling Query for all queue objects"); + _console.cancelSubscription(params.getSubscriptionId()); + + // Create a subscription for _object_id + System.out.println("Creating Query for _object_id = " + _objectId); + query = new QmfQuery(QmfQueryTarget.OBJECT, _objectId); + params = _console.createSubscription(_broker, query, "queues"); + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": BrokerSubscriptionTestConsole failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + System.out.println("WorkItem type: " + wi.getType()); + + if (wi.getType() == AGENT_HEARTBEAT) + { + AgentHeartbeatWorkItem item = (AgentHeartbeatWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println(agent.getName()); + } + + if (wi.getType() == EVENT_RECEIVED) + { + EventReceivedWorkItem item = (EventReceivedWorkItem)wi; + Agent agent = item.getAgent(); + QmfEvent event = item.getEvent(); + + String className = event.getSchemaClassId().getClassName(); + System.out.println("Event: " + className); +//event.listValues(); + } + + if (wi.getType() == METHOD_RESPONSE) + { + MethodResponseWorkItem item = (MethodResponseWorkItem)wi; + MethodResult result = item.getMethodResult(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println(result.getStringValue("message")); + } + + if (wi.getType() == OBJECT_UPDATE) + { + ObjectUpdateWorkItem item = (ObjectUpdateWorkItem)wi; + QmfConsoleData object = item.getQmfConsoleData(); + ObjectId objectId = object.getObjectId(); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + System.out.println("objectId = " + objectId); + System.out.println("MethodCount = " + object.getLongValue("methodCount")); + } + + if (wi.getType() == SUBSCRIBE_RESPONSE) + { + SubscribeResponseWorkItem item = (SubscribeResponseWorkItem)wi; + SubscribeParams params = item.getSubscribeParams(); + System.out.println("duration = " + params.getLifetime()); + System.out.println("interval = " + params.getPublishInterval()); + System.out.println("subscriptionId = " + params.getSubscriptionId()); + System.out.println("consoleHandle = " + params.getConsoleHandle()); + String correlationId = item.getHandle().getCorrelationId(); + System.out.println("correlationId = " + correlationId); + } + + if (wi.getType() == SUBSCRIPTION_INDICATION) + { + SubscriptionIndicationWorkItem item = (SubscriptionIndicationWorkItem)wi; + SubscribeIndication indication = item.getSubscribeIndication(); + String correlationId = indication.getConsoleHandle(); + System.out.println("correlationId = " + correlationId); + + List<QmfConsoleData> objects = indication.getData(); + for (QmfConsoleData object : objects) + { + if (object.isDeleted()) + { + System.out.println("object has been deleted"); + } + String className = object.getSchemaClassId().getClassName(); + System.out.println("object class = " + className); + if (className.equals("queue") || className.equals("exchange")) + { + if (object.hasValue("name")) + { + System.out.println("property update, name = " + object.getStringValue("name")); + } + else + { + _objectId = object.getObjectId(); + System.out.println("statistic update, oid = " + _objectId); + } + } + } + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + BrokerSubscriptionTestConsole test = new BrokerSubscriptionTestConsole(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + // Blocks here until return is pressed + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("BrokerSubscriptionTestConsole main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending BrokerSubscriptionTestConsole ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/InvokeMethodTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/InvokeMethodTest.java new file mode 100644 index 0000000000..8b175e3ca6 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/InvokeMethodTest.java @@ -0,0 +1,112 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.SchemaClass; +import org.apache.qpid.qmf2.common.SchemaClassId; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.MethodResult; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; + +/** + * This class tests invoking a method lots of times. + * + * @author Fraser Adams + */ +public final class InvokeMethodTest implements QmfEventListener +{ + private Console _console; + + public InvokeMethodTest(String url) + { + try + { + System.out.println("*** Starting InvokeMethodTest ctrl^C to exit ***"); + System.out.println("This is intended to soak test QMF2 invokeMethod, it doesn't do anything obvious"); + System.out.println("but attaching jconsole shows memory consumption. It *looks* like it's leaking"); + System.out.println("memory, but it turns out to be due to the use of a SoftReference in Qpid's"); + System.out.println("setReplyTo() method on JMSMessage. Consumption *eventually* flattens out..."); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + // First we create a large number of queues using the QMF2 create method on the broker object + List<QmfConsoleData> brokers = _console.getObjects("org.apache.qpid.broker", "broker"); + if (brokers.isEmpty()) + { + System.out.println("No broker QmfConsoleData returned"); + System.exit(1); + } + + QmfConsoleData broker = brokers.get(0); + QmfData arguments = new QmfData(); + + while (true) + { + try + { + MethodResult results = broker.invokeMethod("getLogLevel", arguments); +//System.out.println(results.getStringValue("level")); + } + catch (QmfException e) + { // This may be throw if we've already added the queues, we just catch and ignore for this test. + //System.out.println(e.getMessage()); + } + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": InvokeMethodTest failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + } + + public static void main(String[] args) + { + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + InvokeMethodTest test = new InvokeMethodTest(url); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/PartialGetObjectsTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/PartialGetObjectsTest.java new file mode 100644 index 0000000000..e42879947b --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/PartialGetObjectsTest.java @@ -0,0 +1,177 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.SchemaClass; +import org.apache.qpid.qmf2.common.SchemaClassId; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; + +/** + * This class tests the case where getObjects() returns "a lot" of objects. The broker ManagementAgent actually + * sends multiple messages in this case with the initial messages marked with a "partial" header. The Console + * getObjects() method needs to be able to support receiving multiple response messages when the "partial" + * header is set. + * + * @author Fraser Adams + */ +public final class PartialGetObjectsTest implements QmfEventListener +{ + private Console _console; + + public PartialGetObjectsTest(String url) + { + try + { + System.out.println("*** Starting PartialGetObjectsTest used to test schema retrieval ***"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + // First we create a large number of queues using the QMF2 create method on the broker object + List<QmfConsoleData> brokers = _console.getObjects("org.apache.qpid.broker", "broker"); + if (brokers.isEmpty()) + { + System.out.println("No broker QmfConsoleData returned"); + System.exit(1); + } + + QmfConsoleData broker = brokers.get(0); + QmfData arguments = new QmfData(); + arguments.setValue("type", "queue"); + + for (int i = 0; i < 300; i++) + { + arguments.setValue("name", "test " + i); + + try + { + broker.invokeMethod("create", arguments); + } + catch (QmfException e) + { // This may be throw if we've already added the queues, we just catch and ignore for this test. + //System.out.println(e.getMessage()); + } + } + + // After we've created lots of queues we attempt to list them. This list should include all the queues + // we've added irrespective of the number. + List<QmfConsoleData> queues = _console.getObjects("org.apache.qpid.broker", "queue"); + System.out.println("Call 1 Returned " + queues.size() + " objects"); + for (QmfConsoleData queue : queues) + { + String name = queue.getStringValue("name"); + System.out.println("Queue: " + name); + } + + // We get the queue objects a second time. If getObjects() correctly handles partial responses then + // this should return the complete list of queue objects, if not it will only return the subset that + // corresponds to the additional partial responses. Not handling these messages is likely to be a very + // bad thing as subsequent QMF requests will then start to receive the wrong responses. + queues = _console.getObjects("org.apache.qpid.broker", "queue"); + System.out.println("Call 2 Returned " + queues.size() + " objects"); + for (QmfConsoleData queue : queues) + { + String name = queue.getStringValue("name"); + System.out.println("Queue: " + name); + } + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": PartialGetObjectsTest failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + /* if (wi instanceof AgentAddedWorkItem) + { + AgentAddedWorkItem item = (AgentAddedWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println("\nAgent " + agent.getName() + " added "); + + // Retrieve the List of SchemaClassIds from the Agent, these will be used to retrieve the Schema. + List<SchemaClassId> schemaClassIds = _console.getClasses(agent); + + if (schemaClassIds.size() > 0) + { + // For each retrieved Class retrieve and display the Schema. + for (SchemaClassId schemaClassId : schemaClassIds) + { + List<SchemaClass> schema = _console.getSchema(schemaClassId, agent); + if (schema.size() == 1) + { + schema.get(0).listValues(); + } + } + } + else + { + System.out.println("No schema information is available for this Agent"); + } + }*/ + + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + PartialGetObjectsTest test = new PartialGetObjectsTest(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("PartialGetObjectsTest main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending PartialGetObjectsTest ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/SchemaTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/SchemaTest.java new file mode 100644 index 0000000000..f510bb201c --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/SchemaTest.java @@ -0,0 +1,126 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfData; +import org.apache.qpid.qmf2.common.QmfEvent; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.SchemaClass; +import org.apache.qpid.qmf2.common.SchemaClassId; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.AgentAddedWorkItem; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; + +/** + * This class retrieves schema information when it detects that Agents have been added. + * + * @author Fraser Adams + */ +public final class SchemaTest implements QmfEventListener +{ + private Console _console; + + public SchemaTest(String url) + { + try + { + System.out.println("*** Starting SchemaTest used to test schema retrieval ***"); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(this); + _console.addConnection(connection); + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + ": SchemaTest failed"); + System.exit(1); + } + } + + public void onEvent(WorkItem wi) + { + if (wi instanceof AgentAddedWorkItem) + { + AgentAddedWorkItem item = (AgentAddedWorkItem)wi; + Agent agent = item.getAgent(); + System.out.println("\nAgent " + agent.getName() + " added "); + + // Retrieve the List of SchemaClassIds from the Agent, these will be used to retrieve the Schema. + List<SchemaClassId> schemaClassIds = _console.getClasses(agent); + + if (schemaClassIds.size() > 0) + { + // For each retrieved Class retrieve and display the Schema. + for (SchemaClassId schemaClassId : schemaClassIds) + { + List<SchemaClass> schema = _console.getSchema(schemaClassId, agent); + if (schema.size() == 1) + { + schema.get(0).listValues(); + } + } + } + else + { + System.out.println("No schema information is available for this Agent"); + } + } + + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + SchemaTest test = new SchemaTest(url); + + BufferedReader commandLine = new BufferedReader(new InputStreamReader(System.in)); + try + { // Blocks here until return is pressed + System.out.println("Hit Return to exit"); + String s = commandLine.readLine(); + System.exit(0); + } + catch (IOException e) + { + System.out.println ("SchemaTest main(): IOException: " + e.getMessage()); + } + + System.out.println("*** Ending SchemaTest ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test1.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test1.java new file mode 100644 index 0000000000..f71f4cdf32 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test1.java @@ -0,0 +1,140 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.BlockingNotifier; +import org.apache.qpid.qmf2.common.Notifier; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; + +/** + * A class used to test the basic Console Agent discovery behaviour + * + * @author Fraser Adams + */ + +public final class Test1 +{ + private Console _console; + + public Test1(String url) + { + try + { + System.out.println("*** Starting Test1 synchronous Agent discovery ***"); + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(); + _console.addConnection(connection); + + System.out.println("*** Test1 testing _console.getAgents(): ***"); + List<Agent> agents = _console.getAgents(); + + if (agents.size() == 0) + { + System.out.println("*** Test1 failed, _console.getAgents() should return at least Broker Agent ***"); + System.exit(1); + } + + for (Agent agent : agents) + { + agent.listValues(); + } + + System.out.println("*** Test1 testing _console.getAgent(\"broker\"): ***"); + Agent agent = _console.getAgent("broker"); + agent.listValues(); + + System.out.println("*** Test1 testing _console.findAgent(\"broker\"): ***"); + agent = _console.findAgent("broker"); + if (agent == null) + { + System.out.println("*** Test1 _console.findAgent(\"broker\") returned null : Test1 failed ***"); + System.exit(1); + } + else + { + agent.listValues(); + } + + + System.out.println("*** Test1 testing _console.findAgent(\"monkey\"): ***"); + agent = _console.findAgent("monkey"); + if (agent == null) + { + System.out.println("*** Test1 _console.findAgent(\"monkey\") correctly returned null ***"); + } + else + { + agent.listValues(); + } + + + System.out.println("*** Test1 testing _console.getObjects(\"broker\"): ***"); + List<QmfConsoleData> brokers = _console.getObjects("broker"); + if (brokers.size() == 0) + { + System.out.println("*** Test1 _console.getObjects(\"broker\") should return at least one object : Test1 failed ***"); + System.exit(1); + } + else + { + for (QmfConsoleData broker : brokers) + { + broker.listValues(); + } + } + + System.out.println("*** Ending Test1 ***"); + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: Test1 failed"); + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + // As of Qpid 0.16 the Session Dispatcher Thread is non-Daemon so the JVM gets prevented from exiting. + // Setting the following property to true makes it a Daemon Thread. + System.setProperty("qpid.jms.daemon.dispatcher", "true"); + + String url = (args.length == 1) ? args[0] : "localhost"; + Test1 test1 = new Test1(url); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test2.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test2.java new file mode 100644 index 0000000000..11924f824d --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test2.java @@ -0,0 +1,121 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +import javax.jms.Connection; + +// Misc Imports +import java.io.*; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.HashMap; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.BlockingNotifier; +import org.apache.qpid.qmf2.common.Notifier; +import org.apache.qpid.qmf2.common.QmfEventListener; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfQuery; +import org.apache.qpid.qmf2.common.QmfQueryTarget; +import org.apache.qpid.qmf2.common.WorkItem; +import org.apache.qpid.qmf2.console.Agent; +import org.apache.qpid.qmf2.console.Console; +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.util.ConnectionHelper; +import static org.apache.qpid.qmf2.common.WorkItem.WorkItemType.*; + +/** + * A class used to test a non-blocking query for all Agents using the Notifier/WorkItem Event API. As most of + * the tests and samples use the alternative QmfEventListener API (because the author prefers that) rather than + * the official QMF2 WorkQueue API it seems sensible to include at least one test illustrating that. + * + * Note that in practice the WorkQueue API can also be used without an explicit notifier as one of the + * overloaded Console getNextWorkitem() methods is a blocking call to the WorkQueue that blocks until a WorkItem + * is available. The approach used in this class is for API illustration purposes and the author is unlikely to + * use it for anything useful. + * + * @author Fraser Adams + */ + +public final class Test2 +{ + private Console _console; + + public Test2(String url) + { + try + { + System.out.println("*** Starting Test2 asynchronous Agent discovery using WorkQueue API ***"); + + BlockingNotifier notifier = new BlockingNotifier(); + + Connection connection = ConnectionHelper.createConnection(url, "{reconnect: true}"); + _console = new Console(notifier); +//console.disableAgentDiscovery(); // To miss all notifications this needs done before addConnection() + _console.addConnection(connection); + + int count = 0; + while (true) + { + notifier.waitForWorkItem(); + System.out.println("WorkItem available, WorkItem count = " + _console.getWorkitemCount()); + + WorkItem wi; + while ((wi = _console.getNextWorkitem(0)) != null) + { + System.out.println("WorkItem type: " + wi.getType()); + if (wi.getType() == AGENT_HEARTBEAT || wi.getType() == AGENT_ADDED || + wi.getType() == AGENT_DELETED || wi.getType() == AGENT_RESTARTED || + wi.getType() == EVENT_RECEIVED) + { + Map<String, Object> p = wi.<Map<String, Object>>getParams(); + Agent agent = (Agent)p.get("agent"); + System.out.println(agent.getName()); + } + } + + count++; + if (count == 10) + { + System.out.println("Applying Agent Discovery Query ['eq', '_product', ['quote', 'gizmo']]"); + System.out.println("This should disable broker Agent events but allow gizmo Agent events"); + System.out.println("Run AgentTest to prove this"); + QmfQuery query = new QmfQuery(QmfQueryTarget.OBJECT, "['eq', '_product', ['quote', 'gizmo']]"); + _console.enableAgentDiscovery(query); + } + } + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: Test2 failed"); + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + String url = (args.length == 1) ? args[0] : "localhost"; + Test2 test2 = new Test2(url); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test3.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test3.java new file mode 100644 index 0000000000..fdb9180d36 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test3.java @@ -0,0 +1,137 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +// Misc Imports +import java.io.*; +import java.util.List; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfType; +import org.apache.qpid.qmf2.common.SchemaEventClass; +import org.apache.qpid.qmf2.common.SchemaMethod; +import org.apache.qpid.qmf2.common.SchemaObjectClass; +import org.apache.qpid.qmf2.common.SchemaProperty; + +/** + * A class used to test the Schema classes + * + * @author Fraser Adams + */ +public final class Test3 +{ + public Test3() + { + try + { + System.out.println("*** Starting Test3 testing the various Schema classes ***"); + + // Create and register schema for this agent. + String packageName = "com.profitron.gizmo"; + + // Declare a schema for a structured exception that can be used in failed method invocations. + SchemaObjectClass exception = new SchemaObjectClass(packageName, "exception"); + + exception.addProperty(new SchemaProperty("whatHappened", QmfType.TYPE_STRING)); + exception.addProperty(new SchemaProperty("howBad", QmfType.TYPE_INT)); + exception.addProperty(new SchemaProperty("details", QmfType.TYPE_MAP)); + + // Declare a control object to test methods against. + SchemaObjectClass control = new SchemaObjectClass(packageName, "control"); + control.addProperty(new SchemaProperty("state", QmfType.TYPE_STRING)); + control.addProperty(new SchemaProperty("methodCount", QmfType.TYPE_INT)); + + SchemaMethod stopMethod = new SchemaMethod("stop", "Stop Agent"); + stopMethod.addArgument(new SchemaProperty("message", QmfType.TYPE_STRING)); + control.addMethod(stopMethod); + + SchemaMethod echoMethod = new SchemaMethod("echo", "Echo Arguments"); + echoMethod.addArgument(new SchemaProperty("sequence", QmfType.TYPE_INT, "{dir:INOUT}")); + echoMethod.addArgument(new SchemaProperty("map", QmfType.TYPE_MAP, "{dir:INOUT}")); + control.addMethod(echoMethod); + + SchemaMethod eventMethod = new SchemaMethod("event", "Raise an Event"); + eventMethod.addArgument(new SchemaProperty("text", QmfType.TYPE_STRING, "{dir:IN}")); + eventMethod.addArgument(new SchemaProperty("severity", QmfType.TYPE_INT, "{dir:IN}")); + control.addMethod(eventMethod); + + SchemaMethod failMethod = new SchemaMethod("fail", "Expected to Fail"); + failMethod.addArgument(new SchemaProperty("useString", QmfType.TYPE_BOOL, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("stringVal", QmfType.TYPE_STRING, "{dir:IN}")); + failMethod.addArgument(new SchemaProperty("details", QmfType.TYPE_MAP, "{dir:IN}")); + control.addMethod(failMethod); + + SchemaMethod createMethod = new SchemaMethod("create_child", "Create Child Object"); + createMethod.addArgument(new SchemaProperty("name", QmfType.TYPE_STRING, "{dir:IN}")); + createMethod.addArgument(new SchemaProperty("childAddr", QmfType.TYPE_MAP, "{dir:OUT}")); + control.addMethod(createMethod); + + // Declare the child class + SchemaObjectClass child = new SchemaObjectClass(packageName, "child"); + child.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + + // Declare the event class + SchemaEventClass event = new SchemaEventClass(packageName, "event"); + event.addProperty(new SchemaProperty("text", QmfType.TYPE_STRING)); + + System.out.println("Test3 Schema classes initialised OK"); + + // Now we create new instance of each class from the map encodings and list the values + // to check everything looks OK. + + System.out.println("Test3 testing serialisation of exception schema"); + SchemaObjectClass exceptionFromMap = new SchemaObjectClass(exception.mapEncode()); + exceptionFromMap.listValues(); + System.out.println(); + + System.out.println("Test3 testing serialisation of control schema"); + SchemaObjectClass controlFromMap = new SchemaObjectClass(control.mapEncode()); + controlFromMap.listValues(); + System.out.println(); + + System.out.println("Test3 testing serialisation of child schema"); + SchemaObjectClass childFromMap = new SchemaObjectClass(child.mapEncode()); + childFromMap.listValues(); + System.out.println(); + + System.out.println("Test3 testing serialisation of event schema"); + SchemaEventClass eventFromMap = new SchemaEventClass(event.mapEncode()); + eventFromMap.listValues(); + System.out.println(); + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: Test3 failed"); + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + Test3 Test3 = new Test3(); + + System.out.println("*** Ending Test3 ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test4.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test4.java new file mode 100644 index 0000000000..29a8ba8f88 --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/Test4.java @@ -0,0 +1,339 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +// Misc Imports +import java.io.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; + +// QMF2 Imports +import org.apache.qpid.qmf2.common.ObjectId; +import org.apache.qpid.qmf2.common.QmfException; +import org.apache.qpid.qmf2.common.QmfQuery; +import org.apache.qpid.qmf2.common.QmfQueryTarget; +import org.apache.qpid.qmf2.common.QmfType; +import org.apache.qpid.qmf2.common.SchemaClass; +import org.apache.qpid.qmf2.common.SchemaClassId; +import org.apache.qpid.qmf2.common.SchemaEventClass; +import org.apache.qpid.qmf2.common.SchemaMethod; +import org.apache.qpid.qmf2.common.SchemaObjectClass; +import org.apache.qpid.qmf2.common.SchemaProperty; + +import org.apache.qpid.qmf2.console.QmfConsoleData; +import org.apache.qpid.qmf2.agent.QmfAgentData; + + +/** + * A class used to test the QmfQuery classes + * + * @author Fraser Adams + */ +public final class Test4 +{ + + private Map<SchemaClassId, SchemaClass> _schemaCache = new ConcurrentHashMap<SchemaClassId, SchemaClass>(); + private Map<ObjectId, QmfAgentData> _objectIndex = new ConcurrentHashMap<ObjectId, QmfAgentData>(); + + public Test4() + { + try + { + System.out.println("*** Starting Test4 testing the QmfQuery class ***"); + + // Create and register schema for this agent. + String packageName = "com.fadams.qmf2"; + + // Declare a mammal class to test against. + SchemaObjectClass mammal = new SchemaObjectClass(packageName, "mammal"); + mammal.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + mammal.addProperty(new SchemaProperty("legs", QmfType.TYPE_INT)); + mammal.setIdNames("name"); + + // Declare an insect class to test against. + SchemaObjectClass insect = new SchemaObjectClass(packageName, "insect"); + insect.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + insect.addProperty(new SchemaProperty("legs", QmfType.TYPE_INT)); + insect.setIdNames("name"); + + // Declare a reptile class to test against. + SchemaObjectClass reptile = new SchemaObjectClass(packageName, "reptile"); + reptile.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + reptile.addProperty(new SchemaProperty("legs", QmfType.TYPE_INT)); + reptile.setIdNames("name"); + + // Declare a bird class to test against. + SchemaObjectClass bird = new SchemaObjectClass(packageName, "bird"); + bird.addProperty(new SchemaProperty("name", QmfType.TYPE_STRING)); + bird.addProperty(new SchemaProperty("legs", QmfType.TYPE_INT)); + bird.setIdNames("name"); + + + registerObjectClass(mammal); + registerObjectClass(insect); + registerObjectClass(reptile); + registerObjectClass(bird); + + QmfAgentData cat = new QmfAgentData(mammal); + cat.setValue("name", "cat"); + cat.setValue("legs", 4l); + addObject(cat); + + QmfAgentData dog = new QmfAgentData(mammal); + dog.setValue("name", "dog"); + dog.setValue("legs", 4l); + addObject(dog); + + QmfAgentData rabbit = new QmfAgentData(mammal); + rabbit.setValue("name", "rabbit"); + rabbit.setValue("legs", 4); + addObject(rabbit); + + QmfAgentData horse = new QmfAgentData(mammal); + horse.setValue("name", "horse"); + horse.setValue("legs", 4); + addObject(horse); + + QmfAgentData human = new QmfAgentData(mammal); + human.setValue("name", "human"); + human.setValue("legs", 2); + addObject(human); + + + QmfAgentData wasp = new QmfAgentData(insect); + wasp.setValue("name", "wasp"); + wasp.setValue("legs", 6); + addObject(wasp); + + QmfAgentData ant = new QmfAgentData(insect); + ant.setValue("name", "ant"); + ant.setValue("legs", 6); + addObject(ant); + + QmfAgentData crocodile = new QmfAgentData(reptile); + crocodile.setValue("name", "crocodile"); + crocodile.setValue("legs", 4); + addObject(crocodile); + + QmfAgentData gecko = new QmfAgentData(reptile); + gecko.setValue("name", "gecko"); + gecko.setValue("legs", 4); + addObject(gecko); + + QmfAgentData python = new QmfAgentData(reptile); + python.setValue("name", "python"); + python.setValue("legs", 0); + addObject(python); + + QmfAgentData hawk = new QmfAgentData(bird); + hawk.setValue("name", "hawk"); + hawk.setValue("legs", 2); + addObject(hawk); + + QmfAgentData ostrich = new QmfAgentData(bird); + ostrich.setValue("name", "ostrich"); + ostrich.setValue("legs", 2); + addObject(ostrich); + + + System.out.println("total number of objects registered: " + _objectIndex.size()); + + QmfQuery query; + List<QmfConsoleData> results; + + System.out.println("looking up wasp object by ID"); + query = new QmfQuery(QmfQueryTarget.OBJECT, wasp.getObjectId()); + results = evaluateDataQuery(query); + displayResults(results); + + System.out.println("\nlooking up mammal objects"); + query = new QmfQuery(QmfQueryTarget.OBJECT, new SchemaClassId("mammal")); + results = evaluateDataQuery(query); + displayResults(results); + + System.out.println("\nlooking up everything in package com.fadams.qmf2"); + query = new QmfQuery(QmfQueryTarget.OBJECT, new SchemaClassId("com.fadams.qmf2", null)); + results = evaluateDataQuery(query); + displayResults(results); + + + System.out.println("\nQuery for all mammals with more than two legs"); + String predicate = "['and', ['eq', '_package_name', ['quote', 'com.fadams.qmf2']], " + + "['eq', '_class_name', ['quote', 'mammal']], " + + "['gt', 'legs', 2]]"; + + //predicate = "['eq', '_package_name', ['quote', 'com.fadams.qmf2']]"; + + //predicate = "[]"; + + query = new QmfQuery(QmfQueryTarget.OBJECT, predicate); + System.out.println(query.getPredicate()); + + results = evaluateDataQuery(query); + displayResults(results); + + + System.out.println("\nQuery for everything with less than four legs"); + predicate = "['lt', 'legs', 4]"; + + query = new QmfQuery(QmfQueryTarget.OBJECT, predicate); + System.out.println(query.getPredicate()); + + results = evaluateDataQuery(query); + displayResults(results); + + + System.out.println("\nQuery for everything with between two and four legs"); + predicate = "['and', ['ge', 'legs', 2], " + + "['le', 'legs', 4]]"; + + query = new QmfQuery(QmfQueryTarget.OBJECT, predicate); + System.out.println(query.getPredicate()); + + results = evaluateDataQuery(query); + displayResults(results); + + + System.out.println("\nQuery for all reptiles or birds"); + predicate = "['or', ['eq', '_class_name', ['quote', 'reptile']], " + + "['eq', '_class_name', ['quote', 'bird']]]"; + + query = new QmfQuery(QmfQueryTarget.OBJECT, predicate); + System.out.println(query.getPredicate()); + + results = evaluateDataQuery(query); + displayResults(results); + + + System.out.println("\nQuery for everything whose name matches the regex ^h"); + predicate = "['re_match', 'name', ['quote', '^h']]"; + + query = new QmfQuery(QmfQueryTarget.OBJECT, predicate); + System.out.println(query.getPredicate()); + + results = evaluateDataQuery(query); + displayResults(results); + + + } + catch (QmfException qmfe) + { + System.err.println("QmfException " + qmfe.getMessage() + " caught: Test4 failed"); + } + } + + public void registerObjectClass(SchemaObjectClass schema) + { + SchemaClassId classId = schema.getClassId(); + _schemaCache.put(classId, schema); + } + + public void addObject(QmfAgentData object) throws QmfException + { + SchemaClassId classId = object.getSchemaClassId(); + SchemaClass schema = _schemaCache.get(classId); + + // Try to create an objectName using the set of property names that have been specified as idNames in the schema + StringBuilder buf = new StringBuilder(); + if (schema != null && schema instanceof SchemaObjectClass) + { + String[] idNames = ((SchemaObjectClass)schema).getIdNames(); + for (String name : idNames) + { + buf.append(object.getStringValue(name)); + } + } + String objectName = buf.toString(); + + // If the schema hasn't given any help we use a UUID + if (objectName.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 it's ObjectId and add that to the object + ObjectId addr = new ObjectId("test"/*name*/, objectName, 0/*epoch*/); + object.setObjectId(addr); + + if (_objectIndex.get(addr) != null) + { + throw new QmfException("Duplicate QmfAgentData Address"); + } + + _objectIndex.put(addr, object); + } + + + public List<QmfConsoleData> evaluateDataQuery(QmfQuery query) + { + List<QmfConsoleData> results = new ArrayList<QmfConsoleData>(); + + if (query.getObjectId() != null) + { + // 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(new QmfConsoleData(object.mapEncode(), null)); + } + } + else + { + for (QmfAgentData object : _objectIndex.values()) + { + if (!object.isDeleted() && query.evaluate(object)) + { + results.add(new QmfConsoleData(object.mapEncode(), null)); + } + } + } + + return results; + } + + public List<SchemaClass> evaluateSchemaQuery(QmfQuery query) + { + return null; + } + + + public void displayResults(List<QmfConsoleData> values) + { + for (QmfConsoleData object : values) + { + System.out.println("name = " + object.getStringValue("name") + ", legs = " + object.getLongValue("legs")); + } + } + + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + Test4 Test4 = new Test4(); + + System.out.println("*** Ending Test4 ***"); + } +} diff --git a/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/URLTest.java b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/URLTest.java new file mode 100644 index 0000000000..35bd9f537b --- /dev/null +++ b/qpid/tools/src/java/qpid-qmf2-test/src/main/java/org/apache/qpid/qmf2/test/URLTest.java @@ -0,0 +1,82 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.qmf2.test; + +//import javax.jms.Connection; + +// Misc Imports +import java.io.*; + +// QMF2 Imports +import org.apache.qpid.qmf2.util.ConnectionHelper; + +/** + * A class used to test the ConnectionHelper utility, which provides support for a range of AMQP URL formats + * and a basic wrapper for Connection creation. + * + * @author Fraser Adams + */ + +public final class URLTest +{ + public static void main(String[] args) + { + //System.out.println ("Setting log level to FATAL"); + System.setProperty("amqj.logging.level", "FATAL"); + + System.out.println("Running URLTest, this tests ConnectionHelper.createConnectionURL() for various URL formats."); + System.out.println("It doesn't actually create a connection, it just displays the resulting ConnectionURL"); + + String url; + url = ConnectionHelper.createConnectionURL("localhost"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("localhost:5672", "{username: foo, password: bar, reconnect: true, reconnect_timeout: 5, reconnect_limit: 5000, tcp-nodelay: true, heartbeat: 10, protocol: ssl}"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("guest/guest@localhost:5672", "{reconnect: true, tcp-nodelay: true}"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp:localhost:5672, tcp:localhost:5673", "{reconnect: true, tcp-nodelay: true, failover: roundrobin, cyclecount: 20}"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://foo:bar@host1:1234/vhost?clientid=baz"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://localhost"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://vm:foo:1234,tcp:foo:5678/"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://host1,host2,host3/?retry=2"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://host1,host2?retry=2,host3"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://grok:hostname?flavour=strawberry;frobnication=on/vhost"); + System.out.println(url); + + url = ConnectionHelper.createConnectionURL("amqp://host?ssl=true"); + System.out.println(url); + } +} |