merge PR #252 - Improvements on CLI and Bootstrap

This commit is contained in:
Andy Taylor 2015-05-13 11:50:07 +01:00
commit d1b317b975
13 changed files with 248 additions and 28 deletions

View File

@ -38,11 +38,6 @@ public class Artemis
public static void main(String[] args) throws Throwable public static void main(String[] args) throws Throwable
{ {
ArrayList<File> dirs = new ArrayList<File>(); ArrayList<File> dirs = new ArrayList<File>();
String instance = System.getProperty("artemis.instance");
if (instance != null)
{
dirs.add(new File(new File(instance), "lib"));
}
String home = System.getProperty("artemis.home"); String home = System.getProperty("artemis.home");
if (home != null) if (home != null)
@ -50,6 +45,14 @@ public class Artemis
dirs.add(new File(new File(home), "lib")); dirs.add(new File(new File(home), "lib"));
} }
String instance = System.getProperty("artemis.instance");
File instanceFile = null;
if (instance != null)
{
instanceFile = new File(instance);
dirs.add(new File(instanceFile, "lib"));
}
ArrayList<URL> urls = new ArrayList<URL>(); ArrayList<URL> urls = new ArrayList<URL>();
for (File bootdir : dirs) for (File bootdir : dirs)
{ {
@ -95,6 +98,14 @@ public class Artemis
System.setProperty("logging.configuration", fixupFileURI(loggingConfig)); System.setProperty("logging.configuration", fixupFileURI(loggingConfig));
} }
// Without the etc on the config, things like JGroups configuration wouldn't be loaded
if (instanceFile != null)
{
File etcFile = new File(instance, "etc");
// Adding etc to the classLoader so modules can lookup for their configs
urls.add(etcFile.toURI().toURL());
}
// Now setup our classloader.. // Now setup our classloader..
URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()])); URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
Thread.currentThread().setContextClassLoader(loader); Thread.currentThread().setContextClassLoader(loader);

View File

@ -25,7 +25,7 @@
<artifactId>artemis-cli</artifactId> <artifactId>artemis-cli</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ActiveMQ Artemis Bootstrap</name> <name>ActiveMQ Artemis CLI</name>
<properties> <properties>
<activemq.basedir>${project.basedir}/..</activemq.basedir> <activemq.basedir>${project.basedir}/..</activemq.basedir>

View File

@ -25,6 +25,7 @@ import org.apache.activemq.artemis.cli.commands.Action;
import org.apache.activemq.artemis.cli.commands.ActionContext; import org.apache.activemq.artemis.cli.commands.ActionContext;
import org.apache.activemq.artemis.cli.commands.Create; import org.apache.activemq.artemis.cli.commands.Create;
import org.apache.activemq.artemis.cli.commands.HelpAction; import org.apache.activemq.artemis.cli.commands.HelpAction;
import org.apache.activemq.artemis.cli.commands.Kill;
import org.apache.activemq.artemis.cli.commands.Run; import org.apache.activemq.artemis.cli.commands.Run;
import org.apache.activemq.artemis.cli.commands.Stop; import org.apache.activemq.artemis.cli.commands.Stop;
import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal; import org.apache.activemq.artemis.cli.commands.tools.DecodeJournal;
@ -53,7 +54,7 @@ public class Artemis
if (instance != null) if (instance != null)
{ {
builder = builder builder = builder
.withCommands(Run.class, Stop.class); .withCommands(Run.class, Stop.class, Kill.class);
} }
else else
{ {
@ -61,7 +62,6 @@ public class Artemis
.withCommand(Create.class); .withCommand(Create.class);
} }
Cli<Action> parser = builder.build(); Cli<Action> parser = builder.build();
try try
{ {

View File

@ -61,6 +61,8 @@ public class Create implements Action
private static final Integer HQ_PORT = 5445; private static final Integer HQ_PORT = 5445;
private static final Integer HTTP_PORT = 8161;
public static final String BIN_ARTEMIS_CMD = "bin/artemis.cmd"; public static final String BIN_ARTEMIS_CMD = "bin/artemis.cmd";
public static final String BIN_ARTEMIS_SERVICE_EXE = "bin/artemis-service.exe"; public static final String BIN_ARTEMIS_SERVICE_EXE = "bin/artemis-service.exe";
public static final String BIN_ARTEMIS_SERVICE_XML = "bin/artemis-service.xml"; public static final String BIN_ARTEMIS_SERVICE_XML = "bin/artemis-service.xml";
@ -107,6 +109,9 @@ public class Create implements Action
@Option(name = "--encoding", description = "The encoding that text files should use") @Option(name = "--encoding", description = "The encoding that text files should use")
String encoding = "UTF-8"; String encoding = "UTF-8";
@Option(name = "--java-options", description = "Extra java options to be passed to the profile")
String javaOptions = "";
ActionContext context; ActionContext context;
private Scanner scanner; private Scanner scanner;
@ -115,6 +120,110 @@ public class Create implements Action
boolean IS_CYGWIN; boolean IS_CYGWIN;
public int getPortOffset()
{
return portOffset;
}
public void setPortOffset(int portOffset)
{
this.portOffset = portOffset;
}
public String getJavaOptions()
{
return javaOptions;
}
public void setJavaOptions(String javaOptions)
{
this.javaOptions = javaOptions;
}
public File getInstance()
{
return directory;
}
public void setInstance(File directory)
{
this.directory = directory;
}
public String getHost()
{
return host;
}
public void setHost(String host)
{
this.host = host;
}
public boolean isForce()
{
return force;
}
public void setForce(boolean force)
{
this.force = force;
}
public File getHome()
{
if (home == null)
{
home = new File(System.getProperty("artemis.home"));
}
return home;
}
public void setHome(File home)
{
this.home = home;
}
public boolean isClustered()
{
return clustered;
}
public void setClustered(boolean clustered)
{
this.clustered = clustered;
}
public boolean isReplicated()
{
return replicated;
}
public void setReplicated(boolean replicated)
{
this.replicated = replicated;
}
public boolean isSharedStore()
{
return sharedStore;
}
public void setSharedStore(boolean sharedStore)
{
this.sharedStore = sharedStore;
}
public String getEncoding()
{
return encoding;
}
public void setEncoding(String encoding)
{
this.encoding = encoding;
}
@Override @Override
public Object execute(ActionContext context) throws Exception public Object execute(ActionContext context) throws Exception
{ {
@ -125,7 +234,7 @@ public class Create implements Action
catch (Throwable e) catch (Throwable e)
{ {
e.printStackTrace(context.err); e.printStackTrace(context.err);
return e; throw e;
} }
} }
@ -209,12 +318,15 @@ public class Create implements Action
filters.put("${amqp.port}", String.valueOf(AMQP_PORT + portOffset)); filters.put("${amqp.port}", String.valueOf(AMQP_PORT + portOffset));
filters.put("${stomp.port}", String.valueOf(STOMP_PORT + portOffset)); filters.put("${stomp.port}", String.valueOf(STOMP_PORT + portOffset));
filters.put("${hq.port}", String.valueOf(HQ_PORT + portOffset)); filters.put("${hq.port}", String.valueOf(HQ_PORT + portOffset));
filters.put("${http.port}", String.valueOf(HTTP_PORT + portOffset));
if (home != null) if (home != null)
{ {
filters.put("${home}", path(home, false)); filters.put("${home}", path(home, false));
} }
filters.put("${artemis.home}", path(System.getProperty("artemis.home"), false)); filters.put("${artemis.home}", path(getHome().toString(), false));
filters.put("${artemis.instance}", path(directory, false)); filters.put("${artemis.instance}", path(directory, false));
filters.put("${artemis.instance.name}", directory.getName());
filters.put("${java.home}", path(System.getProperty("java.home"), false)); filters.put("${java.home}", path(System.getProperty("java.home"), false));
new File(directory, "bin").mkdirs(); new File(directory, "bin").mkdirs();
@ -223,6 +335,12 @@ public class Create implements Action
new File(directory, "tmp").mkdirs(); new File(directory, "tmp").mkdirs();
new File(directory, "data").mkdirs(); new File(directory, "data").mkdirs();
if (javaOptions == null || javaOptions.length() == 0)
{
javaOptions = "";
}
filters.put("${java-opts}", javaOptions);
if (IS_WINDOWS) if (IS_WINDOWS)
{ {
@ -243,7 +361,7 @@ public class Create implements Action
} }
write(ETC_LOGGING_PROPERTIES, null, false); write(ETC_LOGGING_PROPERTIES, null, false);
write(ETC_BOOTSTRAP_XML, null, false); write(ETC_BOOTSTRAP_XML, filters, false);
write(ETC_BROKER_XML, filters, false); write(ETC_BROKER_XML, filters, false);
write(ETC_ARTEMIS_ROLES_PROPERTIES, null, false); write(ETC_ARTEMIS_ROLES_PROPERTIES, null, false);
write(ETC_ARTEMIS_USERS_PROPERTIES, null, false); write(ETC_ARTEMIS_USERS_PROPERTIES, null, false);
@ -277,17 +395,21 @@ public class Create implements Action
context.out.println(String.format(" \"%s\" start", path(service, true))); context.out.println(String.format(" \"%s\" start", path(service, true)));
context.out.println(""); context.out.println("");
} }
} }
if (IS_WINDOWS) if (IS_WINDOWS)
{ {
service = new File(directory, BIN_ARTEMIS_SERVICE_EXE);
context.out.println("Or you can setup the broker as Windows service and run it in the background:"); context.out.println("Or you can setup the broker as Windows service and run it in the background:");
context.out.println(""); context.out.println("");
context.out.println(String.format(" \"%s\" install", path(service, true))); context.out.println(String.format(" \"%s\" install", path(service, true)));
context.out.println(String.format(" \"%s\" start", path(service, true))); context.out.println(String.format(" \"%s\" start", path(service, true)));
context.out.println(""); context.out.println("");
context.out.println(" To stop the windows service:");
context.out.println(String.format(" \"%s\" stop", path(service, true)));
context.out.println("");
context.out.println(" To uninstall the windows service");
context.out.println(String.format(" \"%s\" uninstall", path(service, true)));
} }
return null; return null;

View File

@ -0,0 +1,41 @@
/**
* 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.cli.commands;
import java.io.File;
import io.airlift.airline.Command;
import org.apache.activemq.artemis.dto.BrokerDTO;
@Command(name = "kill", description = "Kills a broker instance started with --allow-kill")
public class Kill extends Configurable implements Action
{
@Override
public Object execute(ActionContext context) throws Exception
{
BrokerDTO broker = getBrokerDTO();
File file = broker.server.getConfigurationFile().getParentFile();
File killFile = new File(file, "KILL_ME");
killFile.createNewFile();
return null;
}
}

View File

@ -22,6 +22,7 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import io.airlift.airline.Command; import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.Artemis; import org.apache.activemq.artemis.cli.Artemis;
import org.apache.activemq.artemis.components.ExternalComponent; import org.apache.activemq.artemis.components.ExternalComponent;
import org.apache.activemq.artemis.core.server.ActiveMQComponent; import org.apache.activemq.artemis.core.server.ActiveMQComponent;
@ -36,6 +37,8 @@ import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
@Command(name = "run", description = "runs the broker instance") @Command(name = "run", description = "runs the broker instance")
public class Run extends Configurable implements Action public class Run extends Configurable implements Action
{ {
@Option(name = "--allow-kill", description = "This will allow the server to kill itself. Useful for tests (failover tests for instance)")
boolean allowKill;
private Broker server; private Broker server;
@ -88,12 +91,33 @@ public class Run extends Configurable implements Action
ActiveMQBootstrapLogger.LOGGER.errorDeletingFile(file.getAbsolutePath()); ActiveMQBootstrapLogger.LOGGER.errorDeletingFile(file.getAbsolutePath());
} }
} }
final File fileKill = new File(configurationDir,"KILL_ME");
if (fileKill.exists())
{
if (!fileKill.delete())
{
ActiveMQBootstrapLogger.LOGGER.errorDeletingFile(fileKill.getAbsolutePath());
}
}
final Timer timer = new Timer("ActiveMQ Artemis Server Shutdown Timer", true); final Timer timer = new Timer("ActiveMQ Artemis Server Shutdown Timer", true);
timer.scheduleAtFixedRate(new TimerTask() timer.scheduleAtFixedRate(new TimerTask()
{ {
@Override @Override
public void run() public void run()
{ {
if (allowKill && fileKill.exists())
{
try
{
System.err.println("Halting by user request");
fileKill.delete();
}
catch (Throwable ignored)
{
}
Runtime.getRuntime().halt(0);
}
if (file.exists()) if (file.exists())
{ {
try try
@ -116,5 +140,22 @@ public class Run extends Configurable implements Action
} }
} }
}, 500, 500); }, 500, 500);
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
try
{
server.stop();
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
} }
} }

View File

@ -57,6 +57,10 @@ public interface ActiveMQBootstrapLogger extends BasicLogger
@Message(id = 101002, value = "Starting Naming server on {0}:{1,number,#} (rmi {2}:{3,number,#})", format = Message.Format.MESSAGE_FORMAT) @Message(id = 101002, value = "Starting Naming server on {0}:{1,number,#} (rmi {2}:{3,number,#})", format = Message.Format.MESSAGE_FORMAT)
void startedNamingService(String bindAddress, int port, String rmiBindAddress, int rmiPort); void startedNamingService(String bindAddress, int port, String rmiBindAddress, int rmiPort);
@LogMessage(level = Logger.Level.INFO)
@Message(id = 101003, value = "Halting ActiveMQ Artemis Server after user request", format = Message.Format.MESSAGE_FORMAT)
void serverKilled();
@LogMessage(level = Logger.Level.WARN) @LogMessage(level = Logger.Level.WARN)
@Message(id = 102000, value = "Error during undeployment: {0}", format = Message.Format.MESSAGE_FORMAT) @Message(id = 102000, value = "Error during undeployment: {0}", format = Message.Format.MESSAGE_FORMAT)
void errorDuringUndeployment(@Cause Throwable t, String name); void errorDuringUndeployment(@Cause Throwable t, String name);

View File

@ -48,7 +48,6 @@ fi
ARTEMIS_LOGGING_CONF="file:$ARTEMIS_INSTANCE/etc/logging.properties" ARTEMIS_LOGGING_CONF="file:$ARTEMIS_INSTANCE/etc/logging.properties"
ARTEMIS_DATA_DIR="$ARTEMIS_INSTANCE/data" ARTEMIS_DATA_DIR="$ARTEMIS_INSTANCE/data"
ARTEMIS_LOG_MANAGER=org.jboss.logmanager.LogManager ARTEMIS_LOG_MANAGER=org.jboss.logmanager.LogManager
JAVA_ARGS="-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M"
# Load Profile Data # Load Profile Data
. "$ARTEMIS_INSTANCE/etc/artemis.profile" . "$ARTEMIS_INSTANCE/etc/artemis.profile"
@ -116,4 +115,4 @@ exec "$JAVACMD" $JAVA_ARGS $ARTEMIS_CLUSTER_PROPS \
-Djava.util.logging.manager="$ARTEMIS_LOG_MANAGER" \ -Djava.util.logging.manager="$ARTEMIS_LOG_MANAGER" \
-Dlogging.configuration="$ARTEMIS_LOGGING_CONF" \ -Dlogging.configuration="$ARTEMIS_LOGGING_CONF" \
$DEBUG_ARGS \ $DEBUG_ARGS \
org.apache.activemq.artemis.boot.Artemis $@ org.apache.activemq.artemis.boot.Artemis "$@"

View File

@ -18,14 +18,14 @@
--> -->
<service> <service>
<id>armetis-${host}</id> <id>armetis-${artemis.instance.name}-${host}</id>
<name>ActiveMQ Artemis: ${host}</name> <name>ActiveMQ Artemis: ${artemis.instance.name} @ ${host}</name>
<description>Apache ActiveMQ Artemis is a reliable messaging broker</description> <description>Apache ActiveMQ Artemis is a reliable messaging broker</description>
<logpath>${artemis.instance}\log</logpath> <logpath>${artemis.instance}\log</logpath>
<logmode>roll</logmode> <logmode>roll</logmode>
<executable>"${java.home}\bin\java.exe"</executable> <executable>java</executable>
<argument>-XX:+UseParallelGC</argument> <argument>-XX:+UseParallelGC</argument>
<argument>-XX:+AggressiveOpts</argument> <argument>-XX:+AggressiveOpts</argument>
<argument>-XX:+UseFastAccessorMethods</argument> <argument>-XX:+UseFastAccessorMethods</argument>
@ -41,18 +41,18 @@
<argument>-classpath</argument> <argument>-classpath</argument>
<argument>"${artemis.home}\lib\artemis-boot.jar"</argument> <argument>"${artemis.home}\lib\artemis-boot.jar"</argument>
<argument>"-artemis.home=${artemis.home}"</argument> <argument>-Dartemis.home="${artemis.home}"</argument>
<argument>"-artemis.instance=${artemis.instance}"</argument> <argument>-Dartemis.instance="${artemis.instance}"</argument>
<argument>"-Ddata.dir=${artemis.instance}/data"</argument> <argument>-Ddata.dir="${artemis.instance}/data"</argument>
<argument>-Djava.util.logging.manager=org.jboss.logmanager.LogManager</argument> <argument>-Djava.util.logging.manager=org.jboss.logmanager.LogManager</argument>
<argument>"-Dlogging.configuration=file:${artemis.instance}\etc\logging.properties"</argument> <argument>-Dlogging.configuration="file:${artemis.instance}\etc\logging.properties"</argument>
<!-- Debug args: Uncomment to enable debug <!-- Debug args: Uncomment to enable debug
<argument>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</argument> <argument>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</argument>
--> -->
<argument>Armetis</argument> <argument>org.apache.activemq.artemis.boot.Artemis</argument>
<argument>run</argument> <argument>run</argument>

View File

@ -48,7 +48,6 @@ echo.
:RUN_JAVA :RUN_JAVA
rem "Set Defaults." rem "Set Defaults."
set JAVA_ARGS=-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M
set ARTEMIS_LOGGING_CONF=file:%ARTEMIS_INSTANCE%\etc\logging.properties set ARTEMIS_LOGGING_CONF=file:%ARTEMIS_INSTANCE%\etc\logging.properties
set ARTEMIS_DATA_DIR=%ARTEMIS_INSTANCE%\data set ARTEMIS_DATA_DIR=%ARTEMIS_INSTANCE%\data
set ARTEMIS_LOG_MANAGER=org.jboss.logmanager.LogManager set ARTEMIS_LOG_MANAGER=org.jboss.logmanager.LogManager

View File

@ -20,8 +20,11 @@ ARTEMIS_HOME='${artemis.home}'
# Cluster Properties: Used to pass arguments to ActiveMQ which can be referenced in broker.xml # Cluster Properties: Used to pass arguments to ActiveMQ which can be referenced in broker.xml
#ARTEMIS_CLUSTER_PROPS="-Dactivemq.remoting.default.port=61617 -Dactivemq.remoting.amqp.port=5673 -Dactivemq.remoting.stomp.port=61614 -Dactivemq.remoting.hornetq.port=5446" #ARTEMIS_CLUSTER_PROPS="-Dactivemq.remoting.default.port=61617 -Dactivemq.remoting.amqp.port=5673 -Dactivemq.remoting.stomp.port=61614 -Dactivemq.remoting.hornetq.port=5446"
# Java Opts # Java Opts
#JAVA_ARGS="-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M" JAVA_ARGS="-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M ${java-opts}"
# Debug args: Uncomment to enable debug # Debug args: Uncomment to enable debug
#DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" #DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"

View File

@ -21,7 +21,7 @@ rem Cluster Properties: Used to pass arguments to ActiveMQ which can be referenc
rem set ARTEMIS_CLUSTER_PROPS=-Dactivemq.remoting.default.port=61617 -Dactivemq.remoting.amqp.port=5673 -Dactivemq.remoting.stomp.port=61614 -Dactivemq.remoting.hornetq.port=5446 rem set ARTEMIS_CLUSTER_PROPS=-Dactivemq.remoting.default.port=61617 -Dactivemq.remoting.amqp.port=5673 -Dactivemq.remoting.stomp.port=61614 -Dactivemq.remoting.hornetq.port=5446
rem Java Opts rem Java Opts
rem set JAVA_ARGS=-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M set JAVA_ARGS=-XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M ${java-opts}
rem Debug args: Uncomment to enable debug rem Debug args: Uncomment to enable debug
rem set DEBUG_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 rem set DEBUG_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

View File

@ -26,7 +26,7 @@
<server configuration="file:${artemis.instance}/etc/broker.xml"/> <server configuration="file:${artemis.instance}/etc/broker.xml"/>
<web bind="http://localhost:8161" path="web"> <web bind="http://localhost:${http.port}" path="web">
<app url="jolokia" war="jolokia-war-1.2.3.war"/> <app url="jolokia" war="jolokia-war-1.2.3.war"/>
</web> </web>