You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by js...@apache.org on 2006/03/28 17:27:57 UTC
svn commit: r389519 - in /incubator/activemq/trunk/activemq-core/src:
main/java/org/apache/activemq/broker/
main/java/org/apache/activemq/broker/view/
test/java/org/apache/activemq/test/
Author: jstrachan
Date: Tue Mar 28 07:27:55 2006
New Revision: 389519
URL: http://svn.apache.org/viewcvs?rev=389519&view=rev
Log:
added extra visualisation plugin; to render the broker, connections, sessions, consumers in a DOT graph
Added:
incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java (with props)
incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java (with props)
Modified:
incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java
incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java
incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/DestinationDotFileInterceptor.java
incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/test/Main.java
Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java?rev=389519&r1=389518&r2=389519&view=diff
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java (original)
+++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerPlugin.java Tue Mar 28 07:27:55 2006
@@ -27,6 +27,6 @@
* Installs the plugin into the interceptor chain of the broker, returning the new
* intercepted broker to use.
*/
- public Broker installPlugin(Broker broker);
+ public Broker installPlugin(Broker broker) throws Exception;
}
Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java?rev=389519&r1=389518&r2=389519&view=diff
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java (original)
+++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/BrokerService.java Tue Mar 28 07:27:55 2006
@@ -917,7 +917,7 @@
*
* @throws IOException
*/
- protected Broker addInterceptors(Broker broker) throws IOException {
+ protected Broker addInterceptors(Broker broker) throws Exception {
broker = new TransactionBroker(broker, getPersistenceAdapter().createTransactionStore());
broker = new AdvisoryBroker(broker);
broker = new CompositeDestinationBroker(broker);
Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java?rev=389519&view=auto
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java (added)
+++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java Tue Mar 28 07:27:55 2006
@@ -0,0 +1,252 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.broker.view;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.Connection;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.broker.Connector;
+import org.apache.activemq.broker.jmx.BrokerViewMBean;
+import org.apache.activemq.broker.jmx.ManagementContext;
+import org.apache.activemq.broker.jmx.SubscriptionViewMBean;
+import org.apache.activemq.broker.region.Subscription;
+import org.apache.activemq.command.ActiveMQDestination;
+import org.apache.activemq.command.ConsumerInfo;
+import org.apache.activemq.command.ProducerInfo;
+import org.apache.activemq.filter.DestinationMap;
+import org.apache.activemq.filter.DestinationMapNode;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import java.io.PrintWriter;
+import java.util.*;
+
+/**
+ *
+ * @version $Revision: $
+ */
+public class ConnectionDotFileInterceptor extends DotFileInterceptorSupport {
+
+ protected static final String ID_SEPARATOR = "_";
+
+ private final boolean redrawOnRemove;
+ private String domain = "org.apache.activemq";
+ private BrokerViewMBean brokerView;
+ private MBeanServer mbeanServer;
+
+ public ConnectionDotFileInterceptor(Broker next, String file, boolean redrawOnRemove)
+ throws MalformedObjectNameException {
+ super(next, file);
+ this.redrawOnRemove = redrawOnRemove;
+
+ mbeanServer = new ManagementContext().getMBeanServer();
+ ObjectName brokerName = new ObjectName(domain + ":Type=Broker,BrokerName=localhost");
+ brokerView = (BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(mbeanServer, brokerName,
+ BrokerViewMBean.class, true);
+ }
+
+ public Subscription addConsumer(ConnectionContext context, ConsumerInfo info) throws Exception {
+ Subscription answer = super.addConsumer(context, info);
+ generateFile();
+ return answer;
+ }
+
+ public void addProducer(ConnectionContext context, ProducerInfo info) throws Exception {
+ super.addProducer(context, info);
+ generateFile();
+ }
+
+ public void removeConsumer(ConnectionContext context, ConsumerInfo info) throws Exception {
+ super.removeConsumer(context, info);
+ if (redrawOnRemove) {
+ generateFile();
+ }
+ }
+
+ public void removeProducer(ConnectionContext context, ProducerInfo info) throws Exception {
+ super.removeProducer(context, info);
+ if (redrawOnRemove) {
+ generateFile();
+ }
+ }
+
+ protected void generateFile(PrintWriter writer) throws Exception {
+
+ writer.println("digraph \"ActiveMQ Connections\" {");
+ writer.println();
+ writer.println("node [style = \"rounded,filled\", fillcolor = yellow, fontname=\"Helvetica-Oblique\"];");
+ writer.println();
+
+ writer.println("broker [fillcolor = deepskyblue, label=\"ActiveMQ Broker\\n" + brokerView.getBrokerId() + "\"];");
+ writer.println();
+
+ Map clients = new HashMap();
+ Map destinations = new HashMap();
+ printSubscribers(writer, clients, destinations, "queue_", brokerView.getQueueSubscribers());
+ writer.println();
+
+ printSubscribers(writer, clients, destinations, "topic_", brokerView.getTopicSubscribers());
+ writer.println();
+
+ // lets print the broker links
+ for (Iterator iter = clients.keySet().iterator(); iter.hasNext();) {
+ String clientId = (String) iter.next();
+ writer.print(clientId);
+ writer.println(" -> broker");
+ }
+ writer.println();
+
+ writeLabels(writer, "green", "Client: ", clients);
+ writer.println();
+
+ writeLabels(writer, "red", "Queue: ", destinations);
+ writer.println("}");
+ }
+
+ protected void writeLabels(PrintWriter writer, String color, String prefix, Map map) {
+ for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
+ Map.Entry entry = (Map.Entry) iter.next();
+ String id = (String) entry.getKey();
+ String label = (String) entry.getValue();
+
+ writer.print(id);
+ writer.print(" [ fillcolor = ");
+ writer.print(color);
+ writer.print(", label = \"");
+ writer.print(prefix);
+ writer.print(label);
+ writer.println("\"];");
+ }
+ }
+
+ protected void printSubscribers(PrintWriter writer, Map clients, Map destinations, String type,
+ ObjectName[] subscribers) {
+ for (int i = 0; i < subscribers.length; i++) {
+ ObjectName name = subscribers[i];
+ SubscriptionViewMBean subscriber = (SubscriptionViewMBean) MBeanServerInvocationHandler.newProxyInstance(
+ mbeanServer, name, SubscriptionViewMBean.class, true);
+
+ String clientId = subscriber.getClientId();
+ String destination = subscriber.getDestinationName();
+ String selector = subscriber.getSelector();
+
+ String safeClientId = asID(clientId);
+ clients.put(safeClientId, clientId);
+
+ String safeDestinationId = type + asID(destination);
+ destinations.put(safeDestinationId, destination);
+
+ // lets write out the links
+
+ String subscriberId = safeClientId + "_" + subscriber.getSessionId() + "_" + subscriber.getSubcriptionId();
+
+ writer.print(safeClientId);
+ writer.print(" -> ");
+ writer.print(subscriberId);
+ writer.println(";");
+
+ writer.print(safeDestinationId);
+ writer.print(" -> ");
+ writer.print(subscriberId);
+ writer.println(";");
+
+ // now lets write out the label
+ writer.print(subscriberId);
+ writer.print(" [label = \"");
+ String label = "Subscription: " + subscriber.getSessionId() + "-" + subscriber.getSubcriptionId();
+ if (selector != null && selector.length() > 0) {
+ label = label + "\\nSelector: " + selector;
+ }
+ writer.print(label);
+ writer.println("\"];");
+ }
+ }
+
+ /**
+ * Lets strip out any non supported characters
+ */
+ protected String asID(String name) {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0, size = name.length(); i < size; i++) {
+ char ch = name.charAt(i);
+ if (Character.isLetterOrDigit(ch) || ch == '_') {
+ buffer.append(ch);
+ }
+ else {
+ buffer.append('_');
+ }
+ }
+ return buffer.toString();
+ }
+
+ protected void printNodes(PrintWriter writer, DestinationMapNode node, String prefix) {
+ String path = getPath(node);
+ writer.print(" ");
+ writer.print(prefix);
+ writer.print(ID_SEPARATOR);
+ writer.print(path);
+ String label = path;
+ if (prefix.equals("topic")) {
+ label = "Topics";
+ }
+ else if (prefix.equals("queue")) {
+ label = "Queues";
+ }
+ writer.print("[ label = \"");
+ writer.print(label);
+ writer.println("\" ];");
+
+ Collection children = node.getChildren();
+ for (Iterator iter = children.iterator(); iter.hasNext();) {
+ DestinationMapNode child = (DestinationMapNode) iter.next();
+ printNodes(writer, child, prefix + ID_SEPARATOR + path);
+ }
+ }
+
+ protected void printNodeLinks(PrintWriter writer, DestinationMapNode node, String prefix) {
+ String path = getPath(node);
+ Collection children = node.getChildren();
+ for (Iterator iter = children.iterator(); iter.hasNext();) {
+ DestinationMapNode child = (DestinationMapNode) iter.next();
+
+ writer.print(" ");
+ writer.print(prefix);
+ writer.print(ID_SEPARATOR);
+ writer.print(path);
+ writer.print(" -> ");
+ writer.print(prefix);
+ writer.print(ID_SEPARATOR);
+ writer.print(path);
+ writer.print(ID_SEPARATOR);
+ writer.print(getPath(child));
+ writer.println(";");
+
+ printNodeLinks(writer, child, prefix + ID_SEPARATOR + path);
+ }
+ }
+
+ protected String getPath(DestinationMapNode node) {
+ String path = node.getPath();
+ if (path.equals("*")) {
+ return "root";
+ }
+ return path;
+ }
+}
Propchange: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFileInterceptor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java?rev=389519&view=auto
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java (added)
+++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java Tue Mar 28 07:27:55 2006
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.broker.view;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerPlugin;
+
+/**
+ * A <a href="http://www.graphviz.org/">DOT</a> file creator plugin which
+ * creates a DOT file showing the current connections
+ *
+ * @version $Revision: $
+ */
+public class ConnectionDotFilePlugin implements BrokerPlugin {
+ private String file = "ActiveMQConnections.dot";
+ private boolean redrawOnRemove;
+
+ public Broker installPlugin(Broker broker) throws Exception {
+ return new ConnectionDotFileInterceptor(broker, file, redrawOnRemove);
+ }
+
+ public String getFile() {
+ return file;
+ }
+
+ /**
+ * Sets the destination file name to create the destination diagram
+ */
+ public void setFile(String file) {
+ this.file = file;
+ }
+
+}
Propchange: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/ConnectionDotFilePlugin.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/DestinationDotFileInterceptor.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/DestinationDotFileInterceptor.java?rev=389519&r1=389518&r2=389519&view=diff
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/DestinationDotFileInterceptor.java (original)
+++ incubator/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/broker/view/DestinationDotFileInterceptor.java Tue Mar 28 07:27:55 2006
@@ -16,18 +16,12 @@
package org.apache.activemq.broker.view;
import org.apache.activemq.broker.Broker;
-import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.broker.region.Destination;
-import org.apache.activemq.broker.region.Subscription;
import org.apache.activemq.command.ActiveMQDestination;
-import org.apache.activemq.command.ConsumerInfo;
import org.apache.activemq.filter.DestinationMap;
import org.apache.activemq.filter.DestinationMapNode;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Iterator;
@@ -39,11 +33,9 @@
public class DestinationDotFileInterceptor extends DotFileInterceptorSupport {
protected static final String ID_SEPARATOR = "_";
-
public DestinationDotFileInterceptor(Broker next, String file) {
super(next, file);
-
}
public Destination addDestination(ConnectionContext context, ActiveMQDestination destination) throws Exception {
Modified: incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/test/Main.java
URL: http://svn.apache.org/viewcvs/incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/test/Main.java?rev=389519&r1=389518&r2=389519&view=diff
==============================================================================
--- incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/test/Main.java (original)
+++ incubator/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/test/Main.java Tue Mar 28 07:27:55 2006
@@ -16,14 +16,17 @@
*/
package org.apache.activemq.test;
-import org.apache.activemq.broker.BrokerFactory;
+import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerPlugin;
import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.broker.view.DestinationDotFileInterceptor;
+import org.apache.activemq.broker.view.ConnectionDotFilePlugin;
import org.apache.activemq.broker.view.DestinationDotFilePlugin;
+import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.demo.DefaultQueueSender;
-import java.net.URI;
+import javax.jms.Connection;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
/**
* A helper class which can be handy for running a broker in your IDE from the
@@ -42,18 +45,29 @@
brokerURI = args[0];
}
try {
- //BrokerService broker = BrokerFactory.createBroker(new URI(brokerURI));
+ // TODO - this seems to break interceptors for some reason
+ // BrokerService broker = BrokerFactory.createBroker(new
+ // URI(brokerURI));
BrokerService broker = new BrokerService();
broker.setPersistent(false);
broker.setUseJmx(true);
- broker.setPlugins(new BrokerPlugin[] { new DestinationDotFilePlugin() });
+ broker.setPlugins(new BrokerPlugin[] { /*new DestinationDotFilePlugin(), */ new ConnectionDotFilePlugin() });
broker.addConnector("tcp://localhost:61616");
broker.addConnector("stomp://localhost:61613");
broker.start();
-
+
+ // lets create a dummy couple of consumers
+ Connection connection = new ActiveMQConnectionFactory().createConnection();
+ connection.start();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer1 = session.createConsumer(new ActiveMQQueue("Orders.IBM"));
+ MessageConsumer consumer2 = session.createConsumer(new ActiveMQQueue("Orders.MSFT"), "price > 100");
+ Session session2 = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer3 = session2.createConsumer(new ActiveMQQueue("Orders.MSFT"), "price > 200");
+
// lets publish some messages so that there is some stuff to browse
- DefaultQueueSender.main(new String[] {"Prices.Equity.IBM"});
- DefaultQueueSender.main(new String[] {"Prices.Equity.MSFT"});
+ DefaultQueueSender.main(new String[] { "Prices.Equity.IBM" });
+ DefaultQueueSender.main(new String[] { "Prices.Equity.MSFT" });
}
catch (Exception e) {
System.out.println("Failed: " + e);