mirror of https://github.com/apache/activemq.git
https://issues.apache.org/activemq/browse/AMQ-2462 - new activemq-admin commands - create command
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@829073 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e0ee61348e
commit
e384fb99ba
|
@ -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 \"$*\"";
|
||||
|
||||
}
|
Loading…
Reference in New Issue