XML Tranform JMS Queue/Topic to new model
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/d70bf3ba Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/d70bf3ba Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/d70bf3ba Branch: refs/heads/ARTEMIS-780 Commit: d70bf3bac49151fa3fbc5e7a0e7b33d5316af5f1 Parents: 4e378c1 Author: Martyn Taylor <[email protected]> Authored: Tue Oct 25 14:15:34 2016 +0100 Committer: Clebert Suconic <[email protected]> Committed: Mon Nov 7 11:28:07 2016 -0500 ---------------------------------------------------------------------- .../artemis/tools/migrate/config/Main.java | 85 +++++ .../config/XMLConfigurationMigration.java | 330 ++++++++++++------- .../src/main/resources/META-INF/MANIFEST.MF | 2 +- .../config/XMLConfigurationMigrationTest.java | 9 +- artemis-tools/src/test/resources/broker.xml | 13 +- 5 files changed, 307 insertions(+), 132 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d70bf3ba/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/Main.java ---------------------------------------------------------------------- diff --git a/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/Main.java b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/Main.java new file mode 100644 index 0000000..c45d92a --- /dev/null +++ b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/Main.java @@ -0,0 +1,85 @@ +/* + * 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.artemis.tools.migrate.config; + +import java.io.File; + +public class Main { + + public static void main(String[] args) throws Exception { + + if (args.length == 0) { + System.err.println("Invalid args"); + printUsage(); + } else { + File input = new File(args[0]); + if (input.isDirectory()) { + System.out.println("Scanning directory: " + input.getAbsolutePath()); + recursiveTransform(input); + } else { + if (args.length != 2) { + System.err.println("Invalid args"); + printUsage(); + } else { + try { + XMLConfigurationMigration migration = new XMLConfigurationMigration(input, new File(args[1])); + } + catch (Exception e) { + // Unable to process file, move on. + } + } + } + } + } + + private static void recursiveTransform(File root) throws Exception { + for (File file : root.listFiles()) { + scanAndTransform(file); + } + } + + public static void scanAndTransform(File pFile) throws Exception { + try { + for (File f : pFile.listFiles()) { + if (f.isDirectory()) { + scanAndTransform(f); + } else { + try { + if (f.getName().endsWith("xml")) { + File file = new File(f.getAbsolutePath() + ".new"); + XMLConfigurationMigration migration = new XMLConfigurationMigration(f, file); + if (migration.transform()) { + File r = new File(f.getAbsolutePath()); + f.renameTo(new File(f.getAbsolutePath() + ".bk")); + file.renameTo(r); + } + } + } catch (Exception e) { + //Unable to process file, continue + } + } + } + } catch (NullPointerException e) { + System.out.println(pFile.getAbsoluteFile()); + } + } + + public static void printUsage() { + System.out.println("Please specify a directory to scan, or input and output file"); + } + +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d70bf3ba/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java ---------------------------------------------------------------------- diff --git a/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java index 90be53c..f5811a6 100644 --- a/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java +++ b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java @@ -26,9 +26,12 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.io.File; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; @@ -41,83 +44,97 @@ import org.w3c.dom.NodeList; public class XMLConfigurationMigration { - private static XMLConfigurationMigration migration; + // Attributes + private static final String xPathAttrName = "@name"; + + // JMS XPaths + private static final String xPathJMS = "/configuration/jms"; + + private static final String xPathJMSQueues = "/configuration/jms/queue"; + + private static final String xPathJMSTopics = "/configuration/jms/topic"; + + // Core Queue XPaths + private static final String xPathQueues = "/configuration/core/queues"; + + private static final String xPathQueue = "/configuration/core/queues/queue"; + + private static final String xPathAddress = "address"; + + private static final String xPathFilter = "filter/@string"; + + private static final String xPathSelector = "selector/@string"; + + private static final String xPathDurable = "durable"; + + private static final String jmsQueuePrefix = "jms.queue."; + + private static final String jmsTopicPrefix = "jms.topic."; + + private final Map<String, Address> jmsQueueAddresses = new HashMap<>(); + + private final Map<String, Address> jmsTopicAddresses = new HashMap<>(); + + private final Map<String, Address> coreAddresses = new HashMap<>(); + + private final Map<String, Address> aliases = new HashMap<>(); private final Document document; - public static void main(String[] args) throws Exception { + private final File input; - if (args.length == 0) { - System.err.println("Invalid args"); - printUsage(); - } else { - File input = new File(args[0]); - if (input.isDirectory()) { - System.out.println("Scanning directory: " + input.getAbsolutePath()); - recursiveTransform(input); - } else { - if (args.length != 2) { - System.err.println("Invalid args"); - printUsage(); - } else { - transform(input, new File(args[1])); - } - } - } - } + private final File output; - private static void recursiveTransform(File root) throws Exception { - for (File file : root.listFiles()) { - scanAndTransform(file); - } - } + private final Node coreElement; + + private final XPath xPath; + + public XMLConfigurationMigration(File input, File output) throws Exception { + + this.input = input; + this.output = output; - public static void scanAndTransform(File pFile) throws Exception { try { - for (File f : pFile.listFiles()) { - if (f.isDirectory()) { - scanAndTransform(f); - } else { - try { - if (f.getName().endsWith("xml")) { - File file = new File(f.getAbsolutePath() + ".new"); - if (transform(f, file)) { - File r = new File(f.getAbsolutePath()); - - f.renameTo(new File(f.getAbsolutePath() + ".bk")); - file.renameTo(r); - } - } - } catch (Exception e) { - //continue - } - } + if (!input.exists()) { + throw new Exception("Input file not found: " + input); + } + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringElementContentWhitespace(true); + + DocumentBuilder db = factory.newDocumentBuilder(); + this.document = db.parse(this.input); + + xPath = XPathFactory.newInstance().newXPath(); + coreElement = (Node) xPath.evaluate("/configuration/core", document, XPathConstants.NODE); + + if (coreElement == null) { + throw new Exception("Not a artemis config"); } - } catch (NullPointerException e) { - System.out.println(pFile.getAbsoluteFile()); + } + catch (Exception e) { + throw new Exception(e); } } - public static void printUsage() { - System.out.println("Please specify a directory to scan, or input and output file"); - } + public boolean transform() throws Exception { + try { - public static boolean transform(File input, File output) throws Exception { + boolean queuesChanged = convertQueuesToAddresses(); + boolean jmsChanged = convertJMSToAddresses(); - migration = new XMLConfigurationMigration(input); - try { - if (!input.exists()) { - System.err.println("Input file not found: " + input); - } + writeAddressesToDocument(); + document.normalize(); - if (migration.convertQueuesToAddresses()) { + if (queuesChanged || jmsChanged) { Properties properties = new Properties(); properties.put(OutputKeys.INDENT, "yes"); properties.put("{http://xml.apache.org/xslt}indent-amount", "3"); properties.put(OutputKeys.ENCODING, "UTF-8"); - migration.write(output, properties); + write(output, properties); return true; } + } catch (Exception e) { System.err.println("Error tranforming document"); e.printStackTrace(); @@ -125,97 +142,147 @@ public class XMLConfigurationMigration { return false; } - public XMLConfigurationMigration(File input) throws Exception { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringElementContentWhitespace(true); + public boolean convertQueuesToAddresses() throws Exception { - DocumentBuilder db = factory.newDocumentBuilder(); - this.document = db.parse(input); - } + Node coreQueuesElement = getNode(xPathQueues); + if (coreQueuesElement == null) { + return false; + } - public boolean convertQueuesToAddresses() throws Exception { + NodeList coreQueueElements = getNodeList(xPathQueue); + for (int i = 0; i < coreQueueElements.getLength(); i++) { + Node queueNode = coreQueueElements.item(i); + + Queue queue = new Queue(); + queue.setName(getString(queueNode, xPathAttrName)); + queue.setDurable(getString(queueNode, xPathDurable)); + queue.setFilter(getString(queueNode, xPathFilter)); - Map<String, Address> addresses = new HashMap<>(); + String addressName = getString(queueNode, xPathAddress); - String xPathQueues = "/configuration/core/queues"; - String xPathQueue = "/configuration/core/queues/queue"; - String xPathAttrName = "@name"; - String xPathAddress = "address"; - String xPathFilter = "filter/@string"; - String xPathDurable = "durable"; + Address address; + if (coreAddresses.containsKey(addressName)) { + address = coreAddresses.get(addressName); + } else { + address = new Address(); + address.setName(addressName); + coreAddresses.put(addressName, address); + } + address.getQueues().add(queue); + } + + // Remove Core Queues Element from Core + Node queues = getNode(xPathQueues); + if (queues != null) { + coreElement.removeChild(queues); + } - XPath xPath = XPathFactory.newInstance().newXPath(); + return true; + } - NodeList xpathResult = (NodeList) xPath.evaluate(xPathQueue, document, XPathConstants.NODESET); - if (xpathResult == null || xpathResult.getLength() == 0) { - // doesn't require change + public boolean convertJMSToAddresses() throws Exception { + Node jmsElement = getNode(xPathJMS); + if (jmsElement == null) { return false; } - for (int i = 0; i < xpathResult.getLength(); i++) { - Node queueNode = xpathResult.item(i); + NodeList jmsQueueElements = getNodeList(xPathJMSQueues); + for (int i = 0; i < jmsQueueElements.getLength(); i++) { + Node jmsQueueElement = jmsQueueElements.item(i); + String name = jmsQueuePrefix + getString(jmsQueueElement, xPathAttrName); + + Address address; + if (jmsQueueAddresses.containsKey(name)) { + address = jmsQueueAddresses.get(name); + } + else { + address = new Address(); + address.setName(name); + address.setRoutingType("anycast"); + jmsQueueAddresses.put(name, address); + } Queue queue = new Queue(); - queue.setName(xPath.evaluate(xPathAttrName, queueNode, XPathConstants.STRING).toString()); - queue.setDurable(xPath.evaluate(xPathDurable, queueNode, XPathConstants.STRING).toString()); - queue.setFilter(xPath.evaluate(xPathFilter, queueNode, XPathConstants.STRING).toString()); + queue.setName(name); + queue.setDurable(getString(jmsQueueElement, xPathDurable)); + queue.setFilter(getString(jmsQueueElement, xPathSelector)); + address.getQueues().add(queue); + } - String addressName = xPath.evaluate(xPathAddress, queueNode, XPathConstants.STRING).toString(); - Address address; + NodeList jmsTopicElements = getNodeList(xPathJMSTopics); + for (int i = 0; i < jmsTopicElements.getLength(); i++) { + Node jmsTopicElement = jmsTopicElements.item(i); + String name = jmsTopicPrefix + getString(jmsTopicElement, xPathAttrName); - if (addresses.containsKey(addressName)) { - address = addresses.get(addressName); - } else { + Address address; + if (jmsTopicAddresses.containsKey(name)) { + address = jmsTopicAddresses.get(name); + } + else { address = new Address(); - address.setName(addressName); - addresses.put(addressName, address); + address.setName(name); + address.setRoutingType("multicast"); + jmsTopicAddresses.put(name, address); } + + Queue queue = new Queue(); + queue.setName(name); address.getQueues().add(queue); } - Node queues = ((Node) xPath.evaluate(xPathQueues, document, XPathConstants.NODE)); + jmsElement.getParentNode().removeChild(jmsElement); + return true; + } + + public void writeAddressesToDocument() { - if (queues != null) { - Node core = queues.getParentNode(); - core.removeChild(queues); - - Element a = document.createElement("addresses"); - for (Address addr : addresses.values()) { - Element eAddr = document.createElement("address"); - eAddr.setAttribute("name", addr.getName()); - eAddr.setAttribute("type", addr.getRoutingType()); - - if (addr.getQueues().size() > 0) { - Element eQueues = document.createElement("queues"); - for (Queue queue : addr.getQueues()) { - Element eQueue = document.createElement("queue"); - eQueue.setAttribute("name", queue.getName()); - eQueue.setAttribute("max-consumers", addr.getDefaultMaxConsumers()); - eQueue.setAttribute("delete-on-no-consumers", addr.getDefaultDeleteOnNoConsumers()); - - if (queue.getDurable() != null && !queue.getDurable().isEmpty()) { - Element eDurable = document.createElement("durable"); - eDurable.setTextContent(queue.getDurable()); - eQueue.appendChild(eDurable); - } - - if (queue.getFilter() != null && !queue.getFilter().isEmpty()) { - Element eFilter = document.createElement("filter"); - eFilter.setAttribute("string", queue.getFilter()); - eQueue.appendChild(eFilter); - } - - eQueues.appendChild(eQueue); + Element addressElement = document.createElement("addresses"); + + writeAddressListToDoc("= JMS Queues =", jmsQueueAddresses.values(), addressElement); + writeAddressListToDoc("= JMS Topics =", jmsTopicAddresses.values(), addressElement); + writeAddressListToDoc("= Core Queues =", coreAddresses.values(), addressElement); + + coreElement.appendChild(addressElement); + + } + + private void writeAddressListToDoc(String comment, Collection<Address> addresses, Node addressElement) { + if (addresses.isEmpty()) return; + + addressElement.appendChild(document.createComment("==================")); + addressElement.appendChild(document.createComment(comment)); + addressElement.appendChild(document.createComment("==================")); + for (Address addr : addresses) { + Element eAddr = document.createElement("address"); + eAddr.setAttribute("name", addr.getName()); + eAddr.setAttribute("type", addr.getRoutingType()); + + if (addr.getQueues().size() > 0) { + Element eQueues = document.createElement("queues"); + for (Queue queue : addr.getQueues()) { + Element eQueue = document.createElement("queue"); + eQueue.setAttribute("name", queue.getName()); + eQueue.setAttribute("max-consumers", addr.getDefaultMaxConsumers()); + eQueue.setAttribute("delete-on-no-consumers", addr.getDefaultDeleteOnNoConsumers()); + + if (queue.getDurable() != null && !queue.getDurable().isEmpty()) { + Element eDurable = document.createElement("durable"); + eDurable.setTextContent(queue.getDurable()); + eQueue.appendChild(eDurable); } - eAddr.appendChild(eQueues); + + if (queue.getFilter() != null && !queue.getFilter().isEmpty()) { + Element eFilter = document.createElement("filter"); + eFilter.setAttribute("string", queue.getFilter()); + eQueue.appendChild(eFilter); + } + + eQueues.appendChild(eQueue); } - a.appendChild(eAddr); + eAddr.appendChild(eQueues); } - core.appendChild(a); + addressElement.appendChild(eAddr); } - - document.normalize(); - return true; } public void write(File output, Properties outputProperties) throws TransformerException { @@ -224,4 +291,17 @@ public class XMLConfigurationMigration { StreamResult streamResult = new StreamResult(output); transformer.transform(new DOMSource(document), streamResult); } + + private String getString(Node node, String xPathQuery) throws XPathExpressionException { + return xPath.evaluate(xPathQuery, node, XPathConstants.STRING).toString(); + } + + private NodeList getNodeList(String xPathQuery) throws XPathExpressionException { + return (NodeList) xPath.evaluate(xPathQuery, document, XPathConstants.NODESET); + } + + private Node getNode(String xPathQuery) throws XPathExpressionException { + return (Node) xPath.evaluate(xPathQuery, document, XPathConstants.NODE); + } + } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d70bf3ba/artemis-tools/src/main/resources/META-INF/MANIFEST.MF ---------------------------------------------------------------------- diff --git a/artemis-tools/src/main/resources/META-INF/MANIFEST.MF b/artemis-tools/src/main/resources/META-INF/MANIFEST.MF index 72543bf..fc08aed 100644 --- a/artemis-tools/src/main/resources/META-INF/MANIFEST.MF +++ b/artemis-tools/src/main/resources/META-INF/MANIFEST.MF @@ -1,2 +1,2 @@ Manifest-Version: 1.0 -Main-Class: org.apache.activemq.artemis.tools.migrate.config.XMLConfigurationMigration +Main-Class: org.apache.activemq.artemis.tools.migrate.config.Main http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d70bf3ba/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java ---------------------------------------------------------------------- diff --git a/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java b/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java index f68e9c2..e653920 100644 --- a/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java +++ b/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java @@ -27,10 +27,11 @@ public class XMLConfigurationMigrationTest { @Test public void testQueuesReplacedWithAddresses() throws Exception { File brokerXml = new File(this.getClass().getClassLoader().getResource("broker.xml").toURI()); - XMLConfigurationMigration tool = new XMLConfigurationMigration(brokerXml); - File output = new File("target/out.xml"); - tool.convertQueuesToAddresses(); + + XMLConfigurationMigration tool = new XMLConfigurationMigration(brokerXml, output); + + tool.transform(); Properties properties = new Properties(); properties.put(OutputKeys.INDENT, "yes"); @@ -42,6 +43,6 @@ public class XMLConfigurationMigrationTest { @Test public void scanAndReplaceTest() throws Exception { File dir = new File(this.getClass().getClassLoader().getResource("replace").getPath()); - XMLConfigurationMigration.scanAndTransform(dir); + Main.scanAndTransform(dir); } } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/d70bf3ba/artemis-tools/src/test/resources/broker.xml ---------------------------------------------------------------------- diff --git a/artemis-tools/src/test/resources/broker.xml b/artemis-tools/src/test/resources/broker.xml index bd33d59..488be74 100644 --- a/artemis-tools/src/test/resources/broker.xml +++ b/artemis-tools/src/test/resources/broker.xml @@ -18,8 +18,17 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd"> <jms xmlns="urn:activemq:jms"> - <!--the queue used by the example--> - <queue name="exampleQueue"/> + <queue name="queue1"> + <durable>true</durable> + <selector string="car='red'" /> + </queue> + + <queue name="queue2"/> + <queue name="queue3"/> + + <topic name="topic1"/> + <topic name="topic2"/> + <topic name="topic3"/> </jms> <core xmlns="urn:activemq:core">
