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"=<value> pairs of all returned arguments.
+ * @return a map of "name"=<value> 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 [:<port>]
+ *
+ * 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=<mech>
+ * 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=<whitelist XML document>
+ * 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>
+ *<?xml version="1.0" encoding="UTF-8"?>
+ *<whitelist>
+ * <exchangeWhitelist>
+ * <exchange>qmf.default.topic</exchange>
+ * <exchange>qmf.default.direct</exchange>
+ * <exchange>qpid.management</exchange>
+ * <exchange>amq.direct</exchange>
+ * <exchange></exchange>
+ * </exchangeWhitelist>
+ * <queueWhitelist>
+ * <queue>testqueue</queue>
+ * </queueWhitelist>
+ *</whitelist>
+ * </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