You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by fa...@apache.org on 2013/04/08 17:19:09 UTC

svn commit: r1465662 [16/26] - in /qpid/trunk/qpid/tools/src/java: ./ bin/ bin/qpid-web/ bin/qpid-web/authentication/ bin/qpid-web/web/ bin/qpid-web/web/itablet/ bin/qpid-web/web/itablet/css/ bin/qpid-web/web/itablet/images/ bin/qpid-web/web/itablet/im...

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/Console.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/Console.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfEvent;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * EVENT_RECEIVED: When an Agent generates a QmfEvent an EVENT_RECEIVED WorkItem is pushed onto the work-queue.
+ *                 The WorkItem's getParam() call returns a map which contains a reference to the Console Agent
+ *                 instance that generated the Event and a reference to the QmfEvent itself. The Agent reference
+ *                 is indexed from the map using the key string "agent, The QmfEvent reference is indexed from
+ *                 the map using the key string "event". There is no handle associated with this WorkItem.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class EventReceivedWorkItem extends AgentAccessWorkItem
+{
+    /**
+     * Construct a EventReceivedWorkItem. Convenience constructor not in API
+     *
+     * @param agent the Agent used to populate the WorkItem's param
+     * @param event the QmfEvent used to populate the WorkItem's param
+     */
+    public EventReceivedWorkItem(final Agent agent, final QmfEvent event)
+    {
+        super(WorkItemType.EVENT_RECEIVED, null, newParams(agent, event));
+    }
+
+    /**
+     * Return the QmfEvent stored in the params Map.
+     * @return the QmfEvent stored in the params Map.
+     */
+    public QmfEvent getEvent()
+    {
+        Map<String, Object> p = this.<Map<String, Object>>getParams();
+        return (QmfEvent)p.get("event");
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/EventReceivedWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * METHOD_RESPONSE: The METHOD_RESPONSE WorkItem is generated in response to an asynchronous invokeMethod made
+ *                  by a QmfConsoleData object.
+ *
+ *                  The getParams() method of a METHOD_RESPONSE WorkItem will return a MethodResult object.
+ *                  The getHandle() method returns the reply handle provided to the method call.
+ *                  This handle is merely the handle used for the asynchronous response, it is not associated
+ *                  with the QmfConsoleData in any other way.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class MethodResponseWorkItem extends WorkItem
+{
+    /**
+     * Construct a MethodResponseWorkItem. Convenience constructor not in API
+     *
+     * @param handle the reply handle used to associate requests and responses
+     * @param params the MethodCallParams used to populate the WorkItem's param
+     */
+    public MethodResponseWorkItem(final Handle handle, final MethodResult params)
+    {
+        super(WorkItemType.METHOD_RESPONSE, handle, params);
+    }
+
+    /**
+     * Return the MethodResult stored in the params.
+     * @return the MethodResult stored in the params.
+     */
+    public MethodResult getMethodResult()
+    {
+        return (MethodResult)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResponseWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,151 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfData;
+import org.apache.qpid.qmf2.common.QmfException;
+
+/**
+ * The value(s) returned to the Console when the method call completes are represented by the MethodResult class.
+ * <p>
+ * The MethodResult class indicates whether the method call succeeded or not, and, on success, provides access to all
+ * data returned by the method call.
+ * <p>
+ * Returned data is provided in QmfData map indexed by the name of the parameter. The QmfData map contains only those 
+ * parameters that are classified as "output" by the SchemaMethod.
+ * <p?
+ * Should a method call result in a failure, this failure is indicated by the presence of an error object in
+ * the MethodResult. This object is represented by a QmfException object, which contains a description of the
+ * reason for the failure. There are no returned parameters when a method call fails.
+ * <p>
+ * Although not part of the QMF2 API I've made MethodResult extend QmfData so we can directly access the argument
+ * or exception values of the MethodResult object, which tends to neaten up client code.
+ *
+ * @author Fraser Adams
+ */
+public final class MethodResult extends QmfData
+{
+    private QmfData _arguments = null;
+    private QmfData _exception = null;
+
+    /**
+     * The main constructor, taking a java.util.Map as a parameter. In essence it "deserialises" its state from the Map.
+     *
+     * @param m the map used to construct the MethodResult.
+     */
+    @SuppressWarnings("unchecked")
+    public MethodResult(final Map m)
+    {
+        super(m);
+        _exception = this;
+        String opcode = (m == null || !m.containsKey("qmf.opcode")) ? "none" : (String)m.get("qmf.opcode");
+        if (m.size() == 0)
+        { // Valid response from a method returning void
+            _values = m;
+            _arguments = this;
+            _exception = null;
+        }
+        else if (opcode.equals("_method_response"))
+        {
+            Map args = (Map)m.get("_arguments");
+            if (args != null)
+            {
+                _values = args;
+                _arguments = this;
+                _exception = null;
+            }
+        }
+        else if (!opcode.equals("_exception"))
+        {
+            setValue("error_text", "Invalid response received, opcode: " + opcode);
+        }
+    }
+
+    /**
+     * Return true if the method call executed without error.
+     * @return true if the method call executed without error.
+     */
+    public boolean succeeded()
+    {
+        return (_exception == null);
+    }
+
+    /**
+     * Return the QmfData error object if method fails, else null.
+     * @return the QmfData error object if method fails, else null.
+     */
+    public QmfData getException()
+    {
+        return _exception;
+    }
+
+    /**
+     * Return a map of "name"=&lt;value&gt; pairs of all returned arguments.
+     * @return a map of "name"=&lt;value&gt; pairs of all returned arguments.
+     */
+    public QmfData getArguments()
+    {
+        return _arguments;
+    }
+
+    /**
+     * Return value of argument named "name".
+     * @return value of argument named "name".
+     */
+    public Object getArgument(final String name)
+    {
+        if (_arguments == this)
+        {
+            return getValue(name);
+        }
+        return null;
+    }
+
+    /**
+     * Return a QmfException object.
+     * @return a QmfException object.
+     * <p>
+     * If the QmfData exception object contains a String property "error_text" or "message" return a QmfException object 
+     * who's message is set to this value else return null;
+     */
+    public QmfException getQmfException()
+    {
+        if (_exception == this)
+        {
+            if (hasValue("error_text"))
+            {
+                return new QmfException(getStringValue("error_text"));
+            }
+
+            if (hasValue("message"))
+            {
+                return new QmfException(getStringValue("message"));
+            }
+        }
+        return null;
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/MethodResult.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * OBJECT_UPDATE:  The OBJECT_UPDATE WorkItem is generated in response to an asynchronous refresh made by
+ *                 a QmfConsoleData object.
+ *
+ *                 The getParams() method of an OBJECT_UPDATE WorkItem will return a QmfConsoleData.
+ *                 The getHandle() method returns the reply handle provided to the refresh() method call.
+ *                 This handle is merely the handle used for the asynchronous response, it is not associated
+ *                 with the QmfConsoleData in any other way.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class ObjectUpdateWorkItem extends WorkItem
+{
+    /**
+     * Construct a ObjectUpdateWorkItem. Convenience constructor not in API
+     *
+     * @param handle the reply handle used to associate requests and responses
+     * @param params the QmfConsoleData used to populate the WorkItem's param
+     */
+    public ObjectUpdateWorkItem(final Handle handle, final QmfConsoleData params)
+    {
+        super(WorkItemType.OBJECT_UPDATE, handle, params);
+    }
+
+    /**
+     * Return the QmfConsoleData stored in the params.
+     * @return the QmfConsoleData stored in the params.
+     */
+    public QmfConsoleData getQmfConsoleData()
+    {
+        return (QmfConsoleData)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/ObjectUpdateWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,277 @@
+/*
+ *
+ * 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.console;
+
+// Misc Imports
+import java.util.Date;
+import java.util.HashMap;
+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.QmfException;
+import org.apache.qpid.qmf2.common.QmfManaged;
+import org.apache.qpid.qmf2.common.SchemaClassId;
+
+/**
+ * Subclass of QmfManaged to provide a Console specific representation of management data.
+ * <p>
+ * The Console application represents a managed data object by the QmfConsoleData class. The Console has "read only"
+ * access to the data values in the data object via this class. The Console can also invoke the methods defined by
+ * the object via this class.
+ * <p>
+ * The actual data stored in this object is cached from the Agent. In order to update the cached values,
+ * the Console invokes the instance's refresh() method.
+ * <p>
+ * Note that the refresh() and invokeMethod() methods require communication with the remote Agent. As such, they
+ * may block. For these two methods, the Console has the option of blocking in the call until the call completes.
+ * Optionally, the Console can receive a notification asynchronously when the operation is complete.
+ *
+ * @author Fraser Adams
+ */
+public class QmfConsoleData extends QmfManaged
+{
+    private final Agent _agent;
+    private long _updateTimestamp;
+    private long _createTimestamp;
+    private long _deleteTimestamp;
+
+    /**
+     * The main constructor, taking a java.util.Map as a parameter. In essence it "deserialises" its state from the Map.
+     *
+     * @param m the map used to construct the SchemaClass.
+     * @param a the Agent that manages this object.
+     */
+    public QmfConsoleData(final Map m, final Agent a)
+    {
+        super(m);
+        long currentTime = System.currentTimeMillis()*1000000l;
+        _updateTimestamp = m.containsKey("_update_ts") ? getLong(m.get("_update_ts")) : currentTime;
+        _createTimestamp = m.containsKey("_create_ts") ? getLong(m.get("_create_ts")) : currentTime;
+        _deleteTimestamp = m.containsKey("_delete_ts") ? getLong(m.get("_delete_ts")) : currentTime;
+        _agent = a;
+    }
+
+    /**
+     * Sets the state of the QmfConsoleData, used as an assignment operator.
+     * 
+     * @param m the Map used to initialise the QmfConsoleData
+     */
+    @SuppressWarnings("unchecked")
+    public void initialise(final Map m)
+    {
+        Map<String, Object> values = (Map<String, Object>)m.get("_values");
+        _values = (values == null) ? m : values;
+
+        Map<String, String> subtypes = (Map<String, String>)m.get("_subtypes");
+        _subtypes = subtypes;
+
+        setSchemaClassId(new SchemaClassId((Map)m.get("_schema_id")));
+        setObjectId(new ObjectId((Map)m.get("_object_id")));
+
+        long currentTime = System.currentTimeMillis()*1000000l;
+        _updateTimestamp = m.containsKey("_update_ts") ? getLong(m.get("_update_ts")) : currentTime;
+        _createTimestamp = m.containsKey("_create_ts") ? getLong(m.get("_create_ts")) : currentTime;
+        _deleteTimestamp = m.containsKey("_delete_ts") ? getLong(m.get("_delete_ts")) : currentTime;
+    }
+
+    /**
+     * Sets the state of the QmfConsoleData, used as an assignment operator.
+     * 
+     * @param rhs the QmfConsoleData used to initialise the QmfConsoleData
+     */
+    public void initialise(final QmfConsoleData rhs)
+    {
+        _values = rhs._values;
+        _subtypes = rhs._subtypes;
+        setSchemaClassId(rhs.getSchemaClassId());
+        setObjectId(rhs.getObjectId());
+        _updateTimestamp = rhs._updateTimestamp;
+        _createTimestamp = rhs._createTimestamp;
+        _deleteTimestamp = rhs._deleteTimestamp;
+    }
+
+    /**
+     * Return a list of timestamps describing the lifecycle of the object.
+     * @return a list of timestamps describing the lifecycle of the object.
+     * <p>
+     * All timestamps are represented by the AMQP timestamp type recorded in nanoseconds since the epoch.
+     * <pre>
+     * [0] = time of last update from Agent,
+     * [1] = creation timestamp
+     * [2] = deletion timestamp, or zero if not deleted.
+     * </pre>
+     */
+    public final long[] getTimestamps()
+    {
+        long[] timestamps = {_updateTimestamp, _createTimestamp, _deleteTimestamp};
+        return timestamps;
+    }
+
+    /**
+     * Return the creation timestamp.
+     * @return the creation timestamp. Timestamps are recorded in nanoseconds since the epoch.
+     */
+    public final long getCreateTime()
+    {
+        return _createTimestamp;
+    }
+
+    /**
+     * Return the update timestamp.
+     * @return the update timestamp. Timestamps are recorded in nanoseconds since the epoch.
+     */
+    public final long getUpdateTime()
+    {
+        return _updateTimestamp;
+    }
+
+    /**
+     * Return the deletion timestamp, or zero if not deleted.
+     * @return the deletion timestamp, or zero if not deleted. Timestamps are recorded in nanoseconds since the epoch.
+     */
+    public final long getDeleteTime()
+    {
+        return _deleteTimestamp;
+    }
+
+    /**
+     * Return true if deletion timestamp not zero.
+     * @return true if deletion timestamp not zero.
+     */
+    public final boolean isDeleted()
+    {
+        return getDeleteTime() != 0;
+    }
+
+    /**
+     * Request that the Agent updates the value of this object's contents.
+     */    
+    public final void refresh() throws QmfException
+    {
+        refresh(-1);
+    }
+
+    /**
+     * Request that the Agent updates the value of this object's contents.
+     *
+     * @param timeout the maximum time in seconds to wait for a response, overrides default replyTimeout.
+     */    
+    public final void refresh(final int timeout) throws QmfException
+    {
+        if (_agent == null)
+        {
+            throw new QmfException("QmfConsoleData.refresh() called with null Agent");
+        }
+        QmfConsoleData newContents = _agent.refresh(getObjectId(), null, timeout);
+        if (newContents == null)
+        {
+            _deleteTimestamp = System.currentTimeMillis()*1000000l;
+        }
+        else
+        {
+            // Save the original values of create and delete timestamps as the ManagementAgent doesn't return 
+            // these on a call to getObjects(ObjectId);
+            long createTimestamp = _createTimestamp;
+            long deleteTimestamp = _deleteTimestamp;
+            initialise(newContents);
+            _createTimestamp = createTimestamp;
+            _deleteTimestamp = deleteTimestamp;
+        }
+    }
+
+    /**
+     * Request that the Agent updates the value of this object's contents asynchronously.
+     *
+     * @param replyHandle the correlation handle used to tie asynchronous refresh requests with responses.
+     */    
+    public final void refresh(final String replyHandle) throws QmfException
+    {
+        if (_agent == null)
+        {
+            throw new QmfException("QmfConsoleData.refresh() called with null Agent");
+        }
+        _agent.refresh(getObjectId(), replyHandle, -1);
+    }
+
+    /**
+     * Invoke the named method on this instance.
+     *
+     * @param name name of the method to invoke.
+     * @param inArgs inArgs an unordered set of key/value pairs comprising the method arguments.
+     * @return the MethodResult.
+     */    
+    public final MethodResult invokeMethod(final String name, final QmfData inArgs) throws QmfException
+    {
+        if (_agent == null)
+        {
+            throw new QmfException("QmfConsoleData.invokeMethod() called with null Agent");
+        }
+        return _agent.invokeMethod(getObjectId(), name, inArgs, -1);
+    }
+
+    /**
+     * Invoke the named method on this instance.
+     *
+     * @param name name of the method to invoke.
+     * @param inArgs inArgs an unordered set of key/value pairs comprising the method arguments.
+     * @param timeout the maximum time in seconds to wait for a response, overrides default replyTimeout.
+     * @return the MethodResult.
+     */    
+    public final MethodResult invokeMethod(final String name, final QmfData inArgs, final int timeout) throws QmfException
+    {
+        if (_agent == null)
+        {
+            throw new QmfException("QmfConsoleData.invokeMethod() called with null Agent");
+        }
+        return _agent.invokeMethod(getObjectId(), name, inArgs, timeout);
+    }
+
+    /**
+     * Invoke the named method asynchronously on this instance.
+     *
+     * @param name name of the method to invoke.
+     * @param inArgs inArgs an unordered set of key/value pairs comprising the method arguments.
+     * @param replyHandle the correlation handle used to tie asynchronous method requests with responses.
+     */    
+    public final void invokeMethod(final String name, final QmfData inArgs, final String replyHandle) throws QmfException
+    {
+        if (_agent == null)
+        {
+            throw new QmfException("QmfConsoleData.invokeMethod() called with null Agent");
+        }
+        _agent.invokeMethod(getObjectId(), name, inArgs, replyHandle);
+    }
+
+    /**
+     * Helper/debug method to list the QMF Object properties and their type.
+     */
+    @Override
+    public void listValues()
+    {
+        super.listValues();
+        System.out.println("_create_ts: " + new Date(getCreateTime()/1000000l));
+        System.out.println("_update_ts: " + new Date(getUpdateTime()/1000000l));
+        System.out.println("_delete_ts: " + new Date(getDeleteTime()/1000000l));
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/QmfConsoleData.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.console;
+
+import java.util.List;
+
+/**
+ * Holds the result of a subscription data indication from the Agent.
+ *
+ * @author Fraser Adams
+ */
+public final class SubscribeIndication
+{
+    private final String _consoleHandle;
+    private final List<QmfConsoleData> _data;
+
+    /**
+     * Construct a SubscribeIndication from a consoleHandle and list of QmfConsoleData.
+     * @param consoleHandle the handle containing the correlation ID.
+     * @param data the list of QmfConsoleData to pass to the Console application.
+     */
+    public SubscribeIndication(final String consoleHandle, final List<QmfConsoleData> data)
+    {
+        _consoleHandle = consoleHandle;
+        _data = data;
+    }
+
+    /**
+     * Return the console handle as passed to the createSubscription() call.
+     * @return the console handle as passed to the createSubscription() call.
+     */
+    public String getConsoleHandle()
+    {
+        return _consoleHandle;
+    }
+
+    /**
+     * Return a list containing all updated QmfData objects associated with the Subscripion.
+     * @return a list containing all updated QmfData objects associated with the Subscripion.
+     */
+    public List<QmfConsoleData> getData()
+    {
+        return _data;
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeIndication.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,130 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfData;
+
+/**
+ * Holds the result of a subscription request made by this Console.
+ * <p>
+ * The SubscriptionId object must be used when the subscription is refreshed or cancelled - it must be passed to the 
+ * Console's refreshSubscription() and cancel_subscription() methods. The value of the SubscriptionId does not
+ * change over the lifetime of the subscription.
+ * <p>
+ * The console handle will be provided by the Agent on each data indication event that corresponds to this subscription. 
+ * It should not change for the lifetime of the subscription.
+ * <p>
+ * The getHandle() method returns the reply handle provided to the createSubscription() method call. This handle
+ * is merely the handle used for the asynchronous response, it is not associated with the subscription in any other way.
+ * <p>
+ * Once a subscription is created, the Agent that maintains the subscription will periodically issue updates for the  
+ * subscribed data. This update will contain the current values of the subscribed data, and will appear as the first 
+ * SUBSCRIPTION_INDICATION WorkItem for this subscription.
+ *
+ * @author Fraser Adams
+ */
+public final class SubscribeParams extends QmfData
+{
+    private String _consoleHandle;
+
+    /**
+     * Construct SubscribeParams from a consoleHandle and the Map encoded representation.
+     * @param consoleHandle the console handle as passed to the createSubscription() call.
+     * @param m a Map containing the Map encoded representation of this SubscribeParams.
+     */
+    public SubscribeParams(final String consoleHandle, final Map m)
+    {
+        super(m);
+        _consoleHandle = consoleHandle;
+    }
+
+    /**
+     * If the subscription is successful, this method returns a SubscriptionId object.
+     * Should the subscription fail, this method returns null, and getError() can be used to obtain an
+     * application-specific QmfData error object.
+     *
+     * @return a SubscriptionId object.
+     */
+    public String getSubscriptionId()
+    {
+        if (hasValue("_subscription_id"))
+        {
+            return getStringValue("_subscription_id");
+        }
+        return null;
+    }
+
+    /**
+     * Return the time interval in seconds on which the Agent will publish updates for this subscription.
+     * @return the time interval in seconds on which the Agent will publish updates for this subscription.
+     */
+    public long getPublishInterval()
+    {
+        return getLongValue("_interval");
+    }
+
+    /**
+     * Return the lifetime in seconds for the subscription.
+     * @return the lifetime in seconds for the subscription. The subscription will automatically expire after
+     *         this interval if not renewed by the console.
+     */
+    public long getLifetime()
+    {
+        return getLongValue("_duration");
+    }
+
+    /**
+     * Return the QmfData error object if method fails, else null.
+     * @return the QmfData error object if method fails, else null.
+     */
+    public QmfData getError()
+    {
+        if (getSubscriptionId() == null)
+        {
+            return this;
+        }
+        return null;
+    }
+
+    /**
+     * Sets the consoleHandle.
+     * @param consoleHandle the new console handle.
+     */
+    public void setConsoleHandle(final String consoleHandle)
+    {
+        _consoleHandle = consoleHandle;
+    }
+
+    /**
+     * Return the console handle as passed to the createSubscription() call.
+     * @return the console handle as passed to the createSubscription() call.
+     */
+    public String getConsoleHandle()
+    {
+        return _consoleHandle;
+    }
+}
+
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeParams.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,80 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * SUBSCRIBE_RESPONSE: The SUBSCRIBE_RESPONSE WorkItem returns the result of a subscription request made by
+ *                     this Console.  This WorkItem is generated when the Console's createSubscription() is
+ *                     called in an asychronous manner, rather than pending for the result. 
+ *
+ *                     The getParams() method of a SUBSCRIBE_RESPONSE  WorkItem will return an instance of the
+ *                     SubscribeParams class.
+ *
+ *                     The SubscriptionId object must be used when the subscription is refreshed or cancelled.
+ *                     It must be passed to the Console's refresh_subscription() and cancelSubscription() methods.
+ *                     The value of the SubscriptionId does not change over the lifetime of the subscription.
+ *
+ *                     The console handle will be provided by the Agent on each data indication event that
+ *                     corresponds to this subscription.  It should not change for the lifetime of the subscription.
+ *
+ *                     The getHandle() method returns the reply handle provided to the createSubscription()
+ *                     method call.  This handle is merely the handle used for the asynchronous response, it is
+ *                     not associated with the subscription in any other way.
+ *
+ *                     Once a subscription is created, the Agent that maintains the subscription will periodically
+ *                     issue updates for the subscribed data.  This update will contain the current values of the   
+ *                     subscribed data, and will appear as the first SUBSCRIPTION_INDICATION WorkItem for this
+ *                     subscription.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class SubscribeResponseWorkItem extends WorkItem
+{
+    /**
+     * Construct a SubscribeResponseWorkItem. Convenience constructor not in API
+     *
+     * @param handle the reply handle used to associate requests and responses
+     * @param params the SubscribeParams used to populate the WorkItem's param
+     */
+    public SubscribeResponseWorkItem(final Handle handle, final SubscribeParams params)
+    {
+        super(WorkItemType.SUBSCRIBE_RESPONSE, handle, params);
+    }
+
+    /**
+     * Return the SubscribeParams stored in the params.
+     * @return the SubscribeParams stored in the params.
+     */
+    public SubscribeParams getSubscribeParams()
+    {
+        return (SubscribeParams)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscribeResponseWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.console;
+
+import java.util.Map;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.Handle;
+import org.apache.qpid.qmf2.common.WorkItem;
+
+/**
+ * Descriptions below are taken from <a href=https://cwiki.apache.org/qpid/qmfv2-api-proposal.html>QMF2 API Proposal</a> 
+ * <pre>
+ * SUBSCRIPTION_INDICATION: The SUBSCRIPTION_INDICATION WorkItem signals the arrival of an update to subscribed
+ *                          data from the Agent. 
+ *
+ *                          The getParams() method of a SUBSCRIPTION_INDICATION  WorkItem will return an instance
+ *                          of the SubscribeIndication class. The getHandle() method returns null.
+ * </pre>
+ * @author Fraser Adams
+ */
+
+public final class SubscriptionIndicationWorkItem extends WorkItem
+{
+    /**
+     * Construct a SubscriptionIndicationWorkItem. Convenience constructor not in API
+     *
+     * @param params the SubscribeParams used to populate the WorkItem's param
+     */
+    public SubscriptionIndicationWorkItem(final SubscribeIndication params)
+    {
+        super(WorkItemType.SUBSCRIPTION_INDICATION, null, params);
+    }
+
+    /**
+     * Return the SubscribeIndication stored in the params.
+     * @return the SubscribeIndication stored in the params.
+     */
+    public SubscribeIndication getSubscribeIndication()
+    {
+        return (SubscribeIndication)getParams();
+    }
+}
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionIndicationWorkItem.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,255 @@
+/*
+ *
+ * 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.console;
+
+// Simple Logging Facade 4 Java
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// Misc Imports
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimerTask;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.QmfQuery;
+
+/** 
+ * A SubscriptionManager represents a running Subscription on the Console.
+ * <p>
+ * The main reason we have SubscriptionManagers as TimerTasks is to enable proper cleanup of the references stored in
+ * the subscriptionByHandle and subscriptionById Maps. Ideally these will be cleaned up by a client calling 
+ * cancelSubscription but we can't rely on that as the client may forget or the Agent may not respond.
+ * <p>
+ * The SubscriptionManager acts like a client/Console side representation of a Subscription running on an Agent.
+ * As mentioned above its primary purpose is to enable references to Subscriptions maintained by the Console to
+ * be cleaned up should the Subscription time out rather than being cancelled, however as a side effect it is
+ * used to enable emulation of Subscriptions to the broker ManagementAgent, which does not yet natively implement
+ * Subscription.
+ * <p>
+ * To emulate Subscriptions the Console receives the periodic _data indications pushed by the ManagementAgent. The
+ * Console then iterates through Subscriptions referencing the broker Agent and evaluates their queries against
+ * the QmfConsoleData returned by the _data indication. Any QmfConsoleData that match the query are passed to the
+ * client application with the consoleHandle of the matching Subscription.
+ * <p>
+ * The following diagram illustrates the Subscription relationships with the Console and local Agent proxy.
+ * <p>
+ * <img src="doc-files/Subscriptions.png"/>
+ *
+ * @author Fraser Adams
+ */
+public final class SubscriptionManager extends TimerTask
+{
+    private static final Logger _log = LoggerFactory.getLogger(SubscriptionManager.class);
+
+    private final Agent _agent;
+    private long     _startTime = System.currentTimeMillis();
+    private String   _subscriptionId;
+    private String   _consoleHandle;
+    private String   _replyHandle;
+    private QmfQuery _query;
+    private long     _duration = 0;
+    private long     _interval = 0;
+    private boolean  _waiting = true;
+
+    /**
+     * Construct a Console side proxy of a Subscription. Primarily to manage references to the Subscription.
+     *
+     * @param agent the Agent from which the Subscription has been requested
+     * @param query the QmfQuery that the Subscription will run
+     * @param consoleHandle the handle that uniquely identifies the Subscription
+     * @param interval the interval between subscription updates
+     * @param duration the duration of the subscription (assuming it doesn't get refreshed)
+     */
+    SubscriptionManager(final Agent agent, final QmfQuery query, final String consoleHandle,
+                        final String replyHandle, final long interval, final long duration)
+    {
+        _agent = agent;
+        _query = query;
+        _consoleHandle = consoleHandle;
+        _replyHandle = replyHandle;
+        _interval = interval;
+        _duration = duration;
+        _log.debug("Creating SubscriptionManager {}, on Agent {}",_consoleHandle, _agent.getName());
+    }
+
+    /**
+     * This method gets called periodically by the Timer scheduling this TimerTask.
+     * <p>
+     * First a check is made to see if the Subscription has expired, if it has then it is cancelled.
+     */
+    public void run()
+    {
+        long elapsed = (long)Math.round((System.currentTimeMillis() - _startTime)/1000.0f);
+        if (elapsed >= _duration || !_agent.isActive())
+        {
+            _log.debug("Subscription {} has expired, removing", _subscriptionId);
+            // The Subscription has expired so cancel it
+            cancel();
+        }
+    }
+
+    /**
+     * Causes the current thread to wait until it is signalled or times out.
+     * <p>
+     * This method is primarily used as a means to enable a synchronous call to createSubscription().
+     * For most synchronous calls we simply use the receive() call on the synchronous session, but we can't do that
+     * for createSubscription() as we specifically need to use the replyTo on the asynchronous session as once
+     * subscriptions are created the results are asynchronously pushed. This means we have to get the response to 
+     * createSession() on the asynchronous replyTo then signal the (blocked) main thread that the response has
+     * been received.
+     *
+     * @param timeout the maximum time to wait to be signalled.
+     */
+    public synchronized void await(final long timeout)
+    {
+        while (_waiting)
+        {
+            long _startTime = System.currentTimeMillis();
+            try
+            {
+                wait(timeout);
+            }
+            catch (InterruptedException ie)
+            {
+                continue;
+            }
+            // Measure elapsed time to test against spurious wakeups and ensure we really have timed out
+            long elapsedTime = (System.currentTimeMillis() - _startTime);
+            if (elapsedTime >= timeout)
+            {
+                break;
+            }
+        }
+        _waiting = true;
+    }
+
+    /**
+     * Wakes up all waiting threads.
+     */
+    public synchronized void signal()
+    {
+        _waiting = false;
+        notifyAll();
+    }
+
+    /**
+     * Refresh the subscription by zeroing its elapsed time.
+     */
+    public void refresh()
+    {
+        _log.debug("Refreshing Subscription {}", _subscriptionId);
+        _startTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Cancel the Subscription, tidying references up and cancelling the TimerTask.
+     */
+    @Override
+    public boolean cancel()
+    {
+        _log.debug("Cancelling Subscription {}, {}", _consoleHandle, _subscriptionId);
+        _agent.removeSubscription(this);
+        signal(); // Just in case anything is blocking on this Subscription.
+        return super.cancel(); // Cancel the TimerTask
+    }
+
+    /**
+     * Set the SubscriptionId.
+     * @param subscriptionId the new SubscriptionId of this Subscription.
+     */
+    public void setSubscriptionId(final String subscriptionId)
+    {
+        _subscriptionId = subscriptionId;
+    }
+
+    /**
+     * return the SubscriptionId of this Subscription.
+     * @return the SubscriptionId of this Subscription.
+     */
+    public String getSubscriptionId()
+    {
+        return _subscriptionId;
+    }
+
+    /**
+     * Return the consoleHandle of this Subscription.
+     * @return the consoleHandle of this Subscription.
+     */
+    public String getConsoleHandle()
+    {
+        return _consoleHandle;
+    }
+
+    /**
+     * Return the replyHandle of this Subscription.
+     * @return the replyHandle of this Subscription.
+     */
+    public String getReplyHandle()
+    {
+        return _replyHandle;
+    }
+
+    /**
+     * Return the Agent running this Subscription.
+     * @return the Agent running this Subscription.
+     */
+    public Agent getAgent()
+    {
+        return _agent;
+    }
+
+    /**
+     * Set the Subscription lifetime in seconds.
+     *
+     * @param duration the new Subscription lifetime in seconds
+     */
+    public void setDuration(final long duration)
+    {
+        _duration = duration;
+    }
+
+    /**
+     * Return The Subscription's QmfQuery.
+     * @return The Subscription's QmfQuery.
+     */
+    public QmfQuery getQuery()
+    {
+        return _query;
+    }
+
+    /**
+     * Create a Map encoded version.
+     * <p>
+     * When we do a synchronous createSubscription the Subscription itself holds the info needed to populate
+     * the SubscriptionParams result. We encode the info in a Map to pass to the SubscribeParams Constructor
+     */
+    public Map<String, Object> mapEncode()
+    {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("_interval", _interval);
+        map.put("_duration", _duration);
+        map.put("_subscription_id", _subscriptionId);
+        return map;
+    }
+}
+
+

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/SubscriptionManager.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Console.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Console.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Console.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/QmfEventListenerModel.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/QmfEventListenerModel.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/QmfEventListenerModel.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Subscriptions.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Subscriptions.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/Subscriptions.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/WorkQueueEventModel.png
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/WorkQueueEventModel.png?rev=1465662&view=auto
==============================================================================
Binary file - no diff available.

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/console/doc-files/WorkQueueEventModel.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java?rev=1465662&view=auto
==============================================================================
--- qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java (added)
+++ qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java Mon Apr  8 15:19:04 2013
@@ -0,0 +1,474 @@
+/*
+ *
+ * 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.tools;
+
+// JMS Imports
+import javax.jms.Connection;
+
+// Misc Imports
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+// For DOM parsing the whitelist
+import org.w3c.dom.*;
+import javax.xml.parsers.*;
+
+// QMF2 Imports
+import org.apache.qpid.qmf2.common.ObjectId;
+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.AgentRestartedWorkItem;
+import org.apache.qpid.qmf2.console.Console;
+import org.apache.qpid.qmf2.console.EventReceivedWorkItem;
+import org.apache.qpid.qmf2.console.QmfConsoleData;
+import org.apache.qpid.qmf2.util.ConnectionHelper;
+import org.apache.qpid.qmf2.util.GetOpt;
+
+/**
+ * Audits connections to one or more Qpid message brokers.
+ * <pre>
+ * Exchange and Queue names are checked against a whitelist and if no match is found an alert is generated.
+ * 
+ * If no broker-addr is supplied, ConnectionAudit connects to 'localhost:5672'.
+ * 
+ * [broker-addr] syntax:
+ * 
+ * [username/password@] hostname
+ * ip-address [:&lt;port&gt;]
+ * 
+ * Examples:
+ * 
+ * $ ConnectionAudit localhost:5672
+ * $ ConnectionAudit 10.1.1.7:10000
+ * $ ConnectionAudit guest/guest@broker-host:10000
+ * 
+ * Options:
+ *   -h, --help            show this help message and exit
+ *   --sasl-mechanism=&lt;mech&gt;
+ *                         SASL mechanism for authentication (e.g. EXTERNAL,
+ *                         ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). SASL
+ *                         automatically picks the most secure available
+ *                         mechanism - use this option to override.
+ *   --whitelist=&lt;whitelist XML document&gt;
+ *                         The fully qualified name of the whitelist XML file,
+ *                         default is ./whitelist.xml
+ * 
+ * </pre>
+ * An example whitelist is illustrated below, note that in this example the exchanges associated with management
+ * have been whitelisted to remove spurious alerts caused by the temporary management queues.
+ * <pre>
+ *&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ *&lt;whitelist&gt;
+ *    &lt;exchangeWhitelist&gt;
+ *        &lt;exchange&gt;qmf.default.topic&lt;/exchange&gt;
+ *        &lt;exchange&gt;qmf.default.direct&lt;/exchange&gt;
+ *        &lt;exchange&gt;qpid.management&lt;/exchange&gt;
+ *        &lt;exchange&gt;amq.direct&lt;/exchange&gt;
+ *        &lt;exchange&gt;&lt;/exchange&gt;
+ *    &lt;/exchangeWhitelist&gt;
+ *    &lt;queueWhitelist&gt;
+ *        &lt;queue&gt;testqueue&lt;/queue&gt;
+ *    &lt;/queueWhitelist&gt;
+ *&lt;/whitelist&gt;
+ * </pre>
+
+ * @author Fraser Adams
+ */
+public final class ConnectionAudit implements QmfEventListener
+{
+    private static final String _usage =
+    "Usage: ConnectionAudit [options] [broker-addr]...\n";
+
+    private static final String _description =
+    "Audits connections to one or more Qpid message brokers.\n" +
+    "Exchange and Queue names are checked against a whitelist and if no match is found an alert is generated.\n" +
+    "\n" +
+    "If no broker-addr is supplied, ConnectionAudit connects to 'localhost:5672'.\n" +
+    "\n" +
+    "[broker-addr] syntax:\n" +
+    "\n" +
+    "[username/password@] hostname\n" +
+    "ip-address [:<port>]\n" +
+    "\n" +
+    "Examples:\n" +
+    "\n" +
+    "$ ConnectionAudit localhost:5672\n" +
+    "$ ConnectionAudit 10.1.1.7:10000\n" +
+    "$ ConnectionAudit guest/guest@broker-host:10000\n";
+
+    private static final String _options =
+    "Options:\n" +
+    "  -h, --help            show this help message and exit\n" +
+    "  --sasl-mechanism=<mech>\n" +
+    "                        SASL mechanism for authentication (e.g. EXTERNAL,\n" +
+    "                        ANONYMOUS, PLAIN, CRAM-MD, DIGEST-MD5, GSSAPI). SASL\n" +
+    "                        automatically picks the most secure available\n" +
+    "                        mechanism - use this option to override.\n" +
+    "  --whitelist=<whitelist XML document>\n" +
+    "                        The fully qualified name of the whitelist XML file,\n" +
+    "                        default is ./whitelist.xml\n";
+
+
+    private final String _url;
+    private final String _whitelist;
+    private long _whitelistLastModified = 0;
+    private Console _console;
+
+    // The sets to be used as the whitelists.
+    private Set<String> _exchangeWhitelist = new HashSet<String>();
+    private Set<String> _queueWhitelist = new HashSet<String>();
+
+    /**
+     * Basic constructor. Creates JMS Session, Initialises Destinations, Producers & Consumers and starts connection.
+     * @param url the connection URL.
+     * @param connectionOptions the options String to pass to ConnectionHelper.
+     * @param whitelist the path name of the whitelist XML file.
+     */
+    public ConnectionAudit(final String url, final String connectionOptions, final String whitelist)
+    {
+        System.out.println("Connecting to " + url);
+        _url = url;
+        _whitelist = whitelist;
+        try
+        {
+            Connection connection = ConnectionHelper.createConnection(url, connectionOptions);        
+            _console = new Console(this);
+            _console.addConnection(connection);
+            checkExistingSubscriptions();
+        }
+        catch (QmfException qmfe)
+        {
+            System.err.println ("QmfException " + qmfe.getMessage() + " caught in ConnectionAudit constructor");
+        }
+    }
+
+    /**
+     * When we start up we need to check any subscriptions that already exist against the whitelist.
+     * Subsequent checks are made only when we receive new subscribe events.
+     */
+    private void checkExistingSubscriptions()
+    {
+        readWhitelist();
+        List<QmfConsoleData> subscriptions = _console.getObjects("org.apache.qpid.broker", "subscription");
+        for (QmfConsoleData subscription : subscriptions)
+        {
+            QmfConsoleData queue = dereference(subscription.getRefValue("queueRef"));
+            QmfConsoleData session = dereference(subscription.getRefValue("sessionRef"));
+            QmfConsoleData connection = dereference(session.getRefValue("connectionRef"));
+            
+            String queueName = queue.getStringValue("name");
+            String address = connection.getStringValue("address");
+            String timestamp = new Date(subscription.getCreateTime()/1000000l).toString();
+            validateQueue(queueName, address, timestamp);
+        }
+    }
+
+    /**
+     * Dereferences an ObjectId returning a QmfConsoleData.
+     * @param ref the ObjectId to be dereferenced.
+     * @return the dereferenced QmfConsoleData object or null if the object can't be found.
+     */
+    private QmfConsoleData dereference(final ObjectId ref)
+    {
+        List<QmfConsoleData> data = _console.getObjects(ref);
+        if (data.size() == 1)
+        {
+            return data.get(0);
+        }
+        return null;
+    }
+
+    /**
+     * Looks up the exchange and binding information from the supplied queuename then calls the main validateQueue()
+     * @param queueName the name of the queue that we want to check against the whitelists.
+     * @param exchangeName the name of the exchange that the queue we want to check against the whitelists is bound to.
+     * @param binding the binding associating queue "queueName" with exchange "exchangeName".
+     * @param address the connection address information for the subscription.
+     * @param timestamp the timestamp of the subscription.
+     */
+    private void validateQueue(final String queueName, String exchangeName, final QmfConsoleData binding,
+                               final String address, final String timestamp)
+    {
+        if (_exchangeWhitelist.contains(exchangeName))
+        { // Check exchangeName against the exchangeWhitelist and if it's in there we simply return.
+            return;
+        }
+
+        if (_queueWhitelist.contains(queueName))
+        { // Check queueName against the queueWhitelist and if it's in there we simply return.
+            return;
+        }
+
+        if (exchangeName.equals(""))
+        { // Make exchangeName render more prettily if necessary.
+            exchangeName = "''";
+        }
+
+        String bindingKey = binding.getStringValue("bindingKey");
+        Map arguments = (Map)binding.getValue("arguments");
+        if (arguments.isEmpty())
+        {
+            System.out.printf("%s ALERT ConnectionAudit.validateQueue() validation failed for queue: %s with binding[%s] => %s from address: %s with connection timestamp %s\n\n", new Date().toString(), queueName, bindingKey, exchangeName, address, timestamp);
+        }
+        else
+        { // If there are binding arguments then it's a headers exchange so display accordimgly.
+            System.out.printf("%s ALERT ConnectionAudit.validateQueue() validation failed for queue: %s with binding[%s] => %s %s from address: %s with connection timestamp %s\n\n", new Date().toString(), queueName, bindingKey, exchangeName, arguments, address, timestamp);
+        }
+    }
+
+    /**
+     * Looks up the exchange and binding information from the supplied queuename then calls the main validateQueue()
+     * @param queueName the name of the queue that we want to check against the whitelists.
+     * @param address the connection address information for the subscription.
+     * @param timestamp the timestamp of the subscription.
+     */
+    private void validateQueue(final String queueName, final String address, final String timestamp)
+    {
+        ObjectId queueId = null;
+        List<QmfConsoleData> queues = _console.getObjects("org.apache.qpid.broker", "queue");
+        for (QmfConsoleData queue : queues)
+        { // We first have to find the ObjectId of the queue called queueName.
+            if (queue.getStringValue("name").equals(queueName))
+            {
+                queueId = queue.getObjectId();
+                break;
+            }
+        }
+
+        if (queueId == null)
+        {
+            System.out.printf("%s ERROR ConnectionAudit.validateQueue() %s reference couldn't be found\n",
+                              new Date().toString(), queueName);
+        }
+        else
+        { // If we've got the queue's ObjectId we then find the binding that references it.
+            List<QmfConsoleData> bindings = _console.getObjects("org.apache.qpid.broker", "binding");
+            for (QmfConsoleData binding : bindings)
+            {
+                ObjectId queueRef = binding.getRefValue("queueRef");
+                if (queueRef.equals(queueId))
+                { // We've found a binding that matches queue queueName so look up the associated exchange and validate.
+                    QmfConsoleData exchange = dereference(binding.getRefValue("exchangeRef"));
+                    String exchangeName = exchange.getStringValue("name");
+                    validateQueue(queueName, exchangeName, binding, address, timestamp);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles WorkItems delivered by the Console.
+     * <p>
+     * If we receive an EventReceivedWorkItem check if it is a subscribe event. If it is we check if the whitelist has 
+     * changed, and if it has we re-read it. We then extract the queue name, exchange name, binding, connection address
+     * and timestamp and validate with the whitelsist.
+     * <p>
+     * If we receive an AgentRestartedWorkItem we revalidate all subscriptions as it's possible that a client connection
+     * could have been made to the broker before ConnectionAudit has successfully re-established its own connections.
+     * @param wi a QMF2 WorkItem object
+     */
+    public void onEvent(final WorkItem wi)
+    {
+        if (wi instanceof EventReceivedWorkItem)
+        {
+            EventReceivedWorkItem item = (EventReceivedWorkItem)wi;
+            QmfEvent event = item.getEvent();
+            String className = event.getSchemaClassId().getClassName();
+            if (className.equals("subscribe"))
+            {
+                readWhitelist();
+                String queueName = event.getStringValue("qName");
+                String address = event.getStringValue("rhost");
+                String timestamp = new Date(event.getTimestamp()/1000000l).toString();
+                validateQueue(queueName, address, timestamp);
+            }
+        }
+        else if (wi instanceof AgentRestartedWorkItem)
+        {
+            checkExistingSubscriptions();
+        }
+    }
+
+    /**
+     * This method first checks if the whitelist file exists, if not it clears the sets used as whitelists
+     * so that no whitelisting is applied. If the whitelist file does exist it is parsed by a DOM parser.
+     * <p>
+     * We look for all exchange and queue elements and populate the respective whitelist sets with their
+     * contents. Note that we check the whitelist file update time to avoid reading it if it hasn't been changed
+     */
+    private void readWhitelist()
+    {
+        File file = new File(_whitelist);
+        if (file.exists())
+        {
+            long mtime = file.lastModified();
+            if (mtime != _whitelistLastModified)
+            {
+                _whitelistLastModified = mtime;
+                _exchangeWhitelist.clear();
+                _queueWhitelist.clear();
+
+                try
+                {
+                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                    DocumentBuilder docBuilder = factory.newDocumentBuilder();
+                    Document doc = docBuilder.parse(file);
+    
+                    Element whitelist = doc.getDocumentElement();
+                    if (whitelist.getNodeName().equals("whitelist"))
+                    {
+                        NodeList children = whitelist.getChildNodes();
+                        for (int i = 0; i < children.getLength(); i++)
+                        {
+                            Node child = children.item(i);
+                            if (child.getNodeName().equals("exchangeWhitelist"))
+                            {
+                                NodeList exchanges = child.getChildNodes();
+                                for (int j = 0; j < exchanges.getLength(); j++)
+                                {
+                                    Node node = exchanges.item(j);
+                                    if (node.getNodeName().equals("exchange"))
+                                    {
+                                        if (node.hasChildNodes())
+                                        {
+                                            String exchange = node.getFirstChild().getNodeValue();
+                                            _exchangeWhitelist.add(exchange);
+                                        }
+                                        else
+                                        {
+                                            _exchangeWhitelist.add("");
+                                        }
+                                    }
+                                }
+                            }
+                            else if (child.getNodeName().equals("queueWhitelist"))
+                            {
+                                NodeList queues = child.getChildNodes();
+                                for (int j = 0; j < queues.getLength(); j++)
+                                {
+                                    Node node = queues.item(j);
+                                    if (node.getNodeName().equals("queue"))
+                                    {
+                                        if (node.hasChildNodes())
+                                        {
+                                            String queue = node.getFirstChild().getNodeValue();
+                                            _queueWhitelist.add(queue);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                catch (Exception e)
+                { // Failed to parse correctly.
+                    System.out.println("Exception " + e + " while reading " + _whitelist);
+                    System.out.println(new Date().toString() + " WARN ConnectionAudit.readWhitelist() " + 
+                                       _whitelist + " failed: " + e.getMessage());
+                    return;
+                }
+            }
+        }
+        else 
+        { // If whitelist file doesn't exist log a warning and clear the whitelists.
+            System.out.println(new Date().toString() + " WARN ConnectionAudit.readWhitelist() " + 
+                               _whitelist + " doesn't exist");
+            _exchangeWhitelist.clear();
+            _queueWhitelist.clear();
+        }
+    } // End of readWhitelist()
+
+    /**
+     * Runs ConnectionAudit.
+     * @param args the command line arguments.
+     */
+    public static void main(final String[] args)
+    {
+        String logLevel = System.getProperty("amqj.logging.level");
+        logLevel = (logLevel == null) ? "FATAL" : logLevel; // Set default log level to FATAL rather than DEBUG.
+        System.setProperty("amqj.logging.level", logLevel);
+
+        String[] longOpts = {"help", "whitelist=", "sasl-mechanism="};
+        try
+        {
+            String connectionOptions = "{reconnect: true}";
+            String whitelist = "./whitelist.xml";
+            GetOpt getopt = new GetOpt(args, "h", longOpts);
+            List<String[]> optList = getopt.getOptList();
+            String[] cargs = {};
+            cargs = getopt.getEncArgs().toArray(cargs);
+            for (String[] opt : optList)
+            {
+                if (opt[0].equals("-h") || opt[0].equals("--help"))
+                {
+                    System.out.println(_usage);
+                    System.out.println(_description);
+                    System.out.println(_options);
+                    System.exit(1);
+                }
+                else if (opt[0].equals("--whitelist"))
+                {
+                    whitelist = opt[1];
+                }
+                else if (opt[0].equals("--sasl-mechanism"))
+                {
+                    connectionOptions = "{reconnect: true, sasl_mechs: " + opt[1] + "}";
+                }
+            }
+
+            int nargs = cargs.length;
+            if (nargs == 0)
+            {
+                cargs = new String[] {"localhost"};
+            }
+
+            for (String url : cargs)
+            {
+                ConnectionAudit eventPrinter = new ConnectionAudit(url, connectionOptions, whitelist);
+            }
+        }
+        catch (IllegalArgumentException e)
+        {
+            System.out.println(_usage);
+            System.exit(1);
+        }
+
+        try
+        {   // Block here
+            Thread.currentThread().join();
+        }
+        catch (InterruptedException ie)
+        {
+        }
+    }
+}

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/trunk/qpid/tools/src/java/src/main/java/org/apache/qpid/qmf2/tools/ConnectionAudit.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org