ARTEMIS-4081 Upgrade command

This command will help updating the instance from a previous home
This commit is contained in:
Clebert Suconic 2022-10-07 11:44:40 -04:00 committed by clebertsuconic
parent db1338af52
commit 9c88fb4f88
36 changed files with 2421 additions and 175 deletions

View File

@ -32,6 +32,7 @@ import org.apache.activemq.artemis.cli.commands.InvalidOptionsError;
import org.apache.activemq.artemis.cli.commands.Kill;
import org.apache.activemq.artemis.cli.commands.Mask;
import org.apache.activemq.artemis.cli.commands.PrintVersion;
import org.apache.activemq.artemis.cli.commands.Upgrade;
import org.apache.activemq.artemis.cli.commands.activation.ActivationSequenceSet;
import org.apache.activemq.artemis.cli.commands.check.HelpCheck;
import org.apache.activemq.artemis.cli.commands.check.NodeCheck;
@ -243,7 +244,7 @@ public class Artemis {
} else {
builder.withGroup("data").withDescription("data tools group (print|recover) (example ./artemis data print)").
withDefaultCommand(HelpData.class).withCommands(RecoverMessages.class, PrintData.class);
builder = builder.withCommand(Create.class);
builder = builder.withCommands(Create.class, Upgrade.class);
}
return builder;

View File

@ -17,29 +17,18 @@
package org.apache.activemq.artemis.cli.commands;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.airlift.airline.Arguments;
import io.airlift.airline.Command;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
import org.apache.activemq.artemis.api.core.RoutingType;
import org.apache.activemq.artemis.cli.CLIException;
import org.apache.activemq.artemis.cli.commands.util.HashUtil;
import org.apache.activemq.artemis.cli.commands.util.SyncCalculation;
import org.apache.activemq.artemis.core.server.JournalType;
@ -52,7 +41,7 @@ import org.apache.activemq.artemis.utils.FileUtil;
* CLI action that creates a broker instance directory.
*/
@Command(name = "create", description = "creates a new broker instance")
public class Create extends InputAbstract {
public class Create extends InstallAbstract {
private static final Integer DEFAULT_PORT = 61616;
@ -73,13 +62,17 @@ public class Create extends InputAbstract {
* This is to make sure maven or something else is not hiding these resources.
* ********************************************************************************** */
public static final String BIN_ARTEMIS_CMD = "bin/artemis.cmd";
public static final String ARTEMIS_CMD = "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_CONFIG = "bin/artemis-service.exe.config";
public static final String BIN_ARTEMIS_SERVICE_XML = "bin/artemis-service.xml";
public static final String ARTEMIS_SERVICE_XML = "artemis-service.xml";
public static final String BIN_ARTEMIS_SERVICE_XML = "bin/" + ARTEMIS_SERVICE_XML;
public static final String ETC_ARTEMIS_PROFILE_CMD = "artemis.profile.cmd";
public static final String BIN_ARTEMIS = "bin/artemis";
public static final String BIN_ARTEMIS_SERVICE = "bin/artemis-service";
public static final String ARTEMIS = "artemis";
public static final String BIN_ARTEMIS = "bin/" + ARTEMIS;
public static final String ARTEMIS_SERVICE = "artemis-service";
public static final String BIN_ARTEMIS_SERVICE = "bin/" + ARTEMIS_SERVICE;
public static final String ETC_ARTEMIS_PROFILE = "artemis.profile";
public static final String ETC_LOG4J2_PROPERTIES = "log4j2.properties";
public static final String ETC_BOOTSTRAP_XML = "bootstrap.xml";
@ -115,9 +108,6 @@ public class Create extends InputAbstract {
public static final String ETC_PAGE_SYNC_SETTINGS = "etc/page-sync-settings.txt";
public static final String ETC_JOLOKIA_ACCESS_XML = "jolokia-access.xml";
@Arguments(description = "The instance directory to hold the broker's configuration and data. Path must be writable.", required = true)
private File directory;
@Option(name = "--host", description = "The host name of the broker (Default: 0.0.0.0 or input if clustered)")
private String host;
@ -160,15 +150,9 @@ public class Create extends InputAbstract {
@Option(name = "--force", description = "Overwrite configuration at destination directory")
private boolean force;
@Option(name = "--home", description = "Directory where ActiveMQ Artemis is installed")
private File home;
@Option(name = "--data", description = "Directory where ActiveMQ data are stored. Paths can be absolute or relative to artemis.instance directory ('data' by default)")
private String data = "data";
@Option(name = "--etc", description = "Directory where ActiveMQ configuration is located. Paths can be absolute or relative to artemis.instance directory ('etc' by default)")
private String etc = "etc";
@Option(name = "--clustered", description = "Enable clustering")
private boolean clustered = false;
@ -196,15 +180,6 @@ public class Create extends InputAbstract {
@Option(name = "--cluster-password", description = "The cluster password to use for clustering. (Default: input)")
private String clusterPassword = null;
@Option(name = "--encoding", description = "The encoding that text files should use")
private String encoding = "UTF-8";
@Option(name = "--java-options", description = "Extra java options to be passed to the profile")
private String javaOptions = "";
@Option(name = "--java-memory", description = "Define the -Xmx memory parameter for the broker. Default = '2G'")
private String javaMemory = "2G";
@Option(name = "--allow-anonymous", description = "Enables anonymous configuration on security, opposite of --require-login (Default: input)")
private Boolean allowAnonymous = null;
@ -345,9 +320,6 @@ public class Create extends InputAbstract {
@Option(name = "--jdbc-lock-expiration", description = "Lock expiration")
long jdbcLockExpiration = ActiveMQDefaultConfiguration.getDefaultJdbcLockExpirationMillis();
private boolean IS_WINDOWS;
private boolean IS_CYGWIN;
private boolean isAutoCreate() {
if (autoCreate == null) {
if (noAutoCreate != null) {
@ -362,14 +334,6 @@ public class Create extends InputAbstract {
return autoCreate;
}
public File getInstance() {
return directory;
}
public void setInstance(File directory) {
this.directory = directory;
}
public String getHost() {
if (host == null) {
host = "0.0.0.0";
@ -397,13 +361,6 @@ public class Create extends InputAbstract {
this.force = force;
}
public File getHome() {
if (home == null) {
home = new File(getBrokerHome());
}
return home;
}
public void setHome(File home) {
this.home = home;
}
@ -420,14 +377,6 @@ public class Create extends InputAbstract {
return sharedStore;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public String getData() {
return data;
}
@ -553,13 +502,6 @@ public class Create extends InputAbstract {
return run(context);
}
/**
* This method is made public for the testsuite
*/
public InputStream openStream(String source) {
return this.getClass().getResourceAsStream(source);
}
/**
* Checks that the directory provided either exists and is writable or doesn't exist but can be created.
*/
@ -583,10 +525,9 @@ public class Create extends InputAbstract {
return directory;
}
@Override
public Object run(ActionContext context) throws Exception {
IS_WINDOWS = System.getProperty("os.name").toLowerCase().trim().startsWith("win");
IS_CYGWIN = IS_WINDOWS && "cygwin".equals(System.getenv("OSTYPE"));
super.run(context);
setupJournalType();
@ -670,7 +611,6 @@ public class Create extends InputAbstract {
filters.put("${message-load-balancing}", messageLoadBalancing.toString());
filters.put("${user}", getUser());
filters.put("${password}", getPassword());
filters.put("${role}", role);
filters.put("${encoded.role}", role.replaceAll(" ", "\\\\ "));
@ -749,30 +689,21 @@ public class Create extends InputAbstract {
if (home != null) {
filters.put("${home}", path(home));
}
filters.put("${artemis.home}", path(getHome().toString()));
filters.put("${artemis.instance}", path(directory));
filters.put("${artemis.instance.uri}", directory.toURI().toString());
filters.put("${artemis.instance.uri.windows}", directory.toURI().toString().replaceAll("%", "%%"));
filters.put("${artemis.instance.name}", directory.getName());
filters.put("${java.home}", path(System.getProperty("java.home")));
new File(directory, "bin").mkdirs();
File etcFolder = createDirectory(etc, directory);
filters.put("${artemis.instance.etc.uri}", etcFolder.toURI().toString());
filters.put("${artemis.instance.etc.uri.windows}", etcFolder.toURI().toString().replaceAll("%", "%%"));
filters.put("${artemis.instance.etc}", path(etcFolder));
File logFolder = createDirectory("log", directory);
File oomeDumpFile = new File(logFolder, "oom_dump.hprof");
filters.put("${artemis.instance.oome.dump}", path(oomeDumpFile));
new File(directory, "tmp").mkdirs();
new File(directory, "lib").mkdirs();
File dataFolder = createDirectory(data, directory);
filters.put("${artemis.instance.data}", path(dataFolder));
File logFolder = createDirectory("log", directory);
File oomeDumpFile = new File(logFolder, "oom_dump.hprof");
if (javaOptions == null || javaOptions.length() == 0) {
javaOptions = "";
}
addScriptFilters(filters, getHome(), getInstance(), etcFolder, dataFolder, oomeDumpFile, javaMemory, javaOptions, role);
boolean allowAnonymous = isAllowAnonymous();
@ -794,22 +725,21 @@ public class Create extends InputAbstract {
filters.put("${journal-retention}", retentionTag);
filters.put("${java-opts}", javaOptions);
filters.put("${java-memory}", javaMemory);
if (allowAnonymous) {
write(ETC_LOGIN_CONFIG_WITH_GUEST, new File(etcFolder, ETC_LOGIN_CONFIG), filters, false);
write(ETC_LOGIN_CONFIG_WITH_GUEST, new File(etcFolder, ETC_LOGIN_CONFIG), filters, false, force);
} else {
write(ETC_LOGIN_CONFIG_WITHOUT_GUEST, new File(etcFolder, ETC_LOGIN_CONFIG), filters, false);
write(ETC_LOGIN_CONFIG_WITHOUT_GUEST, new File(etcFolder, ETC_LOGIN_CONFIG), filters, false, force);
}
writeEtc(ETC_ARTEMIS_ROLES_PROPERTIES, etcFolder, filters, false);
if (IS_WINDOWS) {
write(BIN_ARTEMIS_CMD, filters, false);
write(BIN_ARTEMIS_SERVICE_EXE);
write(BIN_ARTEMIS_SERVICE_EXE_CONFIG);
write(BIN_ARTEMIS_SERVICE_EXE, force);
write(BIN_ARTEMIS_SERVICE_EXE_CONFIG, force);
write(BIN_ARTEMIS_SERVICE_XML, filters, false);
writeEtc(ETC_ARTEMIS_PROFILE_CMD, etcFolder, filters, false);
}
@ -881,7 +811,6 @@ public class Create extends InputAbstract {
writeEtc(ETC_ARTEMIS_USERS_PROPERTIES, etcFolder, filters, false);
// we want this variable to remain unchanged so that it will use the value set in the profile
filters.remove("${artemis.instance}");
if (SecurityManagerType.getType(securityManager) == SecurityManagerType.BASIC) {
filters.put("${security-manager-settings}", readTextFile(ETC_BASIC_SECURITY_MANAGER_TXT, filters));
} else {
@ -894,7 +823,7 @@ public class Create extends InputAbstract {
filters.put("${jolokia.options}", "<!-- option relax-jolokia used, so strict-checking will be removed here -->");
} else {
filters.put("${jolokia.options}", "<!-- Check for the proper origin on the server side, too -->\n" +
" <strict-checking/>");
" <strict-checking/>");
}
writeEtc(ETC_JOLOKIA_ACCESS_XML, etcFolder, filters, false);
@ -930,6 +859,34 @@ public class Create extends InputAbstract {
return null;
}
protected static void addScriptFilters(HashMap<String, String> filters,
File home,
File directory,
File etcFolder,
File dataFolder,
File oomeDumpFile,
String javaMemory,
String javaOptions,
String role) throws IOException {
filters.put("${artemis.home}", path(home));
// I am using a different replacing pattern here, for cases where want an actual ${artemis.instance} in the output
// so that's just to make a distinction
filters.put("@artemis.instance@", path(directory));
filters.put("${artemis.instance.uri}", directory.toURI().toString());
filters.put("${artemis.instance.uri.windows}", directory.toURI().toString().replaceAll("%", "%%"));
filters.put("${artemis.instance.name}", directory.getName());
filters.put("${java.home}", path(System.getProperty("java.home")));
filters.put("${artemis.instance.etc.uri}", etcFolder.toURI().toString());
filters.put("${artemis.instance.etc.uri.windows}", etcFolder.toURI().toString().replaceAll("%", "%%"));
filters.put("${artemis.instance.etc}", path(etcFolder));
filters.put("${artemis.instance.oome.dump}", path(oomeDumpFile));
filters.put("${artemis.instance.data}", path(dataFolder));
filters.put("${java-memory}", javaMemory);
filters.put("${java-opts}", javaOptions);
filters.put("${role}", role);
}
private String getConnectors(HashMap<String, String> filters) throws IOException {
if (staticNode != null) {
StringWriter stringWriter = new StringWriter();
@ -1069,7 +1026,7 @@ public class Create extends InputAbstract {
syncFilter.put("${maxaio}", journalType == JournalType.ASYNCIO ? "" + ActiveMQDefaultConfiguration.getDefaultJournalMaxIoAio() : "1");
getActionContext().out.println("done! Your system can make " + writesPerMillisecondStr +
" writes per millisecond, your journal-buffer-timeout will be " + nanoseconds);
" writes per millisecond, your journal-buffer-timeout will be " + nanoseconds);
filters.put("${journal-buffer.settings}", readTextFile(ETC_JOURNAL_BUFFER_SETTINGS, syncFilter));
@ -1140,89 +1097,20 @@ public class Create extends InputAbstract {
}
}
private String path(String value) throws IOException {
private static String path(String value) throws IOException {
return path(new File(value));
}
private String path(File value) throws IOException {
private static String path(File value) throws IOException {
return value.getCanonicalPath();
}
private void write(String source, HashMap<String, String> filters, boolean unixTarget) throws Exception {
write(source, new File(directory, source), filters, unixTarget);
write(source, new File(directory, source), filters, unixTarget, force);
}
private void writeEtc(String source, File etcFolder, HashMap<String, String> filters, boolean unixTarget) throws Exception {
write("etc/" + source, new File(etcFolder, source), filters, unixTarget);
}
private void write(String source,
File target,
HashMap<String, String> filters,
boolean unixTarget) throws Exception {
if (target.exists() && !force) {
throw new CLIException(String.format("The file '%s' already exists. Use --force to overwrite.", target));
}
String content = readTextFile(source, filters);
// and then writing out in the new target encoding.. Let's also replace \n with the values
// that is correct for the current platform.
String separator = unixTarget && IS_CYGWIN ? "\n" : System.getProperty("line.separator");
content = content.replaceAll("\\r?\\n", Matcher.quoteReplacement(separator));
ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes(encoding));
try (FileOutputStream fout = new FileOutputStream(target)) {
copy(in, fout);
}
}
private String applyFilters(String content, Map<String, String> filters) throws IOException {
if (filters != null) {
for (Map.Entry<String, String> entry : filters.entrySet()) {
try {
content = replace(content, entry.getKey(), entry.getValue());
} catch (Throwable e) {
getActionContext().out.println("Error on " + entry.getKey());
e.printStackTrace();
System.exit(-1);
}
}
}
return content;
}
private String readTextFile(String source, Map<String, String> filters) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (InputStream in = openStream(source)) {
copy(in, out);
}
return applyFilters(new String(out.toByteArray(), StandardCharsets.UTF_8), filters);
}
private void write(String source) throws IOException {
File target = new File(directory, source);
if (target.exists() && !force) {
throw new RuntimeException(String.format("The file '%s' already exists. Use --force to overwrite.", target));
}
try (FileOutputStream fout = new FileOutputStream(target)) {
try (InputStream in = openStream(source)) {
copy(in, fout);
}
}
}
private String replace(String content, String key, String value) {
return content.replaceAll(Pattern.quote(key), Matcher.quoteReplacement(value));
}
private void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024 * 4];
int c = is.read(buffer);
while (c >= 0) {
os.write(buffer, 0, c);
c = is.read(buffer);
}
write("etc/" + source, new File(etcFolder, source), filters, unixTarget, force);
}
private enum SecurityManagerType {
@ -1240,4 +1128,4 @@ public class Create extends InputAbstract {
}
}
}
}
}

View File

@ -0,0 +1,176 @@
/*
* 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.airlift.airline.Arguments;
import io.airlift.airline.Option;
import org.apache.activemq.artemis.cli.CLIException;
public class InstallAbstract extends InputAbstract {
@Arguments(description = "The instance directory to hold the broker's configuration and data. Path must be writable.", required = true)
protected File directory;
@Option(name = "--etc", description = "Directory where ActiveMQ configuration is located. Paths can be absolute or relative to artemis.instance directory ('etc' by default)")
protected String etc = "etc";
@Option(name = "--home", description = "Directory where ActiveMQ Artemis is installed")
protected File home;
@Option(name = "--encoding", description = "The encoding that text files should use. Default = UTF-8.")
protected String encoding = "UTF-8";
@Option(name = "--windows", description = "Force windows script creation. Default based on your actual system.")
protected boolean windows = false;
@Option(name = "--cygwin", description = "Force cygwin script creation. Default based on your actual system.")
protected boolean cygwin = false;
@Option(name = "--java-options", description = "Extra java options to be passed to the profile")
protected String javaOptions = "";
@Option(name = "--java-memory", description = "Define the -Xmx memory parameter for the broker. Default = '2G'")
protected String javaMemory = "2G";
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public File getInstance() {
return directory;
}
public void setInstance(File directory) {
this.directory = directory;
}
public File getHome() {
if (home == null) {
home = new File(getBrokerHome());
}
return home;
}
protected boolean IS_WINDOWS;
protected boolean IS_CYGWIN;
public Object run(ActionContext context) throws Exception {
IS_WINDOWS = windows | System.getProperty("os.name").toLowerCase().trim().startsWith("win");
IS_CYGWIN = cygwin | IS_WINDOWS && "cygwin".equals(System.getenv("OSTYPE"));
return null;
}
protected String applyFilters(String content, Map<String, String> filters) {
if (filters != null) {
for (Map.Entry<String, String> entry : filters.entrySet()) {
content = replace(content, entry.getKey(), entry.getValue());
}
}
return content;
}
protected String replace(String content, String key, String value) {
return content.replaceAll(Pattern.quote(key), Matcher.quoteReplacement(value));
}
protected void copy(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[1024 * 4];
int c = is.read(buffer);
while (c >= 0) {
os.write(buffer, 0, c);
c = is.read(buffer);
}
}
protected void write(String source,
File target,
HashMap<String, String> filters,
boolean unixTarget, boolean force) throws Exception {
if (target.exists() && !force) {
throw new CLIException(String.format("The file '%s' already exists. Use --force to overwrite.", target));
}
String content = readTextFile(source, filters);
if (content == null) {
new Exception(source + " not found").printStackTrace();
}
// and then writing out in the new target encoding.. Let's also replace \n with the values
// that is correct for the current platform.
String separator = unixTarget && IS_CYGWIN ? "\n" : System.getProperty("line.separator");
content = content.replaceAll("\\r?\\n", Matcher.quoteReplacement(separator));
ByteArrayInputStream in = new ByteArrayInputStream(content.getBytes(encoding));
try (FileOutputStream fout = new FileOutputStream(target)) {
copy(in, fout);
}
}
protected String readTextFile(String source, Map<String, String> filters) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (InputStream in = openStream(source)) {
if (in == null) {
throw new IOException("could not find resource " + source);
}
copy(in, out);
}
return applyFilters(new String(out.toByteArray(), StandardCharsets.UTF_8), filters);
}
protected void write(String source, boolean force) throws IOException {
File target = new File(directory, source);
if (target.exists() && !force) {
throw new RuntimeException(String.format("The file '%s' already exists. Use --force to overwrite.", target));
}
try (FileOutputStream fout = new FileOutputStream(target)) {
try (InputStream in = openStream(source)) {
copy(in, fout);
}
}
}
/**
* This method is made public for the testsuite
*/
public InputStream openStream(String source) {
return this.getClass().getResourceAsStream(source);
}
}

View File

@ -75,6 +75,8 @@ public class Run extends LockAbstract {
public Object execute(ActionContext context) throws Exception {
super.execute(context);
verifyOlderLogging(new File(getBrokerEtc()));
AtomicReference<Throwable> serverActivationFailed = new AtomicReference<>();
try {
BrokerDTO broker = getBrokerDTO();
@ -225,4 +227,20 @@ public class Run extends LockAbstract {
e.printStackTrace();
}
}
public static final String OLD_LOG_NAME = "logging.properties";
public static void verifyOlderLogging(File etc) throws Exception {
File newLogging = new File(etc, Create.ETC_LOG4J2_PROPERTIES);
File oldLogging = new File(etc, OLD_LOG_NAME);
if (oldLogging.exists() && !newLogging.exists()) {
System.out.println("******************************************************************************************************************************************************************************");
System.out.println("Your system has the older logging file " + OLD_LOG_NAME + ", but not the new " + Create.ETC_LOG4J2_PROPERTIES);
System.out.println("It appears you did not complete the migration on this artemis instance properly. Please check all the settings or run the './artemis upgrade' command from the new artemis home");
System.out.println("******************************************************************************************************************************************************************************");
}
}
}

View File

@ -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.cli.commands;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import io.airlift.airline.Command;
@Command(name = "upgrade", description = "Update an artemis instance to the current artemis.home, keeping all the data and broker.xml. Warning: backup your instance before using this command and compare the files.")
public class Upgrade extends InstallAbstract {
/**
* Checks that the directory provided either exists and is writable or doesn't exist but can be created.
*/
protected void checkDirectory() {
if (!directory.exists()) {
throw new RuntimeException(String.format("Could not find path '%s' to upgrade.", directory));
} else if (!directory.canWrite()) {
throw new RuntimeException(String.format("The path '%s' is not writable.", directory));
}
}
@Override
public Object execute(ActionContext context) throws Exception {
this.checkDirectory();
super.execute(context);
return run(context);
}
@Override
public Object run(ActionContext context) throws Exception {
super.run(context);
context.out.println("*******************************************************************************************************************************");
context.out.println("Upgrading broker instance " + directory + " to use artemis.home=" + getBrokerHome());
File bkpFolder = findBackup(context);
File binBkp = new File(bkpFolder, "bin");
File etcBkp = new File(bkpFolder, "etc");
File tmp = new File(bkpFolder, "tmp");
binBkp.mkdirs();
etcBkp.mkdirs();
tmp.mkdirs();
File bin = new File(directory, "bin");
File etcFolder = new File(directory, etc);
if (etc == null || etc.equals("etc")) {
if (IS_WINDOWS && !IS_CYGWIN) {
File cmd = new File(bin, Create.ARTEMIS_CMD);
String pattern = "set ARTEMIS_INSTANCE_ETC=";
etcFolder = getETC(context, etcFolder, cmd, pattern);
} else {
File cmd = new File(bin, Create.ARTEMIS);
String pattern = "ARTEMIS_INSTANCE_ETC=";
etcFolder = getETC(context, etcFolder, cmd, pattern);
}
}
if (bin == null || !bin.exists()) { // it can't be null, just being cautious
throw new IOException(bin + " does not exist for binary");
}
if (etcFolder == null || !etcFolder.exists()) { // it can't be null, just being cautious
throw new IOException(etcFolder + " does not exist for etc");
}
HashMap<String, String> filters = new HashMap<>();
Create.addScriptFilters(filters, getHome(), getInstance(), etcFolder, new File(getInstance(), "notUsed"), new File(getInstance(), "om-not-used.dmp"), javaMemory, javaOptions, "NA");
if (IS_WINDOWS) {
write(Create.BIN_ARTEMIS_CMD, new File(tmp, Create.ARTEMIS_CMD), filters, false, false);
upgrade(new File(tmp, Create.ARTEMIS_CMD), new File(bin, Create.ARTEMIS_CMD), binBkp, "set ARTEMIS_INSTANCE_ETC=");
write(Create.BIN_ARTEMIS_SERVICE_XML, new File(tmp, Create.ARTEMIS_SERVICE_XML), filters, false, false);
upgrade(new File(tmp, Create.ARTEMIS_SERVICE_XML), new File(bin, Create.ARTEMIS_SERVICE_XML), binBkp,
"<env name=\"ARTEMIS_INSTANCE\"", "<env name=\"ARTEMIS_INSTANCE_ETC\"",
"<env name=\"ARTEMIS_INSTANCE_URI\"", "<env name=\"ARTEMIS_INSTANCE_ETC_URI\"",
"<env name=\"ARTEMIS_DATA_DIR\"", "<logpath>", "<startargument>-Xmx", "<stopargument>-Xmx");
write("etc/" + Create.ETC_ARTEMIS_PROFILE_CMD, new File(tmp, Create.ETC_ARTEMIS_PROFILE_CMD), filters, false, false);
upgrade(new File(tmp, Create.ETC_ARTEMIS_PROFILE_CMD), new File(etcFolder, Create.ETC_ARTEMIS_PROFILE_CMD), binBkp,
"set ARTEMIS_INSTANCE=\"", "set ARTEMIS_DATA_DIR=", "set ARTEMIS_ETC_DIR=", "set ARTEMIS_OOME_DUMP=", "set ARTEMIS_INSTANCE_URI=", "set ARTEMIS_INSTANCE_ETC_URI=");
}
if (!IS_WINDOWS || IS_CYGWIN) {
write(Create.BIN_ARTEMIS, new File(tmp, Create.ARTEMIS), filters, false, false);
upgrade(new File(tmp, Create.ARTEMIS), new File(bin, Create.ARTEMIS), binBkp, "ARTEMIS_INSTANCE_ETC=");
write(Create.BIN_ARTEMIS_SERVICE, new File(tmp, Create.ARTEMIS_SERVICE), filters, false, false);
upgrade(new File(tmp, Create.ARTEMIS_SERVICE), new File(bin, Create.ARTEMIS_SERVICE), binBkp); // we replace the whole thing
write("etc/" + Create.ETC_ARTEMIS_PROFILE, new File(tmp, Create.ETC_ARTEMIS_PROFILE), filters, false, false);
upgrade(new File(tmp, Create.ETC_ARTEMIS_PROFILE), new File(etcFolder, Create.ETC_ARTEMIS_PROFILE), etcBkp, "ARTEMIS_INSTANCE=",
"ARTEMIS_DATA_DIR=", "ARTEMIS_ETC_DIR=", "ARTEMIS_OOME_DUMP=", "ARTEMIS_INSTANCE_URI=", "ARTEMIS_INSTANCE_ETC_URI=", "HAWTIO_ROLE=");
}
upgradeLogging(context, etcBkp, etcFolder);
context.out.println();
context.out.println("*******************************************************************************************************************************");
return null;
}
private File getETC(ActionContext context, File etcFolder, File cmd, String pattern) throws IOException {
String etcLine = getLine(cmd, pattern);
if (etcLine != null) {
etcLine = etcLine.trim();
etcLine = etcLine.substring(pattern.length() + 1, etcLine.length() - 1);
etcFolder = new File(etcLine);
context.out.println("ETC found at " + etcFolder);
}
return etcFolder;
}
private String getLine(File cmd, String pattern) throws IOException {
Stream<String> lines = Files.lines(cmd.toPath());
Iterator<String> iterator = lines.iterator();
while (iterator.hasNext()) {
String line = iterator.next();
if (line.trim().startsWith(pattern)) {
return line;
}
}
return null;
}
private void upgrade(File tmpFile, File targetFile, File bkp, String... keepingPrefixes) throws Exception {
HashMap<String, String> replaceMatrix = new HashMap<>();
doUpgrade(tmpFile, targetFile, bkp,
line -> {
for (String prefix : keepingPrefixes) {
if (line.trim().startsWith(prefix)) {
replaceMatrix.put(prefix, line);
}
}
}, line -> {
for (String prefix : keepingPrefixes) {
if (line.trim().startsWith(prefix)) {
String original = replaceMatrix.get(prefix);
return original;
}
}
return line;
});
}
private void doUpgrade(File tmpFile, File targetFile, File bkp, Consumer<String> originalConsumer, Function<String, String> targetFunction) throws Exception {
Files.copy(targetFile.toPath(), bkp.toPath(), StandardCopyOption.REPLACE_EXISTING);
// we first scan the original lines on the originalConsumer, giving a chance to the caller to fill out the original matrix
Stream<String> originalLines = Files.lines(targetFile.toPath());
originalLines.forEach(line -> {
if (originalConsumer != null) {
originalConsumer.accept(line);
}
});
// now we open the new file from the tmp, and we will give a chance for the targetFunction to replace lines from a matrix
try (Stream<String> lines = Files.lines(tmpFile.toPath());
PrintStream streamOutput = new PrintStream(new FileOutputStream(targetFile))) {
Iterator<String> linesIterator = lines.iterator();
while (linesIterator.hasNext()) {
String line = linesIterator.next();
line = targetFunction.apply(line);
if (line != null) {
streamOutput.println(line);
}
}
}
}
private void upgradeLogging(ActionContext context, File bkpFolder, File etc) throws Exception {
File oldLogging = new File(etc, "logging.properties");
if (oldLogging.exists()) {
context.out.println("Moving " + oldLogging + " under " + bkpFolder);
File oldLoggingCopy = new File(bkpFolder, "logging.properties");
context.out.println(oldLogging.toPath() + " copy as " + oldLoggingCopy.toPath());
Files.copy(oldLogging.toPath(), bkpFolder.toPath(), StandardCopyOption.REPLACE_EXISTING);
oldLogging.delete();
File newLogging = new File(etc, Create.ETC_LOG4J2_PROPERTIES);
if (!newLogging.exists()) {
context.out.println("Creating " + newLogging);
InputStream inputStream = getClass().getResourceAsStream("etc/" + Create.ETC_LOG4J2_PROPERTIES);
OutputStream outputStream = new FileOutputStream(newLogging);
outputStream.write(inputStream.readAllBytes());
inputStream.close();
}
}
}
protected File findBackup(ActionContext context) {
for (int bkp = 0; bkp < 10; bkp++) {
File bkpFolder = new File(directory, "old-config-bkp." + bkp);
if (!bkpFolder.exists()) {
bkpFolder.mkdirs();
context.out.println("Using " + bkpFolder.getAbsolutePath() + " as a backup folder for the modified files");
return bkpFolder;
}
}
throw new RuntimeException("Too many backup folders in place already. Please remove some of the old-config-bkp.* folders");
}
}

View File

@ -23,13 +23,13 @@
<description>Apache ActiveMQ Artemis is a reliable messaging broker</description>
<env name="ARTEMIS_HOME" value="${artemis.home}"/>
<env name="ARTEMIS_INSTANCE" value="${artemis.instance}"/>
<env name="ARTEMIS_INSTANCE" value="@artemis.instance@"/>
<env name="ARTEMIS_INSTANCE_ETC" value="${artemis.instance.etc}"/>
<env name="ARTEMIS_INSTANCE_URI" value="${artemis.instance.uri}"/>
<env name="ARTEMIS_INSTANCE_ETC_URI" value="${artemis.instance.etc.uri.windows}"/>
<env name="ARTEMIS_DATA_DIR" value="${artemis.instance.data}"/>
<logpath>${artemis.instance}\log</logpath>
<logpath>@artemis.instance@\log</logpath>
<logmode>roll</logmode>
<executable>%JAVA_HOME%\bin\java.exe</executable>

View File

@ -16,7 +16,7 @@
# under the License.
ARTEMIS_HOME='${artemis.home}'
ARTEMIS_INSTANCE='${artemis.instance}'
ARTEMIS_INSTANCE='@artemis.instance@'
ARTEMIS_DATA_DIR='${artemis.instance.data}'
ARTEMIS_ETC_DIR='${artemis.instance.etc}'
ARTEMIS_OOME_DUMP='${artemis.instance.oome.dump}'

View File

@ -17,7 +17,7 @@ rem specific language governing permissions and limitations
rem under the License.
set ARTEMIS_HOME="${artemis.home}"
set ARTEMIS_INSTANCE="${artemis.instance}"
set ARTEMIS_INSTANCE="@artemis.instance@"
set ARTEMIS_DATA_DIR="${artemis.instance.data}"
set ARTEMIS_ETC_DIR="${artemis.instance.etc}"
set ARTEMIS_OOME_DUMP="${artemis.instance.oome.dump}"

View File

@ -0,0 +1,120 @@
/*
* 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.maven;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.activemq.artemis.boot.Artemis;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
@Mojo(name = "upgrade", defaultPhase = LifecyclePhase.TEST_COMPILE)
public class ArtemisUpgradePlugin extends ArtemisAbstractPlugin {
@Parameter
String name;
/**
* The plugin descriptor
*/
private PluginDescriptor descriptor;
@Parameter(defaultValue = "${activemq.basedir}", required = true)
private File home;
@Parameter(defaultValue = "${activemq.basedir}/artemis-distribution/target/apache-artemis-${project.version}-bin/apache-artemis-${project.version}/", required = true)
private File alternateHome;
@Parameter(defaultValue = "${basedir}/target/server0", required = true)
private File instance;
@Parameter
private String[] args;
@Override
protected boolean isIgnore() {
return false;
}
@Parameter boolean useSystemOutput = getLog().isDebugEnabled();
private void add(List<String> list, String... str) {
for (String s : str) {
list.add(s);
}
}
@Override
protected void doExecute() throws MojoExecutionException, MojoFailureException {
getLog().debug("Local " + localRepository);
MavenProject project = (MavenProject) getPluginContext().get("project");
if (!isArtemisHome(home.toPath())) {
if (isArtemisHome(alternateHome.toPath())) {
home = alternateHome;
} else {
getLog().error("********************************************************************************************");
getLog().error("Could not locate suitable Artemis.home on either " + home + " or " + alternateHome);
getLog().error("Use the binary distribution or build the distribution before running the examples");
getLog().error("********************************************************************************************");
throw new MojoExecutionException("Couldn't find artemis.home");
}
}
Map properties = getPluginContext();
Set<Map.Entry> entries = properties.entrySet();
if (getLog().isDebugEnabled()) {
getLog().debug("Entries.size " + entries.size());
for (Map.Entry entry : entries) {
getLog().debug("... key=" + entry.getKey() + " = " + entry.getValue());
}
}
ArrayList<String> listCommands = new ArrayList<>();
add(listCommands, "upgrade");
add(listCommands, instance.getAbsolutePath());
if (args != null) {
for (String a : args) {
add(listCommands, a);
}
}
getLog().debug("***** Server upgrading at " + instance + " with home=" + home + " *****");
try {
Artemis.execute(home, null, null, useSystemOutput, listCommands);
} catch (Throwable e) {
getLog().error(e);
throw new MojoFailureException(e.getMessage());
}
}
}

View File

@ -16,18 +16,18 @@ Because of this separation it's very easy to upgrade Artemis in most cases.
> **Note:**
>
> It's recommended to choose a folder different than the on where Apache
> It's recommended to choose a folder different from where Apache
> Artemis was downloaded. This separation allows you run multiple broker
> instances with the same Artemis "home" for example. It also simplifies
> updating to newer versions of Artemis.
## General Upgrade Procedure
Upgrading may require some specific steps noted in the [versions](versions.md),
but the general process is as follows:
1. Navigate to the `etc` folder of the broker instance that's being upgraded
1. Open `artemis.profile` (`artemis.profile.cmd` on Windows). It contains a
2. Open `artemis.profile` (`artemis.profile.cmd` on Windows). It contains a
property which is relevant for the upgrade:
```
@ -37,7 +37,7 @@ but the general process is as follows:
If you run Artemis as a service on windows you have to do the following additional steps:
1. Navigate to the `bin` folder of the broker instance that's being upgraded
1. Open `artemis-service.xml`. It contains a property which is relevant for the upgrade:
2. Open `artemis-service.xml`. It contains a property which is relevant for the upgrade:
```
<env name="ARTEMIS_HOME" value="/path/to/apache-artemis-version"/>
@ -48,3 +48,23 @@ most cases_ the instance can be upgraded to a newer version simply by changing
the value of this property to the location of the new broker home. Please refer
to the aforementioned [versions](versions.md) document for additional upgrade
steps (if required).
It is also possible to do these steps automatically as it can be seen in the next section.
## Upgrading tool
An automatic approach can be used to upgrade the instance. You may simply call `./artemis upgrade <old-instance>`.
```shell
cd $NEW_ARTEMIS_DOWNLOAD/bin/
./artemis upgrade PATH_TO_UPGRADING_INSTANCE
```
artemis, artemis.profile will be updated to the new version.
The tool will also update log4j2.properties (if you are migrating from a version previous to 2.27.0).
> **Note:**
>
>Eventual customizations to your scripts will be lost, however the script will copy the older version at a created old-config-bkp folder.

View File

@ -9,8 +9,10 @@ This chapter provides the following information for each release:
chapter in addition to any version-specific upgrade instructions outlined here.
## 2.27.0
[Full release notes](https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12352246&projectId=12315920)
Highlights:
- 2.27.0 Introduced a new upgrade tool to help migrating your instance to a newer version. Simply use `./artemis upgrade <path-to-your-instance>` from the new downloaded broker.
- The client and broker now use [SLF4J](https://www.slf4j.org/) for their logging API.
- The broker distribution now uses [Log4J 2](https://logging.apache.org/log4j/2.x/manual/) as its logging implementation.

View File

@ -191,6 +191,22 @@
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/filtered-resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
@ -1212,6 +1228,29 @@
</args>
</configuration>
</execution>
<execution>
<phase>test-compile</phase>
<id>upgrade</id>
<goals>
<goal>upgrade</goal>
</goals>
<configuration>
<instance>${basedir}/target/classes/servers/toUpgradeTest</instance>
</configuration>
</execution>
<execution>
<phase>test-compile</phase>
<id>upgrade-windows</id>
<goals>
<goal>upgrade</goal>
</goals>
<configuration>
<instance>${basedir}/target/classes/servers/windows</instance>
<args>
<arg>--windows</arg>
</args>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>

View File

@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
amq = y

View File

@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
y = ENC(1024:4D83B7E5E85B4F43D65E31E9C7A69055D13BB165E54F57078F3E5D3DA188F3ED:3D71F9F4D6396B43255D37B47E859357DC244759B9BF5BCCA19DAD8C613E1A7302EF7A433BE2463B6AC4057B7227271C23659BF50CFE30ACE49F891C63F2A7D2)

View File

@ -0,0 +1,65 @@
# 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.
ARTEMIS_HOME='must-change'
ARTEMIS_INSTANCE='${project.basedir}/target/classes/servers/toUpgradeTest'
ARTEMIS_DATA_DIR='${project.basedir}/target/classes/servers/toUpgradeTest/data'
ARTEMIS_ETC_DIR='${project.basedir}/target/classes/servers/toUpgradeETC'
ARTEMIS_OOME_DUMP='${project.basedir}/target/classes/servers/toUpgradeTest/log/oom_dump.hprof'
# The logging config will need an URI
# this will be encoded in case you use spaces or special characters
# on your directory structure
ARTEMIS_INSTANCE_URI='file:${project.basedir}/target/classes/servers/toUpgradeTest'
ARTEMIS_INSTANCE_ETC_URI='file:${project.basedir}/target/classes/servers/toUpgradeETC'
# Cluster Properties: Used to pass arguments to ActiveMQ Artemis 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"
# Hawtio Properties
# HAWTIO_ROLE define the user role or roles required to be able to login to the console. Multiple roles to allow can
# be separated by a comma. Set to '*' or an empty value to disable role checking when Hawtio authenticates a user.
HAWTIO_ROLE='amq'
# Java Opts
if [ -z "$JAVA_ARGS" ]; then
#### I am adding a customization to the JAVA-ARGS that would be replaced
#### If this line is seen on the upgrade it means that things are not working
JAVA_ARGS="-should-not-work -XX:+PrintClassHistogram -XX:+UseG1GC -XX:+UseStringDeduplication -Xms512M -Xmx2G -Dhawtio.disableProxy=true -Dhawtio.realm=activemq -Dhawtio.offline=true -Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal -Djolokia.policyLocation=${ARTEMIS_INSTANCE_ETC_URI}jolokia-access.xml "
fi
# Uncomment to enable logging for Safepoint JVM pauses
#
# In addition to the traditional GC logs you could enable some JVM flags to know any meaningful and "hidden" pause
# that could affect the latencies of the services delivered by the broker, including those that are not reported by
# the classic GC logs and dependent by JVM background work (eg method deoptimizations, lock unbiasing, JNI, counted
# loops and obviously GC activity).
#
# Replace "all_pauses.log" with the file name you want to log to.
# JAVA_ARGS="$JAVA_ARGS -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+LogVMOutput -XX:LogFile=all_pauses.log"
# Uncomment to enable the dumping of the Java heap when a java.lang.OutOfMemoryError exception is thrown
# JAVA_ARGS="$JAVA_ARGS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${ARTEMIS_OOME_DUMP}"
# Only enable debug options for the 'run' command
if [ "$1" = "run" ]; then :
# Uncomment to enable remote debugging
# DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005"
# Uncomment for async profiler
# DEBUG_ARGS="-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints"
fi

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ 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.
-->
<broker xmlns="http://activemq.apache.org/schema">
<jaas-security domain="activemq"/>
<!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
This is to avoid situations where you could have spaces or special characters on this URI -->
<server configuration="file:${project.basedir}/target/classes/servers/toUpgradeETC/broker.xml"/>
<!-- The web server is only bound to localhost by default -->
<web path="web">
<binding uri="http://localhost:8161">
<app url="activemq-branding" war="activemq-branding.war"/>
<app url="artemis-plugin" war="artemis-plugin.war"/>
<app url="console" war="console.war"/>
</binding>
</web>
</broker>

View File

@ -0,0 +1,254 @@
<?xml version='1.0'?>
<!--
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.
-->
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq:core ">
<name>0.0.0.0</name>
<persistence-enabled>true</persistence-enabled>
<!-- this could be ASYNCIO, MAPPED, NIO
ASYNCIO: Linux Libaio
MAPPED: mmap files
NIO: Plain Java Files
-->
<journal-type>NIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<!-- if you want to retain your journal uncomment this following configuration.
This will allow your system to keep 7 days of your data, up to 10G. Tweak it accordingly to your use case and capacity.
it is recommended to use a separate storage unit from the journal for performance considerations.
<journal-retention-directory period="7" unit="DAYS" storage-limit="10G">data/retention</journal-retention-directory>
You can also enable retention by using the argument journal-retention on the `artemis create` command -->
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-device-block-size>4096</journal-device-block-size>
<journal-file-size>10M</journal-file-size>
<!--
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
<network-check-NIC>theNicName</network-check-NIC>
-->
<!--
Use this to use an HTTP server to validate the network
<network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
<!-- <network-check-period>10000</network-check-period> -->
<!-- <network-check-timeout>1000</network-check-timeout> -->
<!-- this is a comma separated list, no spaces, just DNS or IPs
it should accept IPV6
Warning: Make sure you understand your network topology as this is meant to validate if your network is valid.
Using IPs that could eventually disappear or be partially visible may defeat the purpose.
You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
<!-- <network-check-list>10.0.0.1</network-check-list> -->
<!-- use this to customize the ping used for ipv4 addresses -->
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
<!-- use this to customize the ping used for ipv6 addresses -->
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
that won't support flow control. -->
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<!-- the system will enter into page mode once you hit this limit. This is an estimate in bytes of how much the messages are using in memory
The system will use half of the available memory (-Xmx) by default for the global-max-size.
You may specify a different value here if you need to customize it to your needs.
<global-max-size>100Mb</global-max-size> -->
<!-- the maximum number of messages accepted before entering full address mode.
if global-max-size is specified the full address mode will be specified by whatever hits it first. -->
<global-max-messages>-1</global-max-messages>
<acceptors>
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
<!-- amqpCredits: The number of credits sent to AMQP producers -->
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
<!-- amqpDuplicateDetection: If you are not using duplicate detection, set this to false
as duplicate detection requires applicationProperties to be parsed on the server. -->
<!-- amqpMinLargeMessageSize: Determines how many bytes are considered large, so we start using files to hold their data.
default: 102400, -1 would mean to disable large mesasge control -->
<!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
"anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->
<!-- Acceptor for every supported protocol -->
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
<acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
</acceptors>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq"/>
<permission type="deleteNonDurableQueue" roles="amq"/>
<permission type="createDurableQueue" roles="amq"/>
<permission type="deleteDurableQueue" roles="amq"/>
<permission type="createAddress" roles="amq"/>
<permission type="deleteAddress" roles="amq"/>
<permission type="consume" roles="amq"/>
<permission type="browse" roles="amq"/>
<permission type="send" roles="amq"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- if max-size-bytes and max-size-messages were both enabled, the system will enter into paging
based on the first attribute to hits the maximum value -->
<!-- limit for the address in bytes, -1 means unlimited -->
<max-size-bytes>-1</max-size-bytes>
<!-- limit for the address in messages, -1 means unlimited -->
<max-size-messages>-1</max-size-messages>
<!-- the size of each file on paging. Notice we keep files in memory while they are in use.
Lower this setting if you have too many queues in memory. -->
<page-size-bytes>10M</page-size-bytes>
<!-- limit how many messages are read from paging into the Queue. -->
<max-read-page-messages>-1</max-read-page-messages>
<!-- limit how much memory is read from paging into the Queue. -->
<max-read-page-bytes>20M</max-read-page-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-delete-queues>false</auto-delete-queues>
<auto-delete-addresses>false</auto-delete-addresses>
</address-setting>
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
<!-- Uncomment the following if you want to use the Standard LoggingActiveMQServerPlugin pluging to log in events
<broker-plugins>
<broker-plugin class-name="org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin">
<property key="LOG_ALL_EVENTS" value="true"/>
<property key="LOG_CONNECTION_EVENTS" value="true"/>
<property key="LOG_SESSION_EVENTS" value="true"/>
<property key="LOG_CONSUMER_EVENTS" value="true"/>
<property key="LOG_DELIVERING_EVENTS" value="true"/>
<property key="LOG_SENDING_EVENTS" value="true"/>
<property key="LOG_INTERNAL_EVENTS" value="true"/>
</broker-plugin>
</broker-plugins>
-->
</core>
</configuration>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<!-- This policy file controls the Jolokia JMX-HTTP bridge security options for the web console.
see: https://jolokia.org/reference/html/security.html -->
<restrict>
<cors>
<!-- Allow cross origin access from localhost ... -->
<allow-origin>*://localhost*</allow-origin>
<!-- Options from this point on are auto-generated by Create.java from the Artemis CLI -->
<!-- Check for the proper origin on the server side, too -->
<strict-checking/>
</cors>
</restrict>

View File

@ -0,0 +1,90 @@
#
# 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.
#
# Additional logger names to configure (root logger is always configured)
# Root logger option
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.utils.critical,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource,org.apache.curator,org.apache.zookeeper
# Root logger level
logger.level=INFO
# ActiveMQ Artemis logger levels
logger.org.apache.activemq.artemis.core.server.level=INFO
logger.org.apache.activemq.artemis.journal.level=INFO
logger.org.apache.activemq.artemis.utils.level=INFO
# if you have issues with CriticalAnalyzer, setting this as TRACE would give you extra troubleshooting information.
# but do not use it regularly as it would incur in some extra CPU usage for this diagnostic.
logger.org.apache.activemq.artemis.utils.critical.level=INFO
logger.org.apache.activemq.artemis.jms.level=INFO
logger.org.apache.activemq.artemis.integration.bootstrap.level=INFO
logger.org.eclipse.jetty.level=WARN
# Root logger handlers
logger.handlers=FILE,CONSOLE
# quorum logger levels
logger.org.apache.curator.level=WARN
logger.org.apache.zookeeper.level=ERROR
# to enable audit change the level to INFO
logger.org.apache.activemq.audit.base.level=ERROR
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.base.useParentHandlers=false
logger.org.apache.activemq.audit.resource.level=ERROR
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.resource.useParentHandlers=false
logger.org.apache.activemq.audit.message.level=ERROR
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.message.useParentHandlers=false
# Console handler configuration
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
handler.CONSOLE.properties=autoFlush
handler.CONSOLE.level=DEBUG
handler.CONSOLE.autoFlush=true
handler.CONSOLE.formatter=PATTERN
# File handler configuration
handler.FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
handler.FILE.level=DEBUG
handler.FILE.properties=suffix,append,autoFlush,fileName
handler.FILE.suffix=.yyyy-MM-dd
handler.FILE.append=true
handler.FILE.autoFlush=true
handler.FILE.fileName=${artemis.instance}/log/artemis.log
handler.FILE.formatter=PATTERN
# Formatter pattern configuration
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.PATTERN.properties=pattern
formatter.PATTERN.pattern=%d %-5p [%c] %s%E%n
#Audit logger
handler.AUDIT_FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
handler.AUDIT_FILE.level=INFO
handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
handler.AUDIT_FILE.append=true
handler.AUDIT_FILE.autoFlush=true
handler.AUDIT_FILE.fileName=${artemis.instance}/log/audit.log
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.AUDIT_PATTERN.properties=pattern
formatter.AUDIT_PATTERN.pattern=%d [AUDIT](%t) %s%E%n

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
activemq {
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
debug=false
reload=true
org.apache.activemq.jaas.properties.user="artemis-users.properties"
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
debug=false
org.apache.activemq.jaas.guest.user="y"
org.apache.activemq.jaas.guest.role="amq";
};

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ 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.
-->
<management-context xmlns="http://activemq.apache.org/schema">
<!--<connector connector-port="1099"/>-->
<authorisation>
<allowlist>
<entry domain="hawtio"/>
</allowlist>
<default-access>
<access method="list*" roles="amq"/>
<access method="get*" roles="amq"/>
<access method="is*" roles="amq"/>
<access method="set*" roles="amq"/>
<access method="*" roles="amq"/>
</default-access>
<role-access>
<match domain="org.apache.activemq.artemis">
<access method="list*" roles="amq"/>
<access method="get*" roles="amq"/>
<access method="is*" roles="amq"/>
<access method="set*" roles="amq"/>
<!-- Note count and browse are need to access the browse tab in the console-->
<access method="browse*" roles="amq"/>
<access method="count*" roles="amq"/>
<access method="*" roles="amq"/>
</match>
<!--example of how to configure a specific object-->
<!--<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
<access method="list*" roles="view,update,amq"/>
<access method="get*" roles="view,update,amq"/>
<access method="is*" roles="view,update,amq"/>
<access method="set*" roles="update,amq"/>
<access method="*" roles="amq"/>
</match>-->
</role-access>
</authorisation>
</management-context>

View File

@ -0,0 +1,24 @@
#!/usr/bin/env sh
# 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.
## I removed everything from this file, except to the line that matters.
## the upgrade should keep this line in the new script
ARTEMIS_INSTANCE_ETC='${project.basedir}/target/classes/servers/toUpgradeETC'

View File

@ -0,0 +1,158 @@
#!/usr/bin/env sh
# 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.
service=`basename "$0"`
#
# Discover the ARTEMIS_INSTANCE from the location of this script.
#
if [ -z "$ARTEMIS_INSTANCE" ] ; then
## resolve links - $0 may be a link to ActiveMQ's home
PRG="$0"
saveddir=`pwd`
# need this for relative symlinks
dirname_prg=`dirname "$PRG"`
cd "$dirname_prg"
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '.*/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
ARTEMIS_INSTANCE=`dirname "$PRG"`
cd "$saveddir"
# make it fully qualified
ARTEMIS_INSTANCE=`cd "$ARTEMIS_INSTANCE/.." && pwd`
export ARTEMIS_INSTANCE
fi
PID_FILE="${ARTEMIS_INSTANCE}/data/artemis.pid"
if [ ! -d "${ARTEMIS_INSTANCE}/data/" ]; then
mkdir "${ARTEMIS_INSTANCE}/data/"
fi
status() {
if [ -f "${PID_FILE}" ] ; then
pid=`cat "${PID_FILE}"`
# check to see if it's gone...
ps -p ${pid} > /dev/null
if [ $? -eq 0 ] ; then
return 0
else
rm "${PID_FILE}"
return 3
fi
fi
return 3
}
stop() {
if [ -f "${PID_FILE}" ] ; then
pid=`cat "${PID_FILE}"`
kill $@ ${pid} > /dev/null
fi
for i in 1 2 3 4 5 ; do
status
if [ $? -ne 0 ] ; then
return 0
fi
sleep 1
done
echo "Could not stop process ${pid}"
return 1
}
start() {
status
if [ $? -eq 0 ] ; then
echo "Already running."
return 1
fi
if [ -z "$ARTEMIS_USER" -o `id -un` = "$ARTEMIS_USER" ] ; then
nohup "${ARTEMIS_INSTANCE}/bin/artemis" run > /dev/null 2> /dev/null &
else
sudo -n -u ${ARTEMIS_USER} nohup "${ARTEMIS_INSTANCE}/bin/artemis" run > /dev/null 2> /dev/null &
fi
echo $! > "${PID_FILE}"
# check to see if stays up...
sleep 1
status
if [ $? -ne 0 ] ; then
echo "Could not start ${service}"
return 1
fi
echo "${service} is now running (${pid})"
return 0
}
case $1 in
start)
echo "Starting ${service}"
start
exit $?
;;
force-stop)
echo "Forcibly Stopping ${service}"
stop -9
exit $?
;;
stop)
echo "Gracefully Stopping ${service}"
stop
exit $?
;;
restart)
echo "Restarting ${service}"
stop
start
exit $?
;;
status)
status
rc=$?
if [ $rc -eq 0 ] ; then
echo "${service} is running (${pid})"
else
echo "${service} is stopped"
fi
exit $rc
;;
*)
echo "Usage: $0 {start|stop|restart|force-stop|status}" >&2
exit 2
;;
esac

View File

@ -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.
-->
<service>
<id>artemis-windows-0.0.0.0</id>
<name>ActiveMQ Artemis: windows @ 0.0.0.0</name>
<description>Apache ActiveMQ Artemis is a reliable messaging broker</description>
<env name="ARTEMIS_HOME" value="must-change"/>
<env name="ARTEMIS_INSTANCE" value="no-change"/>
<env name="ARTEMIS_INSTANCE_ETC" value="${project.basedir}/target/classes/servers/windowsETC"/>
<env name="ARTEMIS_INSTANCE_URI" value="file:/no-change"/>
<env name="ARTEMIS_INSTANCE_ETC_URI" value="file:${project.basedir}/target/classes/servers/windowsETC"/>
<env name="ARTEMIS_DATA_DIR" value="no-change"/>
<logpath>/must-be/servers/windows\log</logpath>
<logmode>roll</logmode>
<executable>%JAVA_HOME%\bin\java.exe</executable>
<startargument>-XX:+UseParallelGC</startargument>
<startargument>-Xms512M</startargument>
<startargument>-Xmx1024M</startargument>
<!-- Cluster Properties: Used to pass startarguments to ActiveMQ Artemis which can be referenced in broker.xml
<startargument>-Dartemis.remoting.default.port=61617</startargument>
<startargument>-Dartemis.remoting.amqp.port=5673</startargument>
<startargument>-Dartemis.remoting.stomp.port=61614</startargument>
<startargument>-Dartemis.remoting.hornetq.port=5446</startargument>
-->
<startargument>-classpath</startargument>
<startargument>%ARTEMIS_HOME%\lib\artemis-boot.jar</startargument>
<startargument>-Dartemis.home=%ARTEMIS_HOME%</startargument>
<startargument>-Dartemis.instance=%ARTEMIS_INSTANCE%</startargument>
<startargument>-Ddata.dir=%ARTEMIS_DATA_DIR%</startargument>
<startargument>-Dartemis.instance.etc=%ARTEMIS_INSTANCE_ETC%</startargument>
<startargument>-Djava.security.auth.login.config=%ARTEMIS_INSTANCE_ETC%\login.config</startargument>
<startargument>-Dhawtio.disableProxy=true</startargument>
<startargument>-Dhawtio.realm=activemq</startargument>
<startargument>-Dhawtio.offline="true"</startargument>
<startargument>-Dhawtio.role=amq</startargument>
<startargument>-Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal</startargument>
<startargument>-Djolokia.policyLocation=%ARTEMIS_INSTANCE_ETC_URI%/jolokia-access.xml</startargument>
<!-- Debug args: Uncomment to enable debug
<startargument>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005</startargument>
-->
<startargument>org.apache.activemq.artemis.boot.Artemis</startargument>
<startargument>run</startargument>
<stopexecutable>%JAVA_HOME%\bin\java.exe</stopexecutable>
<stopargument>-XX:+UseParallelGC</stopargument>
<stopargument>-Xms512M</stopargument>
<stopargument>-Xmx1024M</stopargument>
<stopargument>-classpath</stopargument>
<stopargument>%ARTEMIS_HOME%\lib\artemis-boot.jar</stopargument>
<stopargument>-Dartemis.home=%ARTEMIS_HOME%</stopargument>
<stopargument>-Dartemis.instance=%ARTEMIS_INSTANCE%</stopargument>
<stopargument>-Ddata.dir=%ARTEMIS_DATA_DIR%</stopargument>
<stopargument>-Dartemis.instance.etc="%ARTEMIS_INSTANCE_ETC%"</stopargument>
<stopargument>org.apache.activemq.artemis.boot.Artemis</stopargument>
<stopargument>stop</stopargument>
</service>

View File

@ -0,0 +1,76 @@
@echo off
rem Licensed to the Apache Software Foundation (ASF) under one
rem or more contributor license agreements. See the NOTICE file
rem distributed with this work for additional information
rem regarding copyright ownership. The ASF licenses this file
rem to you under the Apache License, Version 2.0 (the
rem "License"); you may not use this file except in compliance
rem with the License. You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing,
rem software distributed under the License is distributed on an
rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
rem KIND, either express or implied. See the License for the
rem specific language governing permissions and limitations
rem under the License.
setlocal
if NOT "%ARTEMIS_INSTANCE%"=="" goto CHECK_ARTEMIS_INSTANCE
set ARTEMIS_INSTANCE="%~dp0.."
:CHECK_ARTEMIS_INSTANCE
if exist %ARTEMIS_INSTANCE%\bin\artemis.cmd goto CHECK_JAVA
:NO_HOME
echo ARTEMIS_INSTANCE environment variable is set incorrectly. Please set ARTEMIS_INSTANCE.
goto END
:CHECK_JAVA
set _JAVACMD=%JAVACMD%
if "%JAVA_HOME%" == "" goto NO_JAVA_HOME
if not exist "%JAVA_HOME%\bin\java.exe" goto NO_JAVA_HOME
if "%_JAVACMD%" == "" set _JAVACMD=%JAVA_HOME%\bin\java.exe
goto RUN_JAVA
:NO_JAVA_HOME
if "%_JAVACMD%" == "" set _JAVACMD=java.exe
echo.
echo Warning: JAVA_HOME environment variable is not set.
echo.
:RUN_JAVA
rem "Load Profile Config"
set ARTEMIS_INSTANCE_ETC="${project.basedir}/target/classes/servers/windowsETC"
call %ARTEMIS_INSTANCE_ETC%\artemis.profile.cmd %*
if not exist %ARTEMIS_OOME_DUMP% goto NO_ARTEMIS_OOME_DUMP
rem "Backup the last OOME heap dump"
move /Y %ARTEMIS_OOME_DUMP% %ARTEMIS_OOME_DUMP%.bkp
:NO_ARTEMIS_OOME_DUMP
rem "Create full JVM Args"
set JVM_ARGS=%JAVA_ARGS%
if not "%ARTEMIS_CLUSTER_PROPS%"=="" set JVM_ARGS=%JVM_ARGS% %ARTEMIS_CLUSTER_PROPS%
set JVM_ARGS=%JVM_ARGS% -classpath %ARTEMIS_HOME%\lib\artemis-boot.jar
set JVM_ARGS=%JVM_ARGS% -Dartemis.home=%ARTEMIS_HOME%
set JVM_ARGS=%JVM_ARGS% -Dartemis.instance=%ARTEMIS_INSTANCE%
set JVM_ARGS=%JVM_ARGS% -Ddata.dir=%ARTEMIS_DATA_DIR%
set JVM_ARGS=%JVM_ARGS% -Dartemis.instance.etc=%ARTEMIS_INSTANCE_ETC%
set JVM_ARGS=%JVM_ARGS% -Dartemis.default.sensitive.string.codec.key=%ARTEMIS_DEFAULT_SENSITIVE_STRING_CODEC_KEY%
if not "%DEBUG_ARGS%"=="" set JVM_ARGS=%JVM_ARGS% %DEBUG_ARGS%
if not "%$JAVA_ARGS_APPEND%"=="" set JVM_ARGS=%JVM_ARGS% %$JAVA_ARGS_APPEND%
"%_JAVACMD%" %JVM_ARGS% org.apache.activemq.artemis.boot.Artemis %*
:END
endlocal
GOTO :EOF
:EOF

View File

@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
amq = y

View File

@ -0,0 +1,18 @@
## ---------------------------------------------------------------------------
## 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.
## ---------------------------------------------------------------------------
y = ENC(1024:F2B5A875934D0DA88F3E7416FA616418DB802AB1B0F8925B2C2A93BDC0AD57B4:A9A5D72B87731DA5CB02F8317028B526032240EC26C371B8DEF771CF0BC4805FB10DD5A9BBAEE9F984300EDB03C4A5018D7A4FE3680A98B4CCF57E79C347EF43)

View File

@ -0,0 +1,50 @@
@echo off
rem Licensed to the Apache Software Foundation (ASF) under one
rem or more contributor license agreements. See the NOTICE file
rem distributed with this work for additional information
rem regarding copyright ownership. The ASF licenses this file
rem to you under the Apache License, Version 2.0 (the
rem "License"); you may not use this file except in compliance
rem with the License. You may obtain a copy of the License at
rem
rem http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing,
rem software distributed under the License is distributed on an
rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
rem KIND, either express or implied. See the License for the
rem specific language governing permissions and limitations
rem under the License.
set ARTEMIS_HOME="must-change"
set ARTEMIS_INSTANCE="no-change"
set ARTEMIS_DATA_DIR="no-change"
set ARTEMIS_ETC_DIR="no-change"
set ARTEMIS_OOME_DUMP="no-change"
rem The logging config will need an URI
rem this will be encoded in case you use spaces or special characters
rem on your directory structure
set ARTEMIS_INSTANCE_URI="file:/no-change/"
set ARTEMIS_INSTANCE_ETC_URI="file:/no-change/"
rem Cluster Properties: Used to pass arguments to ActiveMQ Artemis which can be referenced in broker.xml
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
IF "%JAVA_ARGS%"=="" (set JAVA_ARGS= -XX:AutoBoxCacheMax=20000 -XX:+PrintClassHistogram -XX:+UseG1GC -XX:+UseStringDeduplication -Xms512M -Xmx2G -Djava.security.auth.login.config=%ARTEMIS_ETC_DIR%\login.config -Dhawtio.disableProxy=true -Dhawtio.offline=true -Dhawtio.realm=activemq -Dhawtio.role=amq -Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal -Djolokia.policyLocation=%ARTEMIS_INSTANCE_ETC_URI%\jolokia-access.xml -Dartemis.instance=%ARTEMIS_INSTANCE%)
rem Logs Safepoints JVM pauses: Uncomment to enable them
rem In addition to the traditional GC logs you could enable some JVM flags to know any meaningful and "hidden" pause that could
rem affect the latencies of the services delivered by the broker, including those that are not reported by the classic GC logs
rem and dependent by JVM background work (eg method deoptimizations, lock unbiasing, JNI, counted loops and obviously GC activity).
rem Replace "all_pauses.log" with the file name you want to log to.
rem set JAVA_ARGS=%JAVA_ARGS% -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+LogVMOutput -XX:LogFile=all_pauses.log
rem Enables the dumping of the java heap when a java.lang.OutOfMemoryError exception is thrown.
rem set JAVA_ARGS=%JAVA_ARGS% -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=%ARTEMIS_OOME_DUMP%
rem Only enable debug options for the 'run' command
rem Uncomment to enable remote debugging
rem if "%1"=="run" set DEBUG_ARGS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ 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.
-->
<broker xmlns="http://activemq.apache.org/schema">
<jaas-security domain="activemq"/>
<!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
This is to avoid situations where you could have spaces or special characters on this URI -->
<server configuration="file:/no-change/broker.xml"/>
<!-- The web server is only bound to localhost by default -->
<web path="web" rootRedirectLocation="console">
<binding uri="http://localhost:8161">
<app url="activemq-branding" war="activemq-branding.war"/>
<app url="artemis-plugin" war="artemis-plugin.war"/>
<app url="console" war="console.war"/>
</binding>
</web>
</broker>

View File

@ -0,0 +1,254 @@
<?xml version='1.0'?>
<!--
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.
-->
<configuration xmlns="urn:activemq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
<core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:activemq:core ">
<name>0.0.0.0</name>
<persistence-enabled>true</persistence-enabled>
<!-- this could be ASYNCIO, MAPPED, NIO
ASYNCIO: Linux Libaio
MAPPED: mmap files
NIO: Plain Java Files
-->
<journal-type>NIO</journal-type>
<paging-directory>data/paging</paging-directory>
<bindings-directory>data/bindings</bindings-directory>
<journal-directory>data/journal</journal-directory>
<large-messages-directory>data/large-messages</large-messages-directory>
<!-- if you want to retain your journal uncomment this following configuration.
This will allow your system to keep 7 days of your data, up to 10G. Tweak it accordingly to your use case and capacity.
it is recommended to use a separate storage unit from the journal for performance considerations.
<journal-retention-directory period="7" unit="DAYS" storage-limit="10G">data/retention</journal-retention-directory>
You can also enable retention by using the argument journal-retention on the `artemis create` command -->
<journal-datasync>true</journal-datasync>
<journal-min-files>2</journal-min-files>
<journal-pool-files>10</journal-pool-files>
<journal-device-block-size>4096</journal-device-block-size>
<journal-file-size>10M</journal-file-size>
<!--
You can verify the network health of a particular NIC by specifying the <network-check-NIC> element.
<network-check-NIC>theNicName</network-check-NIC>
-->
<!--
Use this to use an HTTP server to validate the network
<network-check-URL-list>http://www.apache.org</network-check-URL-list> -->
<!-- <network-check-period>10000</network-check-period> -->
<!-- <network-check-timeout>1000</network-check-timeout> -->
<!-- this is a comma separated list, no spaces, just DNS or IPs
it should accept IPV6
Warning: Make sure you understand your network topology as this is meant to validate if your network is valid.
Using IPs that could eventually disappear or be partially visible may defeat the purpose.
You can use a list of multiple IPs, and if any successful ping will make the server OK to continue running -->
<!-- <network-check-list>10.0.0.1</network-check-list> -->
<!-- use this to customize the ping used for ipv4 addresses -->
<!-- <network-check-ping-command>ping -c 1 -t %d %s</network-check-ping-command> -->
<!-- use this to customize the ping used for ipv6 addresses -->
<!-- <network-check-ping6-command>ping6 -c 1 %2$s</network-check-ping6-command> -->
<!-- how often we are looking for how many bytes are being used on the disk in ms -->
<disk-scan-period>5000</disk-scan-period>
<!-- once the disk hits this limit the system will block, or close the connection in certain protocols
that won't support flow control. -->
<max-disk-usage>90</max-disk-usage>
<!-- should the broker detect dead locks and other issues -->
<critical-analyzer>true</critical-analyzer>
<critical-analyzer-timeout>120000</critical-analyzer-timeout>
<critical-analyzer-check-period>60000</critical-analyzer-check-period>
<critical-analyzer-policy>HALT</critical-analyzer-policy>
<!-- the system will enter into page mode once you hit this limit. This is an estimate in bytes of how much the messages are using in memory
The system will use half of the available memory (-Xmx) by default for the global-max-size.
You may specify a different value here if you need to customize it to your needs.
<global-max-size>100Mb</global-max-size> -->
<!-- the maximum number of messages accepted before entering full address mode.
if global-max-size is specified the full address mode will be specified by whatever hits it first. -->
<global-max-messages>-1</global-max-messages>
<acceptors>
<!-- useEpoll means: it will use Netty epoll if you are on a system (Linux) that supports it -->
<!-- amqpCredits: The number of credits sent to AMQP producers -->
<!-- amqpLowCredits: The server will send the # credits specified at amqpCredits at this low mark -->
<!-- amqpDuplicateDetection: If you are not using duplicate detection, set this to false
as duplicate detection requires applicationProperties to be parsed on the server. -->
<!-- amqpMinLargeMessageSize: Determines how many bytes are considered large, so we start using files to hold their data.
default: 102400, -1 would mean to disable large mesasge control -->
<!-- Note: If an acceptor needs to be compatible with HornetQ and/or Artemis 1.x clients add
"anycastPrefix=jms.queue.;multicastPrefix=jms.topic." to the acceptor url.
See https://issues.apache.org/jira/browse/ARTEMIS-1644 for more information. -->
<!-- Acceptor for every supported protocol -->
<acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
<!-- AMQP Acceptor. Listens on default AMQP port for AMQP traffic.-->
<acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
<!-- STOMP Acceptor. -->
<acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
<!-- HornetQ Compatibility Acceptor. Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
<acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
<!-- MQTT Acceptor -->
<acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
</acceptors>
<security-settings>
<security-setting match="#">
<permission type="createNonDurableQueue" roles="amq"/>
<permission type="deleteNonDurableQueue" roles="amq"/>
<permission type="createDurableQueue" roles="amq"/>
<permission type="deleteDurableQueue" roles="amq"/>
<permission type="createAddress" roles="amq"/>
<permission type="deleteAddress" roles="amq"/>
<permission type="consume" roles="amq"/>
<permission type="browse" roles="amq"/>
<permission type="send" roles="amq"/>
<!-- we need this otherwise ./artemis data imp wouldn't work -->
<permission type="manage" roles="amq"/>
</security-setting>
</security-settings>
<address-settings>
<!-- if you define auto-create on certain queues, management has to be auto-create -->
<address-setting match="activemq.management#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- with -1 only the global-max-size is in use for limiting -->
<max-size-bytes>-1</max-size-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
</address-setting>
<!--default for catch all-->
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<expiry-address>ExpiryQueue</expiry-address>
<redelivery-delay>0</redelivery-delay>
<!-- if max-size-bytes and max-size-messages were both enabled, the system will enter into paging
based on the first attribute to hits the maximum value -->
<!-- limit for the address in bytes, -1 means unlimited -->
<max-size-bytes>-1</max-size-bytes>
<!-- limit for the address in messages, -1 means unlimited -->
<max-size-messages>-1</max-size-messages>
<!-- the size of each file on paging. Notice we keep files in memory while they are in use.
Lower this setting if you have too many queues in memory. -->
<page-size-bytes>10M</page-size-bytes>
<!-- limit how many messages are read from paging into the Queue. -->
<max-read-page-messages>-1</max-read-page-messages>
<!-- limit how much memory is read from paging into the Queue. -->
<max-read-page-bytes>20M</max-read-page-bytes>
<message-counter-history-day-limit>10</message-counter-history-day-limit>
<address-full-policy>PAGE</address-full-policy>
<auto-create-queues>true</auto-create-queues>
<auto-create-addresses>true</auto-create-addresses>
<auto-delete-queues>false</auto-delete-queues>
<auto-delete-addresses>false</auto-delete-addresses>
</address-setting>
</address-settings>
<addresses>
<address name="DLQ">
<anycast>
<queue name="DLQ" />
</anycast>
</address>
<address name="ExpiryQueue">
<anycast>
<queue name="ExpiryQueue" />
</anycast>
</address>
</addresses>
<!-- Uncomment the following if you want to use the Standard LoggingActiveMQServerPlugin pluging to log in events
<broker-plugins>
<broker-plugin class-name="org.apache.activemq.artemis.core.server.plugin.impl.LoggingActiveMQServerPlugin">
<property key="LOG_ALL_EVENTS" value="true"/>
<property key="LOG_CONNECTION_EVENTS" value="true"/>
<property key="LOG_SESSION_EVENTS" value="true"/>
<property key="LOG_CONSUMER_EVENTS" value="true"/>
<property key="LOG_DELIVERING_EVENTS" value="true"/>
<property key="LOG_SENDING_EVENTS" value="true"/>
<property key="LOG_INTERNAL_EVENTS" value="true"/>
</broker-plugin>
</broker-plugins>
-->
</core>
</configuration>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<!-- This policy file controls the Jolokia JMX-HTTP bridge security options for the web console.
see: https://jolokia.org/reference/html/security.html -->
<restrict>
<cors>
<!-- Allow cross origin access from localhost ... -->
<allow-origin>*://localhost*</allow-origin>
<!-- Options from this point on are auto-generated by Create.java from the Artemis CLI -->
<!-- Check for the proper origin on the server side, too -->
<strict-checking/>
</cors>
</restrict>

View File

@ -0,0 +1,90 @@
#
# 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.
#
# Additional logger names to configure (root logger is always configured)
# Root logger option
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.utils.critical,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource,org.apache.curator,org.apache.zookeeper
# Root logger level
logger.level=INFO
# ActiveMQ Artemis logger levels
logger.org.apache.activemq.artemis.core.server.level=INFO
logger.org.apache.activemq.artemis.journal.level=INFO
logger.org.apache.activemq.artemis.utils.level=INFO
# if you have issues with CriticalAnalyzer, setting this as TRACE would give you extra troubleshooting information.
# but do not use it regularly as it would incur in some extra CPU usage for this diagnostic.
logger.org.apache.activemq.artemis.utils.critical.level=INFO
logger.org.apache.activemq.artemis.jms.level=INFO
logger.org.apache.activemq.artemis.integration.bootstrap.level=INFO
logger.org.eclipse.jetty.level=WARN
# Root logger handlers
logger.handlers=FILE,CONSOLE
# quorum logger levels
logger.org.apache.curator.level=WARN
logger.org.apache.zookeeper.level=ERROR
# to enable audit change the level to INFO
logger.org.apache.activemq.audit.base.level=ERROR
logger.org.apache.activemq.audit.base.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.base.useParentHandlers=false
logger.org.apache.activemq.audit.resource.level=ERROR
logger.org.apache.activemq.audit.resource.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.resource.useParentHandlers=false
logger.org.apache.activemq.audit.message.level=ERROR
logger.org.apache.activemq.audit.message.handlers=AUDIT_FILE
logger.org.apache.activemq.audit.message.useParentHandlers=false
# Console handler configuration
handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
handler.CONSOLE.properties=autoFlush
handler.CONSOLE.level=DEBUG
handler.CONSOLE.autoFlush=true
handler.CONSOLE.formatter=PATTERN
# File handler configuration
handler.FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
handler.FILE.level=DEBUG
handler.FILE.properties=suffix,append,autoFlush,fileName
handler.FILE.suffix=.yyyy-MM-dd
handler.FILE.append=true
handler.FILE.autoFlush=true
handler.FILE.fileName=${artemis.instance}/log/artemis.log
handler.FILE.formatter=PATTERN
# Formatter pattern configuration
formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.PATTERN.properties=pattern
formatter.PATTERN.pattern=%d %-5p [%c] %s%E%n
#Audit logger
handler.AUDIT_FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
handler.AUDIT_FILE.level=INFO
handler.AUDIT_FILE.properties=suffix,append,autoFlush,fileName
handler.AUDIT_FILE.suffix=.yyyy-MM-dd
handler.AUDIT_FILE.append=true
handler.AUDIT_FILE.autoFlush=true
handler.AUDIT_FILE.fileName=${artemis.instance}/log/audit.log
handler.AUDIT_FILE.formatter=AUDIT_PATTERN
formatter.AUDIT_PATTERN=org.jboss.logmanager.formatters.PatternFormatter
formatter.AUDIT_PATTERN.properties=pattern
formatter.AUDIT_PATTERN.pattern=%d [AUDIT](%t) %s%E%n

View File

@ -0,0 +1,29 @@
/*
* 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.
*/
activemq {
org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
debug=false
reload=true
org.apache.activemq.jaas.properties.user="artemis-users.properties"
org.apache.activemq.jaas.properties.role="artemis-roles.properties";
org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
debug=false
org.apache.activemq.jaas.guest.user="y"
org.apache.activemq.jaas.guest.role="amq";
};

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ 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.
-->
<management-context xmlns="http://activemq.apache.org/schema">
<!--<connector connector-port="1099"/>-->
<authorisation>
<allowlist>
<entry domain="hawtio"/>
</allowlist>
<default-access>
<access method="list*" roles="amq"/>
<access method="get*" roles="amq"/>
<access method="is*" roles="amq"/>
<access method="set*" roles="amq"/>
<access method="*" roles="amq"/>
</default-access>
<role-access>
<match domain="org.apache.activemq.artemis">
<access method="list*" roles="amq"/>
<access method="get*" roles="amq"/>
<access method="is*" roles="amq"/>
<access method="set*" roles="amq"/>
<!-- Note count and browse are need to access the browse tab in the console-->
<access method="browse*" roles="amq"/>
<access method="count*" roles="amq"/>
<access method="*" roles="amq"/>
</match>
<!--example of how to configure a specific object-->
<!--<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
<access method="list*" roles="view,update,amq"/>
<access method="get*" roles="view,update,amq"/>
<access method="is*" roles="view,update,amq"/>
<access method="set*" roles="update,amq"/>
<access method="*" roles="amq"/>
</match>-->
</role-access>
</authorisation>
</management-context>

View File

@ -0,0 +1,145 @@
/*
* 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.tests.smoke.upgradeTest;
import java.io.File;
import java.lang.invoke.MethodHandles;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** This test will compare expected values at the upgraded servers. */
public class CompareUpgradeTest {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public static final String basedir = System.getProperty("basedir");
@Test
public void testWindows() throws Exception {
String windowsBin = basedir + "/target/classes/servers/windows/bin";
String windowsETC = basedir + "/target/classes/servers/windowsETC";
checkExpectedValues(windowsBin + "/artemis.cmd", "set ARTEMIS_INSTANCE_ETC=", "\"" + windowsETC + "\"");
Map<String, String> result = checkExpectedValues(windowsBin + "/artemis-service.xml",
"<env name=\"ARTEMIS_HOME\" value=", null, // no expected value for this, we will check on the output
"<env name=\"ARTEMIS_INSTANCE\" value=", "\"no-change\"/>",
"<env name=\"ARTEMIS_INSTANCE_ETC\" value=", "\"" + windowsETC + "\"/>",
"<env name=\"ARTEMIS_INSTANCE_URI\" value=", "\"file:/no-change\"/>",
"<env name=\"ARTEMIS_DATA_DIR\" value=", "\"no-change\"/>"
);
String home = result.get("<env name=\"ARTEMIS_HOME\" value=");
Assert.assertNotNull(home);
Assert.assertFalse("home value must be changed during upgrade", home.contains("must-change"));
result = checkExpectedValues(windowsETC + "/artemis.profile.cmd",
"set ARTEMIS_HOME=", null, // no expected value for this, we will check on the output
"set ARTEMIS_INSTANCE=", "\"no-change\"",
"set ARTEMIS_DATA_DIR=", "\"no-change\"",
"set ARTEMIS_ETC_DIR=", "\"no-change\"",
"set ARTEMIS_OOME_DUMP=", "\"no-change\"",
"set ARTEMIS_INSTANCE_URI=", "\"file:/no-change/\"",
"set ARTEMIS_INSTANCE_ETC_URI=", "\"file:/no-change/\"");
home = result.get("set ARTEMIS_HOME=");
Assert.assertNotNull(home);
Assert.assertFalse("home value must be changed during upgrade", home.contains("must-change"));
checkExpectedValues(windowsETC + "/bootstrap.xml",
"<server configuration=", "\"file:/no-change/broker.xml\"/>");
File oldLogging = new File(windowsETC + "/logging.properties");
File newLogging = new File(windowsETC + "/log4j2.properties");
Assert.assertFalse("Old logging must be removed by upgrade", oldLogging.exists());
Assert.assertTrue("New Logging must be installed by upgrade", newLogging.exists());
}
@Test
public void testLinux() throws Exception {
String instanceDir = basedir + "/target/classes/servers/toUpgradeTest";
String bin = instanceDir + "/bin";
String etc = basedir + "/target/classes/servers/toUpgradeETC";
checkExpectedValues(bin + "/artemis", "ARTEMIS_INSTANCE_ETC=", "'" + etc + "'");
Map<String, String> result = checkExpectedValues(etc + "/artemis.profile",
"ARTEMIS_HOME=", null, // no expected value, will check on result
"ARTEMIS_INSTANCE=", "'" + instanceDir + "'",
"ARTEMIS_DATA_DIR=", "'" + instanceDir + "/data'",
"ARTEMIS_ETC_DIR=", "'" + etc + "'",
"ARTEMIS_OOME_DUMP=", "'" + instanceDir + "/log/oom_dump.hprof'",
"ARTEMIS_INSTANCE_URI=", "'file:" + instanceDir + "'",
"ARTEMIS_INSTANCE_ETC_URI=", "'file:" + etc + "'");
String home = result.get("ARTEMIS_HOME=");
Assert.assertNotNull(home);
Assert.assertNotEquals("'must-change'", home);
File oldLogging = new File(etc + "/logging.properties");
File newLogging = new File(etc + "/log4j2.properties");
Assert.assertFalse("Old logging must be removed by upgrade", oldLogging.exists());
Assert.assertTrue("New Logging must be installed by upgrade", newLogging.exists());
}
private Map<String, String> checkExpectedValues(String fileName, String... expectedPairs) throws Exception {
Assert.assertTrue("You must pass a pair of expected values", expectedPairs.length > 0 && expectedPairs.length % 2 == 0);
HashMap<String, String> expectedValues = new HashMap<>();
HashMap<String, String> matchingValues = new HashMap<>();
for (int i = 0; i < expectedPairs.length; i += 2) {
Assert.assertFalse("Value duplicated on pairs ::" + expectedPairs[i], expectedValues.containsKey(expectedPairs[i]));
expectedValues.put(expectedPairs[i], expectedPairs[i + 1]);
}
File file = new File(fileName);
Stream<String> lines = Files.lines(file.toPath());
lines.forEach(line -> {
String trimmedLine = line.trim();
expectedValues.forEach((key, value) -> {
if (trimmedLine.startsWith(key)) {
String actualValue = trimmedLine.substring(key.length());
logger.debug("match = {}", line);
matchingValues.put(key, actualValue);
if (value == null) {
logger.debug("no expected value was defined for {}, we will just fill out the matchingValues for further evaluation", key);
} else {
logger.debug("prefix={}, expecting={}, actualValue={}", key, value, actualValue);
Assert.assertEquals(key + " did not match", value, actualValue);
}
}
});
});
Assert.assertEquals("Some elements were not found in the output of " + fileName, matchingValues.size(), expectedValues.size());
return matchingValues;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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
* <br>
* http://www.apache.org/licenses/LICENSE-2.0
* <br>
* 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.tests.smoke.upgradeTest;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import java.io.File;
import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
import org.apache.activemq.artemis.tests.util.CFUtil;
import org.apache.activemq.artemis.util.ServerUtil;
import org.apache.activemq.artemis.utils.RandomUtil;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/** This test is making sure the upgrade command would be able to upgrade a test I created with artemis 2.25.0 */
public class UpgradeTest extends SmokeTestBase {
File upgradedServer;
Process processServer;
@Before
public void beforeTest() throws Exception {
upgradedServer = new File(basedir + "/target/classes/servers/toUpgradeTest");
deleteDirectory(new File(upgradedServer, "data"));
deleteDirectory(new File(upgradedServer, "log"));
processServer = ServerUtil.startServer(upgradedServer.getAbsolutePath(), "upgradedServer", 0, 5000);
addProcess(processServer);
}
@Test
public void testSimpleSendReceive() throws Throwable {
ConnectionFactory factory = CFUtil.createConnectionFactory("core", "tcp://localhost:61616");
try (Connection connection = factory.createConnection()) {
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(session.createQueue(getName()));
MessageProducer producer = session.createProducer(session.createQueue(getName()));
String randomString = "Hello " + RandomUtil.randomString();
producer.send(session.createTextMessage(randomString));
TextMessage message = (TextMessage)consumer.receive(5000);
Assert.assertNotNull(message);
Assert.assertEquals(randomString, message.getText());
}
}
}