You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by de...@apache.org on 2009/10/23 16:15:00 UTC
svn commit: r829073 -
/activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
Author: dejanb
Date: Fri Oct 23 14:15:00 2009
New Revision: 829073
URL: http://svn.apache.org/viewvc?rev=829073&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQ-2462 - new activemq-admin commands - create command
Added:
activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
Added: activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java?rev=829073&view=auto
==============================================================================
--- activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java (added)
+++ activemq/trunk/activemq-console/src/main/java/org/apache/activemq/console/command/CreateCommand.java Fri Oct 23 14:15:00 2009
@@ -0,0 +1,292 @@
+/*
+ * 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.console.command;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+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.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class CreateCommand extends AbstractCommand {
+
+ protected final String[] helpFile = new String[] {
+ "Task Usage: Main create path/to/brokerA [create-options]",
+ "Description: Creates a runnable broker instance in the specified path.",
+ "",
+ "List Options:",
+ " --amqconf <file path> Path to ActiveMQ conf file that will be used in the broker instance. Default is: conf/activemq.xml",
+ " --version Display the version information.",
+ " -h,-?,--help Display the create broker help information.",
+ ""
+ };
+
+ protected final String DEFAULT_TARGET_ACTIVEMQ_CONF = "conf/activemq.xml"; // default activemq conf to create in the new broker instance
+ protected final String DEFAULT_BROKERNAME_XPATH = "/beans/broker/@brokerName"; // default broker name xpath to change the broker name
+
+ protected final String[] BASE_SUB_DIRS = { "bin", "conf" }; // default sub directories that will be created
+ protected final String BROKER_NAME_REGEX = "[$][{]brokerName[}]"; // use to replace broker name property holders
+
+ protected String amqConf = "conf/activemq.xml"; // default conf if no conf is specified via --amqconf
+
+ // default files to copy from activemq home to the new broker instance
+ protected String[][] fileCopyMap = {
+ { "conf/log4j.properties", "conf/log4j.properties" },
+ { "conf/broker.ks", "conf/broker.ks" },
+ { "conf/broker.ts", "conf/broker.ts" },
+ { "conf/camel.xml", "conf/camel.xml" },
+ { "conf/jetty.xml", "conf/jetty.xml" },
+ { "conf/credentials.properties", "conf/credentials.properties" }
+ };
+
+ // default files to create
+ protected String[][] fileWriteMap = {
+ { "winActivemq", "bin/${brokerName}.bat" },
+ { "unixActivemq", "bin/${brokerName}" }
+ };
+
+
+ protected String brokerName;
+ protected File amqHome;
+ protected File targetAmqBase;
+
+ protected void runTask(List<String> tokens) throws Exception {
+ context.print("Running create broker task...");
+ amqHome = new File(System.getProperty("activemq.home"));
+ for (String token : tokens) {
+
+ targetAmqBase = new File(token);
+ brokerName = targetAmqBase.getName();
+
+
+ if (targetAmqBase.exists()) {
+ BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
+ String resp;
+ while (true) {
+ context.print("Target directory (" + targetAmqBase.getCanonicalPath() + ") already exists. Overwrite (y/n): ");
+ resp = console.readLine();
+ if (resp.equalsIgnoreCase("y") || resp.equalsIgnoreCase("yes")) {
+ break;
+ } else if (resp.equalsIgnoreCase("n") || resp.equalsIgnoreCase("no")) {
+ return;
+ }
+ }
+ }
+
+ context.print("Creating directory: " + targetAmqBase.getCanonicalPath());
+ targetAmqBase.mkdirs();
+ createSubDirs(targetAmqBase, BASE_SUB_DIRS);
+ writeFileMapping(targetAmqBase, fileWriteMap);
+ copyActivemqConf(amqHome, targetAmqBase, amqConf);
+ copyFileMapping(amqHome, targetAmqBase, fileCopyMap);
+ }
+ }
+
+ /**
+ * Handle the --amqconf options.
+ *
+ * @param token - option token to handle
+ * @param tokens - succeeding command arguments
+ * @throws Exception
+ */
+ protected void handleOption(String token, List<String> tokens) throws Exception {
+ if (token.startsWith("--amqconf")) {
+ // If no amqconf specified, or next token is a new option
+ if (tokens.isEmpty() || tokens.get(0).startsWith("-")) {
+ context.printException(new IllegalArgumentException("Attributes to amqconf not specified"));
+ return;
+ }
+
+ amqConf = tokens.remove(0);
+ } else {
+ // Let super class handle unknown option
+ super.handleOption(token, tokens);
+ }
+ }
+
+ protected void createSubDirs(File target, String[] subDirs) throws IOException {
+ File subDirFile;
+ for (String subDir : BASE_SUB_DIRS) {
+ subDirFile = new File(target, subDir);
+ context.print("Creating directory: " + subDirFile.getCanonicalPath());
+ subDirFile.mkdirs();
+ }
+ }
+
+ protected void writeFileMapping(File targetBase, String[][] fileWriteMapping) throws IOException {
+ for (String[] fileWrite : fileWriteMapping) {
+ File dest = new File(targetBase, resolveParam(BROKER_NAME_REGEX, brokerName, fileWrite[1]));
+ context.print("Creating new file: " + dest.getCanonicalPath());
+ writeFile(fileWrite[0], dest);
+ }
+ }
+
+ protected void copyFileMapping(File srcBase, File targetBase, String[][] fileMapping) throws IOException {
+ for (String[] fileMap : fileMapping) {
+ File src = new File(srcBase, fileMap[0]);
+ File dest = new File(targetBase, resolveParam(BROKER_NAME_REGEX, brokerName, fileMap[1]));
+ context.print("Copying from: " + src.getCanonicalPath() + "\n to: " + dest.getCanonicalPath());
+ copyFile(src, dest);
+ }
+ }
+
+ protected void copyActivemqConf(File srcBase, File targetBase, String activemqConf) throws IOException, ParserConfigurationException, SAXException, TransformerException, XPathExpressionException {
+ File src = new File(srcBase, activemqConf);
+
+ if (!src.exists()) {
+ throw new FileNotFoundException("File: " + src.getCanonicalPath() + " not found.");
+ }
+
+ File dest = new File(targetBase, DEFAULT_TARGET_ACTIVEMQ_CONF);
+ context.print("Copying from: " + src.getCanonicalPath() + "\n to: " + dest.getCanonicalPath());
+
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Element docElem = builder.parse(src).getDocumentElement();
+
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ Attr brokerNameAttr = (Attr) xpath.evaluate(DEFAULT_BROKERNAME_XPATH, docElem, XPathConstants.NODE);
+ brokerNameAttr.setValue(brokerName);
+
+ writeToFile(new DOMSource(docElem), dest);
+ }
+
+ protected void printHelp() {
+ context.printHelp(helpFile);
+ }
+
+ // write the default files to create (i.e. script files)
+ private void writeFile(String typeName, File dest) throws IOException {
+ String data;
+ if (typeName.equals("winActivemq")) {
+ data = winActivemqData;
+ data = resolveParam("[$][{]activemq.home[}]", amqHome.getCanonicalPath().replaceAll("[\\\\]", "/"), data);
+ data = resolveParam("[$][{]activemq.base[}]", targetAmqBase.getCanonicalPath().replaceAll("[\\\\]", "/"), data);
+ } else if (typeName.equals("unixActivemq")) {
+ data = unixActivemqData;
+ data = resolveParam("[$][{]activemq.home[}]", amqHome.getCanonicalPath().replaceAll("[\\\\]", "/"), data);
+ data = resolveParam("[$][{]activemq.base[}]", targetAmqBase.getCanonicalPath().replaceAll("[\\\\]", "/"), data);
+ } else {
+ throw new IllegalStateException("Unknown file type: " + typeName);
+ }
+
+ ByteBuffer buf = ByteBuffer.allocate(data.length());
+ buf.put(data.getBytes());
+ buf.flip();
+
+ FileChannel destinationChannel = new FileOutputStream(dest).getChannel();
+ destinationChannel.write(buf);
+ destinationChannel.close();
+
+ // Set file permissions available for Java 6.0 only
+// dest.setExecutable(true);
+// dest.setReadable(true);
+// dest.setWritable(true);
+ }
+
+ // utlity method to write an xml source to file
+ private void writeToFile(Source src, File file) throws TransformerException {
+ TransformerFactory tFactory = TransformerFactory.newInstance();
+ Transformer fileTransformer = tFactory.newTransformer();
+
+ Result res = new StreamResult(file);
+ fileTransformer.transform(src, res);
+ }
+
+ // utility method to copy one file to another
+ private void copyFile(File from, File dest) throws IOException {
+ if (!from.exists()) {
+ return;
+ }
+ FileChannel sourceChannel = new FileInputStream(from).getChannel();
+ FileChannel destinationChannel = new FileOutputStream(dest).getChannel();
+ sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
+ sourceChannel.close();
+ destinationChannel.close();
+ }
+
+ // replace a property place holder (paramName) with the paramValue
+ private String resolveParam(String paramName, String paramValue, String target) {
+ return target.replaceAll(paramName, paramValue);
+ }
+
+ // Embedded windows script data
+ private static final String winActivemqData =
+ "@echo off\n"
+ + "set ACTIVEMQ_HOME=\"${activemq.home}\"\n"
+ + "set ACTIVEMQ_BASE=\"${activemq.base}\"\n"
+ + "\n"
+ + "set PARAM=%1\n"
+ + ":getParam\n"
+ + "shift\n"
+ + "if \"%1\"==\"\" goto end\n"
+ + "set PARAM=%PARAM% %1\n"
+ + "goto getParam\n"
+ + ":end\n"
+ + "\n"
+ + "%ACTIVEMQ_HOME%/bin/activemq %PARAM%";
+
+
+ // Embedded unix script data
+ private static final String unixActivemqData = "## Figure out the ACTIVEMQ_BASE from the directory this script was run from\n"
+ + "PRG=\"$0\"\n"
+ + "progname=`basename \"$0\"`\n"
+ + "saveddir=`pwd`\n"
+ + "# need this for relative symlinks\n"
+ + "dirname_prg=`dirname \"$PRG\"`\n"
+ + "cd \"$dirname_prg\"\n"
+ + "while [ -h \"$PRG\" ] ; do\n"
+ + " ls=`ls -ld \"$PRG\"`\n"
+ + " link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n"
+ + " if expr \"$link\" : '.*/.*' > /dev/null; then\n"
+ + " PRG=\"$link\"\n"
+ + " else\n"
+ + " PRG=`dirname \"$PRG\"`\"/$link\"\n"
+ + " fi\n"
+ + "done\n"
+ + "ACTIVEMQ_BASE=`dirname \"$PRG\"`/..\n"
+ + "cd \"$saveddir\"\n"
+ + "\n"
+ + "ACTIVEMQ_BASE=`cd \"$ACTIVEMQ_BASE\" && pwd`\n\n"
+ + "export ACTIVEMQ_HOME=${activemq.home}\n"
+ + "export ACTIVEMQ_BASE=$ACTIVEMQ_BASE\n\n"
+ + "${ACTIVEMQ_HOME}/bin/activemq \"$*\"";
+
+}