Repository: activemq
Updated Branches:
  refs/heads/trunk db1e3fc9e -> ae2504ab8


AMQ-5104: Add non-durable subscribers to the subscriber page, and 
topic-specific subscriber view for individual topics.


Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/ae2504ab
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/ae2504ab
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/ae2504ab

Branch: refs/heads/trunk
Commit: ae2504ab8e4c3410b2c12aa8d7f938d7df638892
Parents: db1e3fc
Author: artnaseef <[email protected]>
Authored: Fri Mar 14 23:10:13 2014 -0700
Committer: artnaseef <[email protected]>
Committed: Fri Mar 14 23:10:13 2014 -0700

----------------------------------------------------------------------
 .../main/webapp/WEB-INF/webconsole-query.xml    |  1 +
 .../src/main/webapp/subscribers.jsp             | 58 ++++++++++++++-
 .../src/main/webapp/topicSubscribers.jsp        | 78 ++++++++++++++++++++
 activemq-web-console/src/main/webapp/topics.jsp |  2 +
 .../org/apache/activemq/web/BrokerFacade.java   | 22 ++++++
 .../activemq/web/BrokerFacadeSupport.java       | 32 ++++++--
 .../activemq/web/TopicSubscriberQuery.java      | 45 +++++++++++
 7 files changed, 230 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web-console/src/main/webapp/WEB-INF/webconsole-query.xml
----------------------------------------------------------------------
diff --git a/activemq-web-console/src/main/webapp/WEB-INF/webconsole-query.xml 
b/activemq-web-console/src/main/webapp/WEB-INF/webconsole-query.xml
index 556d9b7..6ec95ca 100644
--- a/activemq-web-console/src/main/webapp/WEB-INF/webconsole-query.xml
+++ b/activemq-web-console/src/main/webapp/WEB-INF/webconsole-query.xml
@@ -23,5 +23,6 @@
   <bean id="queueConsumerQuery" 
class="org.apache.activemq.web.QueueConsumerQuery" autowire="constructor" 
destroy-method="destroy" scope="request"/>
   <bean id="queueProducerQuery" 
class="org.apache.activemq.web.QueueProducerQuery" autowire="constructor" 
destroy-method="destroy" scope="request"/>
   <bean id="topicProducerQuery" 
class="org.apache.activemq.web.TopicProducerQuery" autowire="constructor" 
destroy-method="destroy" scope="request"/>
+  <bean id="topicSubscriberQuery" 
class="org.apache.activemq.web.TopicSubscriberQuery" autowire="constructor" 
destroy-method="destroy" scope="request"/>
   <bean id="connectionQuery" class="org.apache.activemq.web.ConnectionQuery" 
autowire="constructor" destroy-method="destroy" scope="request"/>
 </beans>

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web-console/src/main/webapp/subscribers.jsp
----------------------------------------------------------------------
diff --git a/activemq-web-console/src/main/webapp/subscribers.jsp 
b/activemq-web-console/src/main/webapp/subscribers.jsp
index f876e49..1dfbbd7 100644
--- a/activemq-web-console/src/main/webapp/subscribers.jsp
+++ b/activemq-web-console/src/main/webapp/subscribers.jsp
@@ -96,7 +96,11 @@
 <tbody>
 <c:forEach items="${requestContext.brokerQuery.durableTopicSubscribers}" 
var="row">
 <tr>
-<td><form:tooltip text="${row.clientId}" length="10"/></td>
+<td>
+<a href="<c:url value="connection.jsp?connectionID=${row.clientId}"/>">
+<form:tooltip text="${row.clientId}" length="10"/>
+</a>
+</td>
 <td><form:tooltip text="${row.subscriptionName}" length="10"/></td>
 <td><form:tooltip text="${row.connectionId}" length="10"/></td>
 <td><form:tooltip text="${row.destinationName}" length="10"/></td>
@@ -140,7 +144,11 @@
 <tbody>
 <c:forEach 
items="${requestContext.brokerQuery.inactiveDurableTopicSubscribers}" var="row">
 <tr>
-<td><form:tooltip text="${row.clientId}" length="10"/></td>
+<td>
+<a href="<c:url value="connection.jsp?connectionID=${row.clientId}"/>">
+<form:tooltip text="${row.clientId}" length="10"/>
+</a>
+</td>
 <td><form:tooltip text="${row.subscriptionName}" length="10"/></td>
 <td><form:tooltip text="${row.connectionId}" length="10"/></td>
 <td><form:tooltip text="${row.destinationName}" length="10"/></td>
@@ -162,6 +170,52 @@
 </tbody>
 </table>
 
+
+<h2>Active Non-Durable Topic Subscribers</h2>
+
+
+<table id="topics" class="sortable autostripe">
+<thead>
+<tr>
+<th>Client ID</th>
+<th>Subscription Name</th>
+<th>Connection ID</th>
+<th>Destination</th>
+<th>Selector</th>
+<th>Pending Queue Size</th>
+<th>Dispatched Queue Size</th>
+<th>Dispatched Counter</th>
+<th>Enqueue Counter</th>
+<th>Dequeue Counter</th>
+<th>Operations</th>
+</tr>
+</thead>
+<tbody>
+<c:forEach items="${requestContext.brokerQuery.nonDurableTopicSubscribers}" 
var="row">
+<tr>
+<td>
+<a href="<c:url value="connection.jsp?connectionID=${row.clientId}"/>">
+<form:tooltip text="${row.clientId}" length="10"/>
+</a>
+</td>
+<td><form:tooltip text="${row.subscriptionName}" length="10"/></td>
+<td><form:tooltip text="${row.connectionId}" length="10"/></td>
+<td><form:tooltip text="${row.destinationName}" length="10"/></td>
+<td><c:out value="${row.selector}"/></td>
+<td><c:out value="${row.pendingQueueSize}" /></td>
+<td><c:out value="${row.dispatchedQueueSize}" /></td>
+<td><c:out value="${row.dispatchedCounter}" /></td>
+<td><c:out value="${row.enqueueCounter}" /></td>
+<td><c:out value="${row.dequeueCounter}" /></td>
+<td>
+</td>
+</tr>
+</c:forEach>
+
+</tbody>
+</table>
+
+
 <%@include file="decorators/footer.jsp" %>
 
 </body>

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web-console/src/main/webapp/topicSubscribers.jsp
----------------------------------------------------------------------
diff --git a/activemq-web-console/src/main/webapp/topicSubscribers.jsp 
b/activemq-web-console/src/main/webapp/topicSubscribers.jsp
new file mode 100644
index 0000000..7f2e9c9
--- /dev/null
+++ b/activemq-web-console/src/main/webapp/topicSubscribers.jsp
@@ -0,0 +1,78 @@
+<%--
+    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.
+--%>
+<html>
+<head>
+<c:set var="pageTitle" value="Subscribers for Topic 
${requestContext.topicSubscriberQuery.JMSDestination}"/>
+
+<%@include file="decorators/head.jsp" %>
+</head>
+<body>
+
+<%@include file="decorators/header.jsp" %>
+
+
+
+<h2>Active Subscribers for <c:out 
value="${requestContext.topicSubscriberQuery.JMSDestination}" /></h2>
+
+<table id="producers" class="sortable autostripe">
+<thead>
+<tr>
+       <th>
+               <span>Client ID</span>
+               <br/>
+               <span>Connection ID</span>
+       </th>
+       <th>SessionId</th>
+       <th>SubscriptionId</th>
+       <th>Selector</th>
+       <th>Active</th>
+       <th>Network</th>
+       <th>Pending Queue Size</th>
+       <th>Inflight</th>
+       <th>Enqueued</th>
+       <th>Dequeued</th>
+       <th>Prefetch</th>
+       <th>Subscription Name</th>
+</tr>
+</thead>
+<tbody>
+<c:forEach items="${requestContext.topicSubscriberQuery.subscribers}" 
var="row">
+<tr>
+       <td>
+        <a href="<c:url 
value="connection.jsp?connectionID=${row.clientId}"/>"><c:out 
value="${row.clientId}" /></a><br/>
+        <br>
+        <c:out value="${row.connectionId}" />
+    </td>
+       <td><c:out value="${row.sessionId}" /></td>
+       <td><c:out value="${row.subscriptionId}" /></td>
+       <td><c:out value="${row.selector}" /></td>
+       <td><c:out value="${row.active}" /></td>
+       <td><c:out value="${row.network}" /></td>
+       <td><c:out value="${row.pendingQueueSize}" /></td>
+       <td><c:out value="${row.messageCountAwaitingAcknowledge}" /></td>
+       <td><c:out value="${row.enqueueCounter}" /></td>
+       <td><c:out value="${row.dequeueCounter}" /></td>
+       <td><c:out value="${row.prefetchSize}" /></td>
+       <td><c:out value="${row.subscriptionName}" /></td>
+</tr>
+</c:forEach>
+</tbody>
+</table>
+<%@include file="decorators/footer.jsp" %>
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web-console/src/main/webapp/topics.jsp
----------------------------------------------------------------------
diff --git a/activemq-web-console/src/main/webapp/topics.jsp 
b/activemq-web-console/src/main/webapp/topics.jsp
index d44de08..3043e04 100644
--- a/activemq-web-console/src/main/webapp/topics.jsp
+++ b/activemq-web-console/src/main/webapp/topics.jsp
@@ -61,6 +61,8 @@
     <a href="<c:url value="send.jsp">
                         <c:param name="JMSDestination" value="${row.name}" />
                         <c:param name="JMSDestinationType" 
value="topic"/></c:url>">Send To</a>
+    <a href="<c:url value="topicSubscribers.jsp">
+                        <c:param name="JMSDestination" value="${row.name}" 
/></c:url>">Active Subscribers</a><br/>
     <a href="<c:url value="topicProducers.jsp">
                         <c:param name="JMSDestination" value="${row.name}" 
/></c:url>">Active Producers</a><br/>
     <a href="<c:url value="deleteDestination.action">

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacade.java
----------------------------------------------------------------------
diff --git 
a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacade.java 
b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacade.java
index c7e4d4a..31ef518 100644
--- a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacade.java
+++ b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacade.java
@@ -95,6 +95,28 @@ public interface BrokerFacade {
                        throws Exception;
 
        /**
+        * All active non-durable subscribers to a topic.
+        * 
+        * @param queueName
+        *            the name of the topic, not <code>null</code>
+        * @return not <code>null</code>
+        * @throws Exception
+        */
+       public Collection<SubscriptionViewMBean> getTopicSubscribers(String 
topicName)
+                       throws Exception;
+
+       /**
+        * All active non-durable subscribers to a topic.
+        * 
+        * @param queueName
+        *            the name of the topic, not <code>null</code>
+        * @return not <code>null</code>
+        * @throws Exception
+        */
+       public Collection<SubscriptionViewMBean> getNonDurableTopicSubscribers()
+                       throws Exception;
+
+       /**
         * Active durable subscribers to topics of the broker.
         * 
         * @return not <code>null</code>

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java
----------------------------------------------------------------------
diff --git 
a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java 
b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java
index aa2006a..69e8696 100644
--- 
a/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java
+++ 
b/activemq-web/src/main/java/org/apache/activemq/web/BrokerFacadeSupport.java
@@ -69,8 +69,28 @@ public abstract class BrokerFacadeSupport implements 
BrokerFacade {
         if (broker == null) {
             return Collections.EMPTY_LIST;
         }
-        ObjectName[] queues = broker.getTopics();
-        return getManagedObjects(queues, TopicViewMBean.class);
+        ObjectName[] topics = broker.getTopics();
+        return getManagedObjects(topics, TopicViewMBean.class);
+    }
+
+    @Override
+    public Collection<SubscriptionViewMBean> getTopicSubscribers(String 
topicName) throws Exception {
+        String brokerName = getBrokerName();
+        topicName = StringUtils.replace(topicName, "\"", "_");
+        ObjectName query = new 
ObjectName("org.apache.activemq:type=Broker,brokerName=" + brokerName
+                + ",destinationType=Topic,destinationName=" + topicName + 
",endpoint=Consumer,*");
+        Set<ObjectName> queryResult = queryNames(query, null);
+        return getManagedObjects(queryResult.toArray(new 
ObjectName[queryResult.size()]), SubscriptionViewMBean.class);
+    }
+
+    @Override
+    public Collection<SubscriptionViewMBean> getNonDurableTopicSubscribers() 
throws Exception {
+        BrokerViewMBean broker = getBrokerAdmin();
+        if (broker == null) {
+            return Collections.EMPTY_LIST;
+        }
+        ObjectName[] subscribers = broker.getTopicSubscribers();
+        return getManagedObjects(subscribers, SubscriptionViewMBean.class);
     }
 
     @Override
@@ -79,8 +99,8 @@ public abstract class BrokerFacadeSupport implements 
BrokerFacade {
         if (broker == null) {
             return Collections.EMPTY_LIST;
         }
-        ObjectName[] queues = broker.getDurableTopicSubscribers();
-        return getManagedObjects(queues, DurableSubscriptionViewMBean.class);
+        ObjectName[] subscribers = broker.getDurableTopicSubscribers();
+        return getManagedObjects(subscribers, 
DurableSubscriptionViewMBean.class);
     }
 
     @Override
@@ -89,8 +109,8 @@ public abstract class BrokerFacadeSupport implements 
BrokerFacade {
         if (broker == null) {
             return Collections.EMPTY_LIST;
         }
-        ObjectName[] queues = broker.getInactiveDurableTopicSubscribers();
-        return getManagedObjects(queues, DurableSubscriptionViewMBean.class);
+        ObjectName[] subscribers = broker.getInactiveDurableTopicSubscribers();
+        return getManagedObjects(subscribers, 
DurableSubscriptionViewMBean.class);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/activemq/blob/ae2504ab/activemq-web/src/main/java/org/apache/activemq/web/TopicSubscriberQuery.java
----------------------------------------------------------------------
diff --git 
a/activemq-web/src/main/java/org/apache/activemq/web/TopicSubscriberQuery.java 
b/activemq-web/src/main/java/org/apache/activemq/web/TopicSubscriberQuery.java
new file mode 100644
index 0000000..f07df46
--- /dev/null
+++ 
b/activemq-web/src/main/java/org/apache/activemq/web/TopicSubscriberQuery.java
@@ -0,0 +1,45 @@
+/*
+ * 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.activemq.web;
+
+import java.util.Collection;
+
+import javax.jms.JMSException;
+
+import org.apache.activemq.broker.jmx.SubscriptionViewMBean;
+
+/**
+ * Query for Topic producers.
+ * 
+ * 
+ */
+public class TopicSubscriberQuery extends DestinationFacade {
+
+       public TopicSubscriberQuery(BrokerFacade brokerFacade) throws 
JMSException {
+               super(brokerFacade);
+               setJMSDestinationType("queue");
+       }
+
+       public Collection<SubscriptionViewMBean> getSubscribers() throws 
Exception {
+               return 
getBrokerFacade().getTopicSubscribers(getJMSDestination());
+       }
+
+       public void destroy() {
+               // empty
+       }
+
+}

Reply via email to