activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From clebertsuco...@apache.org
Subject [2/6] activemq-artemis git commit: ARTEMIS-1270 Management Console - Hawtio Solution
Date Tue, 01 Aug 2017 20:18:07 GMT
ARTEMIS-1270 Management Console - Hawtio Solution

Add Artemis Plugin


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

Branch: refs/heads/master
Commit: fa7b247dc460eb76b588befbe4ee3aa5a49a4f5d
Parents: cadf909
Author: Andy Taylor <andytaylor@apache.org>
Authored: Wed Jul 5 16:34:18 2017 +0100
Committer: Clebert Suconic <clebertsuconic@apache.org>
Committed: Tue Aug 1 14:54:27 2017 -0400

----------------------------------------------------------------------
 artemis-hawtio/artemis-plugin/README.md         |   3 +
 artemis-hawtio/artemis-plugin/pom.xml           | 263 ++++++++
 .../hawtio/plugin/PluginContextListener.java    |  71 ++
 .../src/main/resources/WEB-INF/web.xml          |  57 ++
 .../src/main/resources/log4j.properties         |  23 +
 .../src/main/webapp/plugin/doc/help.md          |  19 +
 .../main/webapp/plugin/html/artemisLayout.html  |  42 ++
 .../main/webapp/plugin/html/brokerDiagram.html  | 313 +++++++++
 .../main/webapp/plugin/html/browseQueue.html    | 156 +++++
 .../main/webapp/plugin/html/createAddress.html  |  44 ++
 .../main/webapp/plugin/html/createQueue.html    |  77 +++
 .../main/webapp/plugin/html/deleteAddress.html  |  48 ++
 .../main/webapp/plugin/html/deleteQueue.html    |  62 ++
 .../main/webapp/plugin/html/preferences.html    |  69 ++
 .../main/webapp/plugin/html/sendMessage.html    | 135 ++++
 .../src/main/webapp/plugin/js/address.js        | 119 ++++
 .../src/main/webapp/plugin/js/artemisHelpers.js | 126 ++++
 .../src/main/webapp/plugin/js/artemisPlugin.js  | 246 +++++++
 .../src/main/webapp/plugin/js/artemisService.js |  44 ++
 .../src/main/webapp/plugin/js/brokerDiagram.js  | 665 +++++++++++++++++++
 .../src/main/webapp/plugin/js/browse.js         | 499 ++++++++++++++
 .../main/webapp/plugin/js/jmsHeaderSchema.js    |  62 ++
 .../src/main/webapp/plugin/js/preferences.js    |  54 ++
 .../src/main/webapp/plugin/js/queue.js          | 152 +++++
 .../src/main/webapp/plugin/js/send.js           | 211 ++++++
 .../src/main/webapp/plugin/js/tree.js           |  76 +++
 .../main/webapp/plugin/lib/artemis-console.js   |  82 +++
 artemis-hawtio/pom.xml                          |   1 +
 28 files changed, 3719 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/README.md
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/README.md b/artemis-hawtio/artemis-plugin/README.md
new file mode 100644
index 0000000..dbf6e45
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/README.md
@@ -0,0 +1,3 @@
+# artemis-hawtio
+
+Is a HawtIO plugin that allows the viewing and manipulation of topic/queues and other JMS resources.

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/pom.xml b/artemis-hawtio/artemis-plugin/pom.xml
new file mode 100644
index 0000000..234a054
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/pom.xml
@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.activemq</groupId>
+    <artifactId>artemis-hawtio-pom</artifactId>
+    <version>2.2.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>artemis-plugin</artifactId>
+  <name>ActiveMQ Artemis HawtIO Plugin</name>
+
+  <!-- hawtio plugins are almost always war files -->
+  <packaging>war</packaging>
+
+  <properties>
+    <activemq.basedir>${project.basedir}/../..</activemq.basedir>
+
+    <!-- filtered plugin properties, we don't define plugin-scripts here
+  as we build that dynamically using maven-antrun-plugin below. -->
+    <!-- plugin-context is what context this plugin will handle requests on
+      in the application server -->
+    <plugin-context>/artemis-plugin</plugin-context>
+
+    <!-- plugin-name is the name of our plugin, affects the name used for
+      the plugin's mbean -->
+    <plugin-name>${project.artifactId}</plugin-name>
+
+    <!-- plugin-domain is currently unused, we just define it to an empty
+      string -->
+    <plugin-domain/>
+
+    <!-- this lets this plugin deploy nicely into karaf, these get used
+      for the ImportPackage directive for maven-bundle-plugin -->
+    <fuse.osgi.import>
+      javax.servlet,
+      *;resolution:=optional
+    </fuse.osgi.import>
+
+    <webapp-dir>${project.artifactId}-${project.version}</webapp-dir>
+    <webapp-outdir>${basedir}/target/${webapp-dir}</webapp-outdir>
+    <schema-outdir>${basedir}/src/main/webapp/lib</schema-outdir>
+    <appjs-outfile>${webapp-outdir}/app/app.js</appjs-outfile>
+
+  </properties>
+
+  <dependencies>
+
+    <!-- we only need to embed this dependency in the war, this contains
+      a nice helper class that our plugin can use to export it's plugin
+      mbean -->
+    <dependency>
+      <groupId>io.hawt</groupId>
+      <artifactId>hawtio-plugin-mbean</artifactId>
+    </dependency>
+
+    <!-- servlet API is provided by the container -->
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>log4j</groupId>
+      <artifactId>log4j</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+  </dependencies>
+
+
+  <build>
+
+    <!-- we want to ensure src/main/resources/WEB-INF/web.xml is being filtered
+      so that it picks up all of our javascript files -->
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <includes>
+          <include>**/*.xml</include>
+        </includes>
+      </resource>
+    </resources>
+
+    <plugins>
+
+      <!-- We use maven-antrun-plugin to build up a list of
+           javascript files for our plugin mbean, this means
+           it needs to run before the maven-resources-plugin
+           copies and filters the web.xml, since for this
+           example we use contextParam settings to configure
+           our plugin mbean -->
+
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <version>${maven-antrun-plugin-version}</version>
+        <executions>
+
+          <execution>
+            <!-- we run this early in the build process before
+              maven-resources-plugin is run.  We're exporting the
+              plugin-scripts property from here, so we need to
+              use maven-antrun-plugin 1.6 or up -->
+            <id>generate-sources</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>run</goal>
+            </goals>
+            <configuration>
+              <target>
+                <echo>Building plugin javascript file list</echo>
+                <!-- javascript-files will contain all of the javascript in
+                  our project -->
+                <fileset id="javascript-files" dir="${basedir}/src/main/webapp">
+                  <include name="**/*.js"/>
+                </fileset>
+                <!-- we need to strip out the top level path which is
+                   our source directory and be sure to change the directory
+                   separators to forward slashes -->
+                <pathconvert pathsep="," dirsep="/" property="plugin-scripts" refid="javascript-files">
+                  <map from="${basedir}/src/main/webapp/" to=""/>
+                </pathconvert>
+                <echo>Files: ${plugin-scripts}</echo>
+
+              </target>
+              <!-- this exports plugin-scripts to the maven build, without
+                this line ${plugin-scripts} in the web.xml file won't be
+                replaced -->
+              <exportAntProperties>true</exportAntProperties>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>${maven-resources-plugin-version}</version>
+        <executions>
+          <execution>
+            <!-- defining this maven plugin in the same phase as the
+              maven-antrun-plugin but *after* we've configured the
+              maven-antrun-plugin ensures we filter resources *after*
+              we've discovered the plugin .js files. -->
+            <id>copy-resources</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>resources</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <!-- maven-bundle-plugin config, needed to make this war
+        deployable in karaf, defines the context that this bundle
+        should handle requests on -->
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${maven-bundle-plugin-version}</version>
+        <executions>
+          <execution>
+            <id>bundle-manifest</id>
+            <phase>process-classes</phase>
+            <goals>
+              <goal>manifest</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <manifestLocation>${webapp-outdir}/META-INF</manifestLocation>
+          <supportedProjectTypes>
+            <supportedProjectType>jar</supportedProjectType>
+            <supportedProjectType>bundle</supportedProjectType>
+            <supportedProjectType>war</supportedProjectType>
+          </supportedProjectTypes>
+          <instructions>
+            <Webapp-Context>${plugin-context}</Webapp-Context>
+            <Web-ContextPath>${plugin-context}</Web-ContextPath>
+
+            <Embed-Directory>WEB-INF/lib</Embed-Directory>
+            <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency>
+            <Embed-Transitive>true</Embed-Transitive>
+
+            <Export-Package>${fuse.osgi.export}</Export-Package>
+            <Import-Package>${fuse.osgi.import}</Import-Package>
+            <DynamicImport-Package>${fuse.osgi.dynamic}</DynamicImport-Package>
+            <Private-Package>${fuse.osgi.private.pkg}</Private-Package>
+
+            <Bundle-ClassPath>.,WEB-INF/classes</Bundle-ClassPath>
+
+            <Bundle-Name>${project.description}</Bundle-Name>
+            <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName>
+            <Implementation-Title>HawtIO</Implementation-Title>
+            <Implementation-Version>${project.version}</Implementation-Version>
+          </instructions>
+        </configuration>
+      </plugin>
+
+      <!-- We define the maven-war-plugin here and make sure it uses
+        the manifest file generated by the maven-bundle-plugin.  We
+        also ensure it picks up our filtered web.xml and not the one
+        in src/main/resources -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${war-plugin-version}</version>
+        <configuration>
+          <outputFileNameMapping>@{artifactId}@-@{baseVersion}@@{dashClassifier?}@.@{extension}@</outputFileNameMapping>
+          <packagingExcludes>**/classes/OSGI-INF/**</packagingExcludes>
+          <failOnMissingWebXml>false</failOnMissingWebXml>
+          <archive>
+            <manifestFile>${webapp-outdir}/META-INF/MANIFEST.MF</manifestFile>
+          </archive>
+          <webResources>
+            <resource>
+              <filtering>true</filtering>
+              <directory>src/main/resources</directory>
+              <includes>
+                <include>**/*.*</include>
+              </includes>
+              <excludes>
+                <exclude>log4j.properties</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+
+    </plugins>
+  </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/java/org/apache/activemq/hawtio/plugin/PluginContextListener.java
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/java/org/apache/activemq/hawtio/plugin/PluginContextListener.java b/artemis-hawtio/artemis-plugin/src/main/java/org/apache/activemq/hawtio/plugin/PluginContextListener.java
new file mode 100644
index 0000000..75fa706
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/java/org/apache/activemq/hawtio/plugin/PluginContextListener.java
@@ -0,0 +1,71 @@
+/*
+ * 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.hawtio.plugin;
+
+import io.hawt.web.plugin.HawtioPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * The Plugin Context Listener used to load in the plugin
+ **/
+public class PluginContextListener implements ServletContextListener {
+
+   private static final Logger LOG = LoggerFactory.getLogger(PluginContextListener.class);
+
+   HawtioPlugin plugin = null;
+
+   @Override
+   public void contextInitialized(ServletContextEvent servletContextEvent) {
+
+      ServletContext context = servletContextEvent.getServletContext();
+
+      plugin = new HawtioPlugin();
+      plugin.setContext((String)context.getInitParameter("plugin-context"));
+      plugin.setName(context.getInitParameter("plugin-name"));
+      plugin.setScripts(context.getInitParameter("plugin-scripts"));
+      plugin.setDomain(null);
+
+      try {
+         plugin.init();
+      } catch (Exception e) {
+         throw createServletException(e);
+      }
+
+      LOG.info("Initialized {} plugin", plugin.getName());
+   }
+
+   @Override
+   public void contextDestroyed(ServletContextEvent servletContextEvent) {
+      try {
+         plugin.destroy();
+      } catch (Exception e) {
+         throw createServletException(e);
+      }
+
+      LOG.info("Destroyed {} plugin", plugin.getName());
+   }
+
+   protected RuntimeException createServletException(Exception e) {
+      return new RuntimeException(e);
+   }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/resources/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/resources/WEB-INF/web.xml b/artemis-hawtio/artemis-plugin/src/main/resources/WEB-INF/web.xml
new file mode 100644
index 0000000..b6c454e
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/resources/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+	      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	      xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+	      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+	      version="2.4">
+
+  <description>An Artemis Plugin</description>
+  <display-name>An Artemis plugin</display-name>
+
+  <context-param>
+    <description>Plugin's path on the server</description>
+    <param-name>plugin-context</param-name>
+    <param-value>${plugin-context}</param-value>
+  </context-param>
+
+  <context-param>
+    <description>Plugin's path on the server</description>
+    <param-name>plugin-name</param-name>
+    <param-value>${project.artifactId}</param-value>
+  </context-param>
+
+  <context-param>
+    <description>Plugin's path on the server</description>
+    <param-name>plugin-domain</param-name>
+    <param-value>${plugin-domain}</param-value>
+  </context-param>
+
+  <context-param>
+    <description>Plugin's path on the server</description>
+    <param-name>plugin-scripts</param-name>
+    <param-value>${plugin-scripts}</param-value>
+  </context-param>
+
+  <listener>
+    <listener-class>org.apache.activemq.hawtio.plugin.PluginContextListener</listener-class>
+  </listener>
+
+
+</web-app>
+

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/resources/log4j.properties b/artemis-hawtio/artemis-plugin/src/main/resources/log4j.properties
new file mode 100644
index 0000000..52537ea
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/resources/log4j.properties
@@ -0,0 +1,23 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+
+log4j.rootLogger=INFO, console
+
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.ConversionPattern=%-5p | %t | %m%n
+

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/doc/help.md
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/doc/help.md b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/doc/help.md
new file mode 100644
index 0000000..e875acd
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/doc/help.md
@@ -0,0 +1,19 @@
+### Artemis
+
+Click [Artemis](#/jmx/attributes?tab=artemis) in the top navigation bar to see the Artemis specific plugin. (The Artemis tab won't appear if there is no broker in this JVM).  The Artemis plugin works very much the same as the JMX plugin however with a focus on interacting with an Artemis broker.
+
+The tree view on the left-hand side shows the top level JMX tree of each broker instance running in the JVM.  Expanding the tree will show the various MBeans registered by Artemis that you can inspect via the **Attributes** tab.
+
+#### Creating a new Address
+
+To create a new address simply click on the broker or the address folder in the jmx tree and click on the create tab.
+
+Once you have created an address you should be able to **Send** to it by clicking on it in the jmx tree and clicking on the send tab.
+
+#### Creating a new Queue
+
+To create a new queue click on the address you want to bind the queue to and click on the create tab.
+
+Once you have created a queue you should be able to **Send** a message to it or **Browse** it or view the  **Attributes** or **Charts**. Simply click on the queue in th ejmx tree and click on the appropriate tab.
+
+You can also see a graphical view of all brokers, addresses, queues and their consumers using the **Diagram** tab. 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/artemisLayout.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/artemisLayout.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/artemisLayout.html
new file mode 100644
index 0000000..eb254c9
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/artemisLayout.html
@@ -0,0 +1,42 @@
+<!--
+  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.
+  Architecture
+-->
+<script type="text/ng-template" id="header">
+  <div class="tree-header" ng-controller="ARTEMIS.TreeHeaderController">
+    <div class="left">
+    </div>
+    <div class="right">
+      <i class="icon-chevron-down clickable"
+         title="Expand all nodes"
+         ng-click="expandAll()"></i>
+      <i class="icon-chevron-up clickable"
+         title="Unexpand all nodes"
+         ng-click="contractAll()"></i>
+    </div>
+  </div>
+</script>
+<hawtio-pane position="left" width="300" header="header">
+  <div id="tree-container"
+       ng-controller="Jmx.MBeansController">
+    <div id="artemistree"
+         ng-controller="ARTEMIS.TreeController"></div>
+  </div>
+</hawtio-pane>
+<div class="row-fluid">
+  <ng-include src="'app/jmx/html/subLevelTabs.html'"></ng-include>
+  <div id="properties" ng-view></div>
+</div>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/brokerDiagram.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/brokerDiagram.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/brokerDiagram.html
new file mode 100644
index 0000000..9d0fd05
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/brokerDiagram.html
@@ -0,0 +1,313 @@
+<!--
+  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.
+  Architecture
+-->
+<style type="text/css">
+
+.span4.node-panel {
+  margin-top: 10px;
+  margin-left: 10px;
+  width: 33%;
+}
+.node-attributes dl {
+  margin-top: 5px;
+  margin-bottom: 10px;
+}
+.node-attributes dt {
+  width: 150px;
+}
+.node-attributes dd {
+  margin-left: 160px;
+}
+.node-attributes dd a {
+  /** lets make the destination links wrap */
+  -ms-word-break: break-all;
+  word-break: break-all;
+  -webkit-hyphens: auto;
+  -moz-hyphens: auto;
+  hyphens: auto;
+}
+
+ul.viewMenu li {
+  padding-left: 10px;
+  padding-top: 2px;
+  padding-bottom: 2px;
+}
+
+div#pop-up {
+  display: none;
+  position: absolute;
+  color: white;
+  font-size: 14px;
+  background: rgba(0, 0, 0, 0.6);
+  padding: 5px 10px 5px 10px;
+  -moz-border-radius: 8px 8px;
+  border-radius: 8px 8px;
+}
+
+div#pop-up-title {
+  font-size: 15px;
+  margin-bottom: 4px;
+  font-weight: bolder;
+}
+
+div#pop-up-content {
+  font-size: 12px;
+}
+
+rect.graphbox {
+  fill: #FFF;
+}
+
+rect.graphbox.frame {
+  stroke: #222;
+  stroke-width: 2px
+}
+
+/* only things directly related to the network graph should be here */
+
+path.link {
+  fill: none;
+  stroke: #666;
+  stroke-width: 1.5px;  b
+}
+
+marker.broker {
+  stroke: red;
+  fill: red;
+  stroke-width: 1.5px;
+}
+
+circle.broker {
+  fill: #0c0;
+}
+
+circle.brokerSlave {
+  fill: #c00;
+}
+
+circle.notActive {
+  fill: #c00;
+}
+
+path.link.group {
+  stroke: #ccc;
+}
+
+marker#group {
+  stroke: #ccc;
+  fill: #ccc;
+}
+
+circle.group {
+  fill: #eee;
+  stroke: #ccc;
+}
+
+circle.destination {
+  fill: #bbb;
+  stroke: #ccc;
+}
+
+circle.pinned {
+  stroke-width: 4.5px;
+}
+
+path.link.profile {
+  stroke-dasharray: 0, 2 1;
+  stroke: #888;
+}
+
+marker#container {
+}
+
+circle.container {
+  stroke-dasharray: 0, 2 1;
+  stroke: #888;
+}
+
+path.link.container {
+  stroke-dasharray: 0, 2 1;
+  stroke: #888;
+}
+
+circle {
+  fill: #ccc;
+  stroke: #333;
+  stroke-width: 1.5px;
+  cursor: pointer;
+}
+
+circle.closeMode {
+  cursor: crosshair;
+}
+
+path.link.destination {
+  stroke: #ccc;
+}
+
+circle.topic {
+  fill: #c0c;
+}
+
+circle.queue {
+  fill: #00c;
+}
+
+circle.consumer {
+  fill: #cfc;
+}
+
+circle.producer {
+  fill: #ccf;
+}
+
+path.link.producer {
+  stroke: #ccc;
+}
+
+path.link.consumer {
+  stroke: #ccc;
+}
+
+path.link.network {
+  stroke: #ccc;
+}
+
+circle.selected {
+  stroke-width: 3px;
+}
+
+.selected {
+  stroke-width: 3px;
+}
+
+text {
+  font: 10px sans-serif;
+  pointer-events: none;
+}
+
+text.shadow {
+  stroke: #fff;
+  stroke-width: 3px;
+  stroke-opacity: .8;
+}
+</style>
+
+
+<div class="row-fluid mq-page" ng-controller="ARTEMIS.BrokerDiagramController">
+
+  <div ng-hide="inDashboard" class="span12 page-padded">
+    <div class="section-header">
+
+      <div class="section-filter">
+        <input type="text" class="search-query" placeholder="Filter..." ng-model="searchFilter">
+        <i class="icon-remove clickable" title="Clear filter" ng-click="searchFilter = ''"></i>
+      </div>
+
+      <div class="section-controls">
+        <a href="#"
+           class="dropdown-toggle"
+           data-toggle="dropdown">
+          View &nbsp;<i class="icon-caret-down"></i>
+        </a>
+
+        <ul class="dropdown-menu viewMenu">
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.consumer"> Consumers
+            </label>
+          </li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.producer"> Producers
+            </label>
+          </li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.address"> Addresses
+            </label>
+          </li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.queue"> Queues
+            </label>
+          </li>
+          <li class="divider"></li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.broker"> Brokers
+            </label>
+          </li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.slave"> Slave brokers
+            </label>
+          </li>
+          <li>
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.network"> Networks
+            </label>
+          </li>
+          <li class="divider"></li>
+          <li title="Should we show the details panel on the left">
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.panel"> Details panel
+            </label>
+          </li>
+          <li title="Show the summary popup as you hover over nodes">
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.popup"> Hover text
+            </label>
+          </li>
+          <li title="Show the labels next to nodes">
+            <label class="checkbox">
+              <input type="checkbox" ng-model="viewSettings.label"> Label
+            </label>
+          </li>
+        </ul>
+
+      </div>
+    </div>
+  </div>
+
+
+  <div id="pop-up">
+    <div id="pop-up-title"></div>
+    <div id="pop-up-content"></div>
+  </div>
+
+  <div class="row-fluid">
+    <div class="{{viewSettings.panel ? 'span8' : 'span12'}} canvas broker-canvas">
+      <div hawtio-force-graph graph="graph" selected-model="selectedNode" link-distance="150" charge="-600" nodesize="10" marker-kind="marker-end"
+           style="min-height: 800px">
+      </div>
+    </div>
+    <div ng-show="viewSettings.panel" class="span4 node-panel">
+      <div ng-show="selectedNode" class="node-attributes">
+        <dl ng-repeat="property in selectedNodeProperties" class="dl-horizontal">
+          <dt title="{{property.key}}">{{property.key}}:</dt>
+          <dd ng-bind-html-unsafe="property.value"></dd>
+        </dl>
+      </div>
+    </div>
+  </div>
+
+  <div ng-include="'app/fabric/html/connectToContainerDialog.html'"></div>
+
+</div>
+
+

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/browseQueue.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/browseQueue.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/browseQueue.html
new file mode 100644
index 0000000..650972c
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/browseQueue.html
@@ -0,0 +1,156 @@
+<!--
+  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.
+  Architecture
+-->
+<div ng-controller="ARTEMIS.BrowseQueueController">
+  <div class="row-fluid">
+    <div class="span6">
+      <input class="search-query span12" type="text" ng-model="gridOptions.filterOptions.filterText"
+             placeholder="Filter messages">
+    </div>
+    <div class="span6">
+      <div class="pull-right">
+        <form class="form-inline">
+          <button class="btn" ng-disabled="!gridOptions.selectedItems.length" ng-show="dlq" ng-click="retryMessages()"
+                  title="Moves the dead letter queue message back to its original destination so it can be retried" data-placement="bottom">
+            <i class="icon-reply"></i> Retry
+          </button>
+          <button class="btn" ng-disabled="gridOptions.selectedItems.length !== 1" ng-click="resendMessage()"
+                    title="Edit the message to resend it" data-placement="bottom">
+           <i class="icon-share-alt"></i> Resend
+          </button>
+
+          <button class="btn" ng-disabled="!gridOptions.selectedItems.length" ng-click="moveDialog = true"
+                  title="Move the selected messages to another destination" data-placement="bottom">
+            <i class="icon-share-alt"></i> Move
+          </button>
+          <button class="btn" ng-disabled="!gridOptions.selectedItems.length"
+                  ng-click="deleteDialog = true"
+                  title="Delete the selected messages">
+            <i class="icon-remove"></i> Delete
+          </button>
+          <button class="btn" ng-click="refresh()"
+                  title="Refreshes the list of messages">
+            <i class="icon-refresh"></i>
+          </button>
+        </form>
+      </div>
+    </div>
+  </div>
+
+  <div class="row-fluid">
+    <div class="gridStyle" ng-grid="gridOptions"></div>
+  </div>
+
+  <div hawtio-slideout="showMessageDetails" title="{{row.JMSMessageID}}">
+    <div class="dialog-body">
+
+      <div class="row-fluid">
+        <div class="pull-right">
+          <form class="form-horizontal no-bottom-margin">
+
+            <div class="btn-group"
+                 hawtio-pager="messages"
+                 on-index-change="selectRowIndex"
+                 row-index="rowIndex"></div>
+
+            <button class="btn" ng-disabled="!gridOptions.selectedItems.length" ng-click="moveDialog = true"
+                    title="Move the selected messages to another destination" data-placement="bottom">
+              <i class="icon-share-alt"></i> Move
+            </button>
+
+            <button class="btn btn-danger" ng-disabled="!gridOptions.selectedItems.length"
+                    ng-click="deleteDialog = true"
+                    title="Delete the selected messages">
+              <i class="icon-remove"></i> Delete
+            </button>
+
+            <button class="btn" ng-click="showMessageDetails = !showMessageDetails" title="Close this dialog">
+              <i class="icon-remove"></i> Close
+            </button>
+
+          </form>
+        </div>
+      </div>
+
+      <div class="row-fluid">
+        <div class="expandable closed">
+          <div title="Headers" class="title">
+            <i class="expandable-indicator"></i> Headers & Properties
+          </div>
+          <div class="expandable-body well">
+            <table class="table table-condensed table-striped">
+              <thead>
+              <tr>
+                <th>Header</th>
+                <th>Value</th>
+              </tr>
+              </thead>
+              <tbody ng-bind-html-unsafe="row.headerHtml">
+              </tbody>
+              <!--
+                            <tr ng-repeat="(key, value) in row.headers">
+                              <td class="property-name">{{key}}</td>
+                              <td class="property-value">{{value}}</td>
+                            </tr>
+              -->
+            </table>
+          </div>
+        </div>
+      </div>
+
+      <div class="row-fluid">
+        <div>Displaying body as <span ng-bind="row.textMode"></span></div>
+        <div hawtio-editor="row.bodyText" read-only="true" mode='mode'></div>
+      </div>
+
+    </div>
+  </div>
+
+  <div hawtio-confirm-dialog="deleteDialog"
+       ok-button-text="Delete"
+       on-ok="deleteMessages()">
+    <div class="dialog-body">
+      <p>You are about to delete
+        <ng-pluralize count="gridOptions.selectedItems.length"
+                      when="{'1': 'a message!', 'other': '{} messages!'}">
+        </ng-pluralize>
+      </p>
+      <p>This operation cannot be undone so please be careful.</p>
+    </div>
+  </div>
+
+  <div hawtio-confirm-dialog="moveDialog"
+       ok-button-text="Move"
+       on-ok="moveMessages()">
+    <div class="dialog-body">
+      <p>Move
+        <ng-pluralize count="gridOptions.selectedItems.length"
+                      when="{'1': 'message', 'other': '{} messages'}"></ng-pluralize>
+        to: <input type="text" ng-model="queueName" placeholder="Queue name"
+                   typeahead="title.unescapeHTML() for title in queueNames($viewValue) | filter:$viewValue" typeahead-editable='true'></p>
+      <p>
+        You cannot undo this operation.<br>
+        Though after the move you can always move the
+        <ng-pluralize count="gridOptions.selectedItems.length"
+                      when="{'1': 'message', 'other': 'messages'}"></ng-pluralize>
+        back again.
+      </p>
+    </div>
+  </div>
+
+</div>
+

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createAddress.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createAddress.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createAddress.html
new file mode 100644
index 0000000..0eb2d0a
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createAddress.html
@@ -0,0 +1,44 @@
+<!--
+  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.
+  Architecture
+-->
+<form class="form-horizontal" ng-controller="ARTEMIS.AddressController">
+    <div class="control-group">
+        <label class="control-label" for="addressName"
+                title="The routing name of this address">Address name</label>
+        <div class="controls">
+            <input id="addressName" type="text" maxlength="300" ng-model="addressName" placeholder="Address Name"/>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <label class="control-label" for="routingType">Routing type</label>
+
+        <div class="controls">
+            <select id="routingType" ng-model="routingType">
+                <option value='0'>Multicast</option>
+                <option value='1'>Anycast</option>
+                <option value='2'>Both</option>
+            </select>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <div class="controls">
+            <button type="submit" class="btn btn-info" ng-click="createAddress(addressName, routingType)" ng-disabled="!addressName">Create Address</button>
+        </div>
+    </div>
+</form>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createQueue.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createQueue.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createQueue.html
new file mode 100644
index 0000000..1d294fa
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/createQueue.html
@@ -0,0 +1,77 @@
+<!--
+  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.
+  Architecture
+-->
+<form class="form-horizontal" ng-controller="ARTEMIS.QueueController">
+
+    <div class="control-group">
+        <label class="control-label" for="queueName"
+               title="The routing name of this address">Queue name</label>
+        <div class="controls">
+            <input id="queueName" type="text" maxlength="300" ng-model="queueName" placeholder="Queue Name"/>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <label class="control-label" for="routingType">Routing type</label>
+
+        <div class="controls">
+            <select id="routingType" ng-model="routingType">
+                <option value='0'>Multicast</option>
+                <option value='1'>Anycast</option>
+            </select>
+        </div>
+    </div>
+
+
+    <div class="control-group">
+        <label class="control-label" for="durable"
+               title="Whether the queue will be durable">Durable</label>
+        <div class="controls">
+            <input id="durable" type="checkbox" ng-model="durable" value="false">
+        </div>
+    </div>
+
+    <div class="control-group">
+        <label class="control-label" for="filter"
+               title="The user name to be used when connecting to the broker">Filter</label>
+        <div class="controls">
+            <input id="filter" type="text" maxlength="300" ng-model="filter" placeholder="Filter"/>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <label class="control-label" for="maxConsumers"
+               title="The maximum consumers the queue can have">Max Consumers</label>
+        <div class="controls">
+            <input id="maxConsumers" type="number" ng-model="maxConsumers" placeholder="maxConsumers"/>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <label class="control-label" for="purgeWhenNoConsumers"
+               title="Whether or not this queue should be purged (emptied and paused) when there are no consumers">Purge when no consumers</label>
+        <div class="controls">
+            <input id="purgeWhenNoConsumers" type="checkbox" ng-model="purgeWhenNoConsumers" value="false"/>
+        </div>
+    </div>
+
+    <div class="control-group">
+        <div class="controls">
+            <button type="submit" class="btn btn-info" ng-click="createQueue(queueName, routingType, durable, filter, maxConsumers, purgeWhenNoConsumers)" ng-disabled="!queueName">Create Queue</button>
+        </div>
+    </div>
+</form>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteAddress.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteAddress.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteAddress.html
new file mode 100644
index 0000000..afa3172
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteAddress.html
@@ -0,0 +1,48 @@
+<!--
+  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.
+  Architecture
+-->
+<div ng-controller="ARTEMIS.AddressController">
+  <div class="row-fluid">
+
+    <div class="control-group">
+      <div class="alert">
+        <button type="button" class="close" data-dismiss="alert">×</button>
+        <strong>Warning:</strong> these operations cannot be undone. Please be careful!
+      </div>
+    </div>
+  </div>
+  <div class="row-fluid">
+    <div class="span4">
+      <div class="control-group">
+        <button type="submit" class="btn btn-warning" ng-click="deleteDialog = true">Delete address '{{name().unescapeHTML()}}'</button>
+        <label>This will remove the address completely.</label>
+      </div>
+    </div>
+  </div>
+
+  <div hawtio-confirm-dialog="deleteDialog"
+       ok-button-text="Delete"
+       on-ok="deleteAddress()">
+    <div class="dialog-body">
+      <p>You are about to delete the <b>{{name().unescapeHTML()}}</b> address</p>
+      <p>This operation cannot be undone so please be careful.</p>
+    </div>
+  </div>
+
+
+
+</div>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteQueue.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteQueue.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteQueue.html
new file mode 100644
index 0000000..9caa7c3
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/deleteQueue.html
@@ -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.
+  Architecture
+-->
+<div ng-controller="ARTEMIS.QueueController">
+  <div class="row-fluid">
+
+    <div class="control-group">
+      <div class="alert">
+        <button type="button" class="close" data-dismiss="alert">×</button>
+        <strong>Warning:</strong> these operations cannot be undone. Please be careful!
+      </div>
+    </div>
+  </div>
+  <div class="row-fluid">
+    <div class="span4">
+      <div class="control-group">
+        <button type="submit" class="btn btn-warning" ng-click="deleteDialog = true">Delete queue '{{name().unescapeHTML()}}'</button>
+        <label>This will remove the queue completely.</label>
+      </div>
+    </div>
+    <div class="span4">
+      <div class="control-group">
+        <button type="submit" class="btn btn-warning" ng-click="purgeDialog = true">Purge queue '{{name().unescapeHTML()}}'</button>
+        <label>Purges all the current messages on the queue.</label>
+      </div>
+    </div>
+  </div>
+
+  <div hawtio-confirm-dialog="deleteDialog"
+       ok-button-text="Delete"
+       on-ok="deleteDestination(true)">
+    <div class="dialog-body">
+      <p>You are about to delete the <b>{{name().unescapeHTML()}}</b> queue</p>
+      <p>This operation cannot be undone so please be careful.</p>
+    </div>
+  </div>
+
+  <div hawtio-confirm-dialog="purgeDialog"
+       ok-button-text="Purge"
+       on-ok="purgeDestination()">
+    <div class="dialog-body">
+      <p>You are about to purge the <b>{{name().unescapeHTML()}}</b> queue</p>
+      <p>This operation cannot be undone so please be careful.</p>
+    </div>
+  </div>
+
+
+</div>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/preferences.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/preferences.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/preferences.html
new file mode 100644
index 0000000..10fb619
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/preferences.html
@@ -0,0 +1,69 @@
+<!--
+  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.
+  Architecture
+-->
+<div ng-controller="ARTEMIS.PreferencesController">
+  <form class="form-horizontal">
+
+    <div class="control-group">
+      <label class="control-label" for="artemisUserName"
+             title="The user name to be used when connecting to the broker">User name</label>
+
+      <div class="controls">
+        <input id="artemisUserName" type="text" placeholder="username" ng-model="artemisUserName" autofill/>
+      </div>
+    </div>
+    <div class="control-group">
+      <label class="control-label" for="artemisPassword" title="Password to be used when connecting to the broker">Password</label>
+
+      <div class="controls">
+        <input id="artemisPassword" type="password" placeholder="password" ng-model="artemisPassword" autofill/>
+      </div>
+    </div>
+
+    <div class="control-group">
+      <label class="control-label" for="artemisDLQ" title="The DLQ of the Broker">DLQ</label>
+
+      <div class="controls">
+        <input id="artemisDLQ" type="text" placeholder="DLQ" ng-model="artemisDLQ" autofill/>
+      </div>
+    </div>
+
+    <div class="control-group">
+      <label class="control-label" for="artemisExpiryQueue" title="The Expiry Queue of the Broker">Expiry Queue</label>
+
+      <div class="controls">
+        <input id="artemisExpiryQueue" type="text" placeholder="ExpiryQueue" ng-model="artemisExpiryQueue" autofill/>
+      </div>
+    </div>
+
+    <div class="control-group">
+      <label class="control-label" for="byteMessages">Browse byte messages</label>
+
+      <div class="controls">
+        <select id="byteMessages" ng-model="activemqBrowseBytesMessages">
+          <option value='99'>Off</option>
+          <option value='8'>Decimal</option>
+          <option value='4'>Hex</option>
+          <option value='2'>Decimal and text</option>
+          <option value='1'>Hex and text</option>
+        </select>
+        <span class="help-block">Browsing byte messages should display the message body as</span>
+      </div>
+    </div>
+
+  </form>
+</div>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/sendMessage.html
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/sendMessage.html b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/sendMessage.html
new file mode 100644
index 0000000..002b558
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/html/sendMessage.html
@@ -0,0 +1,135 @@
+<!--
+  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.
+  Architecture
+-->
+<div ng-controller="ARTEMIS.SendMessageController">
+
+  <div class="tabbable" ng-model="tab">
+
+    <div value="compose" class="tab-pane" title="Compose">
+      <!--
+         title="Compose a new message to send"
+      -->
+
+      <div class="row-fluid">
+        <span ng-show="noCredentials" class="alert">
+          No credentials set for endpoint!  Please set your username and password in the <a
+            href="" ng-click="openPrefs()">Preferences</a> page
+        </span>
+
+        <form class="form-inline pull-right">
+          <div class="row-fluid">
+            <div class="controls">
+              <label class="control-label" for="durable" title="Is this message durable">Durable: </label>
+              <input id="durable" type="checkbox" ng-model="durable" value="true">
+            </div>
+          <button class="btn" ng-click="addHeader()" title="Add a new message header"><i
+              class="icon-plus"></i> Header
+          </button>
+          <button type="submit" class="btn btn-primary" ng-click="sendMessage(durable)">Send message</button>
+        </form>
+      </div>
+
+      <form class="form-inline bottom-margin" ng-submit="addHeader()">
+        <ol class="zebra-list header-list">
+          <div class="row-fluid">
+            <li ng-repeat="header in headers">
+              <div class="span4">
+                <input type="text" style="width: 100%" class="headerName"
+                       ng-model="header.name"
+                       typeahead="completion for completion in defaultHeaderNames() | filter:$viewValue"
+                       typeahead-editable='true'
+                       placeholder="Header name">
+              </div>
+              <div class="span6">
+                <input type="text" style="width: 100%" ng-model="header.value"
+                       placeholder="Value of the message header">
+              </div>
+              <div class="span2">
+                <button type="submit" class="btn" title="Add a new message header">
+                  <i class="icon-plus"></i>
+                </button>
+                <button type="button" ng-click="removeHeader(header)" class="btn" title="Removes this message header">
+                  <i class="icon-remove"></i>
+                </button>
+              </div>
+            </li>
+          </div>
+        </ol>
+      </form>
+
+      <div class="row-fluid">
+        <form class="form-inline">
+          <div class="controls">
+            <label class="control-label" for="sourceFormat" title="The text format to use for the message payload">Payload
+              format: </label>
+            <select ng-model="codeMirrorOptions.mode.name" id="sourceFormat">
+              <option value="javascript">JSON</option>
+              <option value="text" selected>Plain text</option>
+              <option value="properties">Properties</option>
+              <option value="xml">XML</option>
+            </select>
+
+            <button class="btn" ng-click="autoFormat()"
+                    title="Automatically pretty prints the message so its easier to read">Auto format
+            </button>
+          </div>
+        </form>
+      </div>
+
+      <div class="row-fluid">
+        <textarea ui-codemirror="codeMirrorOptions" ng-model="message"></textarea>
+      </div>
+    </div>
+    </tab>
+
+    <div ng-switch="showChoose">
+      <div ng-switch-when="true">
+        <div value="choose" class="tab-pane" title="Choose">
+          <!--
+                   title="Choose messages to send from the available files in the Profile configuration for this container">
+          -->
+          <div class="row-fluid bottom-margin">
+        <span ng-show="noCredentials" class="alert">
+          No credentials set for endpoint!  Please set your username and password in the <a
+            href="#/preferences">Preferences</a> page
+        </span>
+            <button type="submit" ng-disabled="!fileSelection().length" class="btn btn-primary pull-right"
+                    ng-click="sendSelectedFiles()">
+              <ng-pluralize count="fileSelection().length"
+                            when="{'0': 'No files selected', '1': 'Send the file','other': 'Send {} files'}">
+              </ng-pluralize>
+            </button>
+          </div>
+
+          <p>Choose which files to send from the profile configuration:</p>
+
+          <div class="control-group inline-block">
+            <input class="search-query" type="text" ng-model="searchText" placeholder="Filter..." autofocus>
+          </div>
+
+          <ul>
+            <li ng-repeat="fileName in profileFileNames | filter:searchText">
+              <input type="checkbox" ng-model="selectedFiles[fileName]"> {{fileName}}
+            </li>
+          </ul>
+        </div>
+      </div>
+
+    </div>
+
+  </div>
+</div>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/address.js
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/address.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/address.js
new file mode 100644
index 0000000..cc0aef1
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/address.js
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+/**
+ * @module ARTEMIS
+ */
+var ARTEMIS = (function(ARTEMIS) {
+
+    /**
+     * @method AddressController
+     * @param $scope
+     * @param ARTEMISService
+     *
+     * Controller for the Create interface
+     */
+    ARTEMIS.AddressController = function ($scope, workspace, ARTEMISService, jolokia, localStorage) {
+        Core.initPreferenceScope($scope, localStorage, {
+            'routingType': {
+                'value': 0,
+                'converter': parseInt,
+                'formatter': parseInt
+            }
+        });
+        var artemisJmxDomain = localStorage['artemisJmxDomain'] || "org.apache.activemq.artemis";
+        $scope.workspace = workspace;
+        $scope.message = "";
+        $scope.deleteDialog = false;
+        $scope.$watch('workspace.selection', function () {
+            workspace.moveIfViewInvalid();
+        });
+        function operationSuccess() {
+            $scope.addressName = "";
+            $scope.workspace.operationCounter += 1;
+            Core.$apply($scope);
+            Core.notification("success", $scope.message);
+            $scope.workspace.loadTree();
+        }
+        function deleteSuccess() {
+            // lets set the selection to the parent
+            workspace.removeAndSelectParentNode();
+            $scope.workspace.operationCounter += 1;
+            Core.$apply($scope);
+            Core.notification("success", $scope.message);
+            $scope.workspace.loadTree();
+        }
+        $scope.createAddress = function (name, routingType) {
+            var mbean = getBrokerMBean(jolokia);
+            if (mbean) {
+                if (routingType == 0) {
+                    $scope.message = "Created  Multicast Address " + name;
+                    ARTEMIS.log.info($scope.message);
+                    ARTEMISService.artemisConsole.createAddress(mbean, jolokia, name, "MULTICAST", onSuccess(operationSuccess));
+                }
+                else if (routingType == 1) {
+                    $scope.message = "Created Anycast Address " + name;
+                    ARTEMIS.log.info($scope.message);
+                    ARTEMISService.artemisConsole.createAddress(mbean, jolokia, name, "ANYCAST", onSuccess(operationSuccess));
+                }
+                else {
+                    $scope.message = "Created Anycast/Multicast Address " + name;
+                    ARTEMIS.log.info($scope.message);
+                    ARTEMISService.artemisConsole.createAddress(mbean, jolokia, name, "ANYCAST,MULTICAST", onSuccess(operationSuccess));
+                }
+            }
+        };
+        $scope.deleteAddress = function () {
+            var selection = workspace.selection;
+            var entries = selection.entries;
+            var mbean = getBrokerMBean(jolokia);
+            ARTEMIS.log.info(mbean);
+            if (mbean) {
+                if (selection && jolokia && entries) {
+                    var domain = selection.domain;
+                    var name = entries["name"];
+                    name = name.unescapeHTML();
+                    if (name.charAt(0) === '"' && name.charAt(name.length -1) === '"')
+                    {
+                        name = name.substr(1,name.length -2);
+                    }
+                    ARTEMIS.log.info(name);
+                    var operation;
+                    $scope.message = "Deleted address " + name;
+                    ARTEMISService.artemisConsole.deleteAddress(mbean, jolokia, name, onSuccess(deleteSuccess));
+                }
+            }
+        };
+        $scope.name = function () {
+            var selection = workspace.selection;
+            if (selection) {
+                return selection.title;
+            }
+            return null;
+        };
+
+        function getBrokerMBean(jolokia) {
+            var mbean = null;
+            var selection = workspace.selection;
+            var folderNames = selection.folderNames;
+            mbean = "" + folderNames[0] + ":broker=" + folderNames[1];
+            ARTEMIS.log.info("broker=" + mbean);
+            return mbean;
+        }
+    };
+
+    return ARTEMIS;
+} (ARTEMIS || {}));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisHelpers.js
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisHelpers.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisHelpers.js
new file mode 100644
index 0000000..210c52a
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisHelpers.js
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var ARTEMIS;
+(function (ARTEMIS) {
+    ARTEMIS.log = Logger.get("ARTEMIS");
+    ARTEMIS.jmxDomain = 'org.apache.ARTEMIS';
+    function getSelectionQueuesFolder(workspace) {
+        function findQueuesFolder(node) {
+            if (node) {
+                if (node.title === "Queues" || node.title === "Queue") {
+                    return node;
+                }
+                var parent = node.parent;
+                if (parent) {
+                    return findQueuesFolder(parent);
+                }
+            }
+            return null;
+        }
+        var selection = workspace.selection;
+        if (selection) {
+            return findQueuesFolder(selection);
+        }
+        return null;
+    }
+    ARTEMIS.getSelectionQueuesFolder = getSelectionQueuesFolder;
+    function getSelectionTopicsFolder(workspace) {
+        function findTopicsFolder(node) {
+            var answer = null;
+            if (node) {
+                if (node.title === "Topics" || node.title === "Topic") {
+                    answer = node;
+                }
+                if (answer === null) {
+                    angular.forEach(node.children, function (child) {
+                        if (child.title === "Topics" || child.title === "Topic") {
+                            answer = child;
+                        }
+                    });
+                }
+            }
+            return answer;
+        }
+        var selection = workspace.selection;
+        if (selection) {
+            return findTopicsFolder(selection);
+        }
+        return null;
+    }
+    ARTEMIS.getSelectionTopicsFolder = getSelectionTopicsFolder;
+    /**
+     * Sets $scope.row to currently selected JMS message.
+     * Used in:
+     *  - ARTEMIS/js/browse.ts
+     *  - camel/js/browseEndpoint.ts
+     *
+     * TODO: remove $scope argument and operate directly on other variables. but it's too much side effects here...
+     *
+     * @param message
+     * @param key unique key inside message that distinguishes between values
+     * @param $scope
+     */
+    function selectCurrentMessage(message, key, $scope) {
+        // clicking on message's link would interfere with messages selected with checkboxes
+        $scope.gridOptions.selectAll(false);
+        var idx = Core.pathGet(message, ["rowIndex"]);
+        var jmsMessageID = Core.pathGet(message, ["entity", key]);
+        $scope.rowIndex = idx;
+        var selected = $scope.gridOptions.selectedItems;
+        selected.splice(0, selected.length);
+        if (idx >= 0 && idx < $scope.messages.length) {
+            $scope.row = $scope.messages.find(function (msg) { return msg[key] === jmsMessageID; });
+            if ($scope.row) {
+                selected.push($scope.row);
+            }
+        }
+        else {
+            $scope.row = null;
+        }
+    }
+    ARTEMIS.selectCurrentMessage = selectCurrentMessage;
+    /**
+     * - Adds functions needed for message browsing with details
+     * - Adds a watch to deselect all rows after closing the slideout with message details
+     * TODO: export these functions too?
+     *
+     * @param $scope
+     */
+    function decorate($scope) {
+        $scope.selectRowIndex = function (idx) {
+            $scope.rowIndex = idx;
+            var selected = $scope.gridOptions.selectedItems;
+            selected.splice(0, selected.length);
+            if (idx >= 0 && idx < $scope.messages.length) {
+                $scope.row = $scope.messages[idx];
+                if ($scope.row) {
+                    selected.push($scope.row);
+                }
+            }
+            else {
+                $scope.row = null;
+            }
+        };
+        $scope.$watch("showMessageDetails", function () {
+            if (!$scope.showMessageDetails) {
+                $scope.row = null;
+                $scope.gridOptions.selectedItems.splice(0, $scope.gridOptions.selectedItems.length);
+            }
+        });
+    }
+    ARTEMIS.decorate = decorate;
+})(ARTEMIS || (ARTEMIS = {}));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
new file mode 100644
index 0000000..6f79169
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+/**
+ * @module ARTEMIS
+ * @main ARTEMIS
+ *
+ * The main entrypoint for the ARTEMIS module
+ *
+ */
+var ARTEMIS = (function(ARTEMIS) {
+
+   /**
+    * @property pluginName
+    * @type {string}
+    *
+    * The name of this plugin
+    */
+   ARTEMIS.pluginName = "ARTEMIS";
+
+   /**
+    * @property log
+    * @type {Logging.Logger}
+    *
+    * This plugin's logger instance
+    */
+   ARTEMIS.log = Logger.get(ARTEMIS.pluginName);
+
+   /**
+    * @property templatePath
+    * @type {string}
+    *
+    * The top level path to this plugin's partials
+    */
+   ARTEMIS.templatePath = "../artemis-plugin/plugin/html/";
+
+   /**
+    * @property jmxDomain
+    * @type {string}
+    *
+    * The JMX domain this plugin mostly works with
+    */
+   ARTEMIS.jmxDomain = "hawtio"
+
+   /**
+    * @property mbeanType
+    * @type {string}
+    *
+    * The mbean type this plugin will work with
+    */
+   ARTEMIS.mbeanType = "ARTEMISHandler";
+
+   /**
+    * @property mbean
+    * @type {string}
+    *
+    * The mbean's full object name
+    */
+   ARTEMIS.mbean = ARTEMIS.jmxDomain + ":type=" + ARTEMIS.mbeanType;
+
+   /**
+    * @property SETTINGS_KEY
+    * @type {string}
+    *
+    * The key used to fetch our settings from local storage
+    */
+   ARTEMIS.SETTINGS_KEY = 'ARTEMISSettings';
+
+   /**
+    * @property module
+    * @type {object}
+    *
+    * This plugin's angularjs module instance
+    */
+   ARTEMIS.module = angular.module(ARTEMIS.pluginName, ['bootstrap', 'ngResource', 'ui.bootstrap.dialog', 'hawtioCore', 'camel', 'hawtio-ui']);
+
+   // set up the routing for this plugin, these are referenced by the subleveltabs added below
+   ARTEMIS.module.config(function($routeProvider) {
+      $routeProvider
+         .when('/artemis/createAddress', {
+            templateUrl: ARTEMIS.templatePath + 'createAddress.html'
+         })
+         .when('/artemis/deleteAddress', {
+            templateUrl: ARTEMIS.templatePath + 'deleteAddress.html'
+         })
+         .when('/artemis/deleteQueue', {
+            templateUrl: ARTEMIS.templatePath + 'deleteQueue.html'
+         })
+         .when('/artemis/createQueue', {
+            templateUrl: ARTEMIS.templatePath + 'createQueue.html'
+         })
+         .when('/artemis/browseQueue', {
+            templateUrl: ARTEMIS.templatePath + 'browseQueue.html'
+         })
+         .when('/artemis/diagram', {
+            templateUrl: ARTEMIS.templatePath + 'brokerDiagram.html'
+         })
+         .when('/artemis/sendMessage', {
+            templateUrl: ARTEMIS.templatePath + 'sendMessage.html'
+         });
+   });
+
+   ARTEMIS.module.factory('artemisMessage', function () {
+        return { 'message': null };
+    });
+
+   // one-time initialization happens in the run function
+   // of our module
+   ARTEMIS.module.run(function(workspace, viewRegistry, helpRegistry, preferencesRegistry, localStorage, jolokia, ARTEMISService, $rootScope) {
+      // let folks know we're actually running
+      ARTEMIS.log.info("plugin running " + jolokia);
+
+      var artemisJmxDomain = localStorage['artemisJmxDomain'] || "org.apache.activemq.artemis";
+
+      ARTEMISService.initArtemis();
+
+      // tell hawtio that we have our own custom layout for
+      // our view
+      viewRegistry["artemis"] = ARTEMIS.templatePath + "artemisLayout.html";
+
+      helpRegistry.addUserDoc("artemis", "../artemis-plugin/plugin/doc/help.md", function () {
+         return workspace.treeContainsDomainAndProperties(artemisJmxDomain);
+     });
+
+      preferencesRegistry.addTab("Artemis", ARTEMIS.templatePath + "preferences.html", function () {
+         return workspace.treeContainsDomainAndProperties(artemisJmxDomain);
+      });
+
+      // Add a top level tab to hawtio's navigation bar
+      workspace.topLevelTabs.push({
+         id: "artemis",
+         content: "Artemis",
+         title: "Artemis Broker",
+         isValid: function (workspace) {
+            return workspace.treeContainsDomainAndProperties(artemisJmxDomain);
+         },
+         href: function () {
+            return "#/jmx/attributes?tab=artemis";
+         },
+         isActive: function () {
+            return workspace.isLinkActive("artemis");
+         }
+      });
+
+      workspace.subLevelTabs.push({
+         content: '<i class="icon-plus"></i> Create',
+         title: "Create a new address",
+         isValid: function (workspace) {
+            return isBroker(workspace, artemisJmxDomain) || isAddressFolder(workspace, artemisJmxDomain);
+         },
+         href: function () {
+            return "#/artemis/createAddress";
+         }
+      });
+
+      workspace.subLevelTabs.push({
+         content: '<i class="icon-plus"></i> Delete',
+         title: "Delete an address",
+         isValid: function (workspace) {
+            return isAddress(workspace, artemisJmxDomain);
+         },
+         href: function () {
+            return "#/artemis/deleteAddress";
+         }
+      });
+
+      workspace.subLevelTabs.push({
+         content: '<i class="icon-plus"></i> Create',
+         title: "Create a new queue",
+         isValid: function (workspace) {
+            return isAddress(workspace, artemisJmxDomain)
+         },
+         href: function () {
+            return "#/artemis/createQueue"
+         }
+      });
+
+      workspace.subLevelTabs.push({
+         content: '<i class="icon-remove"></i> Delete',
+         title: "Delete or purge this queue",
+         isValid: function (workspace) {
+            return isQueue(workspace, artemisJmxDomain)
+         },
+         href: function () {
+            return "#/artemis/deleteQueue"
+         }
+      });
+
+      workspace.subLevelTabs.push({
+          content: '<i class="icon-envelope"></i> Browse',
+          title: "Browse the messages on the queue",
+          isValid: function (workspace) { return isQueue(workspace, artemisJmxDomain); },
+          href: function () { return "#/artemis/browseQueue"; }
+      });
+
+      workspace.subLevelTabs.push({
+      content: '<i class="icon-pencil"></i> Send',
+      title: "Send a message to this address",
+      isValid: function (workspace) { return isAddress(workspace, artemisJmxDomain) || isQueue(workspace, artemisJmxDomain); },
+      href: function () { return "#/artemis/sendMessage"; }
+      });
+
+      workspace.subLevelTabs.push({
+          content: '<i class="icon-picture"></i> Diagram',
+          title: "View a diagram of the producers, destinations and consumers",
+          isValid: function (workspace) { return workspace.isTopTabActive("artemis") || workspace.selectionHasDomain(artemisJmxDomain); },
+          href: function () { return "#/artemis/diagram"; }
+      });
+});
+
+
+   function isBroker(workspace, domain) {
+      return workspace.hasDomainAndProperties(domain, {'broker': 'Broker'}, 3);
+   }
+
+   function isAddressFolder(workspace, domain) {
+      return workspace.selectionHasDomainAndLastFolderName(domain, 'addresses');
+   }
+                                                                                          
+   function isAddress(workspace, domain) {
+      return workspace.hasDomainAndProperties(domain, {'component': 'addresses'}) && !workspace.hasDomainAndProperties(domain, {'subcomponent': 'queues'});
+   }
+
+   function isQueue(workspace, domain) {
+      return workspace.hasDomainAndProperties(domain, {'subcomponent': 'queues'});
+   }
+
+   return ARTEMIS;
+}(ARTEMIS || {}));
+
+// Very important!  Add our module to hawtioPluginLoader so it
+// bootstraps our module
+hawtioPluginLoader.addModule(ARTEMIS.pluginName);
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/fa7b247d/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisService.js
----------------------------------------------------------------------
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisService.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisService.js
new file mode 100644
index 0000000..3d7aa55
--- /dev/null
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisService.js
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+/**
+ * @module ARTEMIS
+ */
+var ARTEMIS = (function(ARTEMIS) {
+
+  ARTEMIS.SERVER = 'Server Messages';
+
+
+  // The ARTEMIS service handles the connection to
+  // the Artemis Jolokia server in the background
+  ARTEMIS.module.factory("ARTEMISService", function(jolokia, $rootScope) {
+    var self = {
+      artemisConsole: undefined,
+
+      getVersion: function(jolokia) {
+        ARTEMIS.log.info("Connecting to ARTEMIS service: " + self.artemisConsole.getServerAttributes(jolokia));
+      } ,
+      initArtemis: function(broker) {
+        ARTEMIS.log.info("*************creating Artemis Console************");
+        self.artemisConsole = new ArtemisConsole();
+      }
+    };
+
+    return self;
+  });
+
+  return ARTEMIS;
+}(ARTEMIS || {}));


Mime
View raw message