ARTEMIS-790 Added Configuration conversion tooL
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/076d78a4 Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/076d78a4 Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/076d78a4 Branch: refs/heads/ARTEMIS-780 Commit: 076d78a497661683a3a18e00cd7d80dd7468a11f Parents: 20278d0 Author: Martyn Taylor <[email protected]> Authored: Fri Oct 21 10:51:21 2016 +0100 Committer: Clebert Suconic <[email protected]> Committed: Mon Nov 7 11:28:07 2016 -0500 ---------------------------------------------------------------------- artemis-tools/pom.xml | 56 + .../config/XMLConfigurationMigration.java | 237 ++ .../migrate/config/addressing/Address.java | 73 + .../tools/migrate/config/addressing/Queue.java | 50 + .../src/main/resources/META-INF/MANIFEST.MF | 2 + .../config/XMLConfigurationMigrationTest.java | 47 + .../test/resources/artemis-configuration.xsd | 2591 ++++++++++++++++++ .../src/test/resources/artemis-server.xsd | 46 + artemis-tools/src/test/resources/broker.xml | 64 + .../src/test/resources/replace/broker.xml | 64 + .../src/test/resources/replace/broker2.xml | 64 + pom.xml | 1 + 12 files changed, 3295 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/artemis-tools/pom.xml ---------------------------------------------------------------------- diff --git a/artemis-tools/pom.xml b/artemis-tools/pom.xml new file mode 100644 index 0000000..9ce22fd --- /dev/null +++ b/artemis-tools/pom.xml @@ -0,0 +1,56 @@ +<!-- + 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-pom</artifactId> + <version>1.5.0-SNAPSHOT</version> + </parent> + + <name>ActiveMQ Artemis Tools</name> + <groupId>org.apache.activemq.tools</groupId> + <artifactId>artemis-tools</artifactId> + <packaging>jar</packaging> + + <properties> + <activemq.basedir>${project.basedir}/..</activemq.basedir> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile> + </archive> + </configuration> + </plugin> + </plugins> + </build> + +</project> http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/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 new file mode 100644 index 0000000..56833ea --- /dev/null +++ b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigration.java @@ -0,0 +1,237 @@ +/* + * 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 javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +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.XPathFactory; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.activemq.artemis.tools.migrate.config.addressing.Address; +import org.apache.activemq.artemis.tools.migrate.config.addressing.Queue; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class XMLConfigurationMigration { + + private static XMLConfigurationMigration migration; + + private final Document document; + + 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 { + transform(input, new File(args[1])); + } + } + } + } + + 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"); + if (transform(f, file)) { + File r = new File(f.getAbsolutePath()); + + f.renameTo(new File(f.getAbsolutePath() + ".bk")); + file.renameTo(r); + } + } + } + catch (Exception e) { + //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"); + } + + public static boolean transform(File input, File output) throws Exception { + + migration = new XMLConfigurationMigration(input); + try { + if (!input.exists()) { + System.err.println("Input file not found: " + input); + } + + if (migration.convertQueuesToAddresses()) { + 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); + return true; + } + } + catch (Exception e) + { + System.err.println("Error tranforming document"); + e.printStackTrace(); + } + return false; + } + + public XMLConfigurationMigration(File input) throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringElementContentWhitespace(true); + + DocumentBuilder db = factory.newDocumentBuilder(); + this.document = db.parse(input); + } + + public boolean convertQueuesToAddresses() throws Exception { + + Map<String, Address> addresses = new HashMap<>(); + + String xPathQueues = "/configuration/core/queues"; + String xPathQueue = "/configuration/core/queues/queue"; + String xPathAttrName = "@name"; + String xPathAddress = "address"; + String xPathFilter = "filter/@string"; + String xPathDurable = "durable"; + + XPath xPath = XPathFactory.newInstance().newXPath(); + + NodeList xpathResult = (NodeList) xPath.evaluate(xPathQueue, document, XPathConstants.NODESET); + if (xpathResult == null || xpathResult.getLength() == 0) { + // doesn't require change + return false; + } + + for (int i = 0; i < xpathResult.getLength(); i++) { + Node queueNode = xpathResult.item(i); + + 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()); + + String addressName = xPath.evaluate(xPathAddress, queueNode, XPathConstants.STRING).toString(); + Address address; + + if (addresses.containsKey(addressName)) { + address = addresses.get(addressName); + } + else { + address = new Address(); + address.setName(addressName); + addresses.put(addressName, address); + } + address.getQueues().add(queue); + } + + Node queues = ((Node) xPath.evaluate(xPathQueues, document, XPathConstants.NODE)); + + 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); + } + eAddr.appendChild(eQueues); + } + a.appendChild(eAddr); + } + core.appendChild(a); + } + + document.normalize(); + return true; + } + + public void write(File output, Properties outputProperties) throws TransformerException { + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperties(outputProperties); + StreamResult streamResult = new StreamResult(output); + transformer.transform(new DOMSource(document), streamResult); + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Address.java ---------------------------------------------------------------------- diff --git a/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Address.java b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Address.java new file mode 100644 index 0000000..c483c75 --- /dev/null +++ b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Address.java @@ -0,0 +1,73 @@ +/* + * 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.addressing; + +import java.util.ArrayList; +import java.util.List; + +public class Address { + + private String name; + + private String routingType = "multicast"; + + private String defaultMaxConsumers = "-1"; + + private String defaultDeleteOnNoConsumers = "false"; + + private List<Queue> queues = new ArrayList<>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRoutingType() { + return routingType; + } + + public void setRoutingType(String routingType) { + this.routingType = routingType; + } + + public String getDefaultMaxConsumers() { + return defaultMaxConsumers; + } + + public void setDefaultMaxConsumers(String defaultMaxConsumers) { + this.defaultMaxConsumers = defaultMaxConsumers; + } + + public String getDefaultDeleteOnNoConsumers() { + return defaultDeleteOnNoConsumers; + } + + public void setDefaultDeleteOnNoConsumers(String defaultDeleteOnNoConsumers) { + this.defaultDeleteOnNoConsumers = defaultDeleteOnNoConsumers; + } + + public List<Queue> getQueues() { + return queues; + } + + public void setQueues(List<Queue> queues) { + this.queues = queues; + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Queue.java ---------------------------------------------------------------------- diff --git a/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Queue.java b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Queue.java new file mode 100644 index 0000000..f88b8ef --- /dev/null +++ b/artemis-tools/src/main/java/org/apache/activemq/artemis/tools/migrate/config/addressing/Queue.java @@ -0,0 +1,50 @@ +/* + * 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.addressing; + +public class Queue { + + String name; + + String filter; + + String durable; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getFilter() { + return filter; + } + + public void setFilter(String filter) { + this.filter = filter; + } + + public String getDurable() { + return durable; + } + + public void setDurable(String durable) { + this.durable = durable; + } +} http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/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 new file mode 100644 index 0000000..72543bf --- /dev/null +++ b/artemis-tools/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Main-Class: org.apache.activemq.artemis.tools.migrate.config.XMLConfigurationMigration http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/076d78a4/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 new file mode 100644 index 0000000..f68e9c2 --- /dev/null +++ b/artemis-tools/src/test/java/org/apache/activemq/artemis/tools/migrate/config/XMLConfigurationMigrationTest.java @@ -0,0 +1,47 @@ +/* + * 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 javax.xml.transform.OutputKeys; +import java.io.File; +import java.util.Properties; + +import org.junit.Test; + +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(); + + 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"); + tool.write(output, properties); + } + + @Test + public void scanAndReplaceTest() throws Exception { + File dir = new File(this.getClass().getClassLoader().getResource("replace").getPath()); + XMLConfigurationMigration.scanAndTransform(dir); + } +}
