You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2022/11/04 04:13:46 UTC
[activemq-artemis] branch main updated: ARTEMIS-4081 Upgrade command
This is an automated email from the ASF dual-hosted git repository.
clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
The following commit(s) were added to refs/heads/main by this push:
new 9c88fb4f88 ARTEMIS-4081 Upgrade command
9c88fb4f88 is described below
commit 9c88fb4f88ce1827d470ceee832e2efb4f5b3980
Author: Clebert Suconic <cl...@apache.org>
AuthorDate: Fri Oct 7 11:44:40 2022 -0400
ARTEMIS-4081 Upgrade command
This command will help updating the instance from a previous home
---
.../org/apache/activemq/artemis/cli/Artemis.java | 3 +-
.../activemq/artemis/cli/commands/Create.java | 220 +++++-------------
.../artemis/cli/commands/InstallAbstract.java | 176 ++++++++++++++
.../apache/activemq/artemis/cli/commands/Run.java | 18 ++
.../activemq/artemis/cli/commands/Upgrade.java | 237 +++++++++++++++++++
.../artemis/cli/commands/bin/artemis-service.xml | 4 +-
.../artemis/cli/commands/etc/artemis.profile | 2 +-
.../artemis/cli/commands/etc/artemis.profile.cmd | 2 +-
.../artemis/maven/ArtemisUpgradePlugin.java | 120 ++++++++++
docs/user-manual/en/upgrading.md | 28 ++-
docs/user-manual/en/versions.md | 2 +
tests/smoke-tests/pom.xml | 39 ++++
.../servers/toUpgradeETC/artemis-roles.properties | 18 ++
.../servers/toUpgradeETC/artemis-users.properties | 18 ++
.../servers/toUpgradeETC}/artemis.profile | 20 +-
.../servers/toUpgradeETC/bootstrap.xml | 39 ++++
.../servers/toUpgradeETC/broker.xml | 254 +++++++++++++++++++++
.../servers/toUpgradeETC/jolokia-access.xml | 35 +++
.../servers/toUpgradeETC/logging.properties | 90 ++++++++
.../servers/toUpgradeETC/login.config | 29 +++
.../servers/toUpgradeETC/management.xml | 52 +++++
.../servers/toUpgradeTest/bin/artemis | 24 ++
.../servers/toUpgradeTest/bin/artemis-service | 158 +++++++++++++
.../servers/windows}/bin/artemis-service.xml | 20 +-
.../servers/windows/bin/artemis.cmd | 76 ++++++
.../servers/windowsETC/artemis-roles.properties | 18 ++
.../servers/windowsETC/artemis-users.properties | 18 ++
.../servers/windowsETC}/artemis.profile.cmd | 16 +-
.../servers/windowsETC/bootstrap.xml | 39 ++++
.../servers/windowsETC/broker.xml | 254 +++++++++++++++++++++
.../servers/windowsETC/jolokia-access.xml | 35 +++
.../servers/windowsETC/logging.properties | 90 ++++++++
.../servers/windowsETC/login.config | 29 +++
.../servers/windowsETC/management.xml | 52 +++++
.../smoke/upgradeTest/CompareUpgradeTest.java | 145 ++++++++++++
.../tests/smoke/upgradeTest/UpgradeTest.java | 72 ++++++
36 files changed, 2250 insertions(+), 202 deletions(-)
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
index f58e56dcf0..31bd72ffd6 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/Artemis.java
@@ -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;
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
index 7aa2d7a75f..0e703dec3f 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Create.java
@@ -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 {
}
}
}
-}
+}
\ No newline at end of file
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InstallAbstract.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InstallAbstract.java
new file mode 100644
index 0000000000..8b3ed5bd01
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/InstallAbstract.java
@@ -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);
+ }
+
+
+}
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
index 62dc89e855..6c2f7e50a5 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Run.java
@@ -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("******************************************************************************************************************************************************************************");
+ }
+ }
+
}
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java
new file mode 100644
index 0000000000..d0e04e9047
--- /dev/null
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/cli/commands/Upgrade.java
@@ -0,0 +1,237 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.activemq.artemis.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");
+ }
+
+
+}
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml
index 0f7881b5e9..fc76661261 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml
@@ -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>
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile
index 56d8adf83e..e0b857fa26 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile
@@ -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}'
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd
index c4ebbff04a..0d7c1e5acb 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd
+++ b/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd
@@ -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}"
diff --git a/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisUpgradePlugin.java b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisUpgradePlugin.java
new file mode 100644
index 0000000000..1d21fee762
--- /dev/null
+++ b/artemis-maven-plugin/src/main/java/org/apache/activemq/artemis/maven/ArtemisUpgradePlugin.java
@@ -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());
+ }
+ }
+}
diff --git a/docs/user-manual/en/upgrading.md b/docs/user-manual/en/upgrading.md
index 4eddda3c76..e82c2eb30f 100644
--- a/docs/user-manual/en/upgrading.md
+++ b/docs/user-manual/en/upgrading.md
@@ -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.
+
diff --git a/docs/user-manual/en/versions.md b/docs/user-manual/en/versions.md
index 65f134181d..ba94c14714 100644
--- a/docs/user-manual/en/versions.md
+++ b/docs/user-manual/en/versions.md
@@ -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.
diff --git a/tests/smoke-tests/pom.xml b/tests/smoke-tests/pom.xml
index a2951950a6..1607bc60c7 100644
--- a/tests/smoke-tests/pom.xml
+++ b/tests/smoke-tests/pom.xml
@@ -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>
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-roles.properties b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-roles.properties
new file mode 100644
index 0000000000..ee6feea790
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-roles.properties
@@ -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
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-users.properties b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-users.properties
new file mode 100644
index 0000000000..47025bdaab
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis-users.properties
@@ -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)
\ No newline at end of file
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis.profile
similarity index 72%
copy from artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile
copy to tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis.profile
index 56d8adf83e..4f0539bae0 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/artemis.profile
@@ -15,17 +15,17 @@
# specific language governing permissions and limitations
# under the License.
-ARTEMIS_HOME='${artemis.home}'
-ARTEMIS_INSTANCE='${artemis.instance}'
-ARTEMIS_DATA_DIR='${artemis.instance.data}'
-ARTEMIS_ETC_DIR='${artemis.instance.etc}'
-ARTEMIS_OOME_DUMP='${artemis.instance.oome.dump}'
+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='${artemis.instance.uri}'
-ARTEMIS_INSTANCE_ETC_URI='${artemis.instance.etc.uri}'
+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"
@@ -33,11 +33,13 @@ ARTEMIS_INSTANCE_ETC_URI='${artemis.instance.etc.uri}'
# 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='${role}'
+HAWTIO_ROLE='amq'
# Java Opts
if [ -z "$JAVA_ARGS" ]; then
- JAVA_ARGS="-XX:AutoBoxCacheMax=20000 -XX:+PrintClassHistogram -XX:+UseG1GC -XX:+UseStringDeduplication -Xms512M -Xmx${java-memory} -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 ${java-opts}"
+ #### 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
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/bootstrap.xml b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/bootstrap.xml
new file mode 100644
index 0000000000..c16bcf9082
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/bootstrap.xml
@@ -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>
+
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/broker.xml b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/broker.xml
new file mode 100644
index 0000000000..c88da8e62f
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/broker.xml
@@ -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>
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/jolokia-access.xml b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/jolokia-access.xml
new file mode 100644
index 0000000000..679523f896
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/jolokia-access.xml
@@ -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>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/logging.properties b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/logging.properties
new file mode 100644
index 0000000000..97980b99c2
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/logging.properties
@@ -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
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/login.config b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/login.config
new file mode 100644
index 0000000000..bcdf92893f
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/login.config
@@ -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";
+};
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/management.xml b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/management.xml
new file mode 100644
index 0000000000..002ee95050
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeETC/management.xml
@@ -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>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis
new file mode 100755
index 0000000000..ebb92a0f78
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis
@@ -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'
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis-service b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis-service
new file mode 100755
index 0000000000..491f881a29
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/toUpgradeTest/bin/artemis-service
@@ -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
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml b/tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis-service.xml
similarity index 84%
copy from artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml
copy to tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis-service.xml
index 0f7881b5e9..e31e8db1e6 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/bin/artemis-service.xml
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis-service.xml
@@ -18,18 +18,18 @@
-->
<service>
- <id>artemis-${artemis.instance.name}-${host}</id>
- <name>ActiveMQ Artemis: ${artemis.instance.name} @ ${host}</name>
+ <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="${artemis.home}"/>
- <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}"/>
+ <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>${artemis.instance}\log</logpath>
+ <logpath>/must-be/servers/windows\log</logpath>
<logmode>roll</logmode>
<executable>%JAVA_HOME%\bin\java.exe</executable>
@@ -54,7 +54,7 @@
<startargument>-Dhawtio.disableProxy=true</startargument>
<startargument>-Dhawtio.realm=activemq</startargument>
<startargument>-Dhawtio.offline="true"</startargument>
- <startargument>-Dhawtio.role=${role}</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>
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis.cmd b/tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis.cmd
new file mode 100644
index 0000000000..299675660a
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windows/bin/artemis.cmd
@@ -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
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-roles.properties b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-roles.properties
new file mode 100644
index 0000000000..ee6feea790
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-roles.properties
@@ -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
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-users.properties b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-users.properties
new file mode 100644
index 0000000000..8d4122dc45
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis-users.properties
@@ -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)
\ No newline at end of file
diff --git a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis.profile.cmd
similarity index 71%
copy from artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd
copy to tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis.profile.cmd
index c4ebbff04a..0ea79ca86c 100644
--- a/artemis-cli/src/main/resources/org/apache/activemq/artemis/cli/commands/etc/artemis.profile.cmd
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/artemis.profile.cmd
@@ -16,24 +16,24 @@ 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="${artemis.home}"
-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}"
+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="${artemis.instance.uri.windows}"
-set ARTEMIS_INSTANCE_ETC_URI="${artemis.instance.etc.uri.windows}"
+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=${java-opts} -XX:AutoBoxCacheMax=20000 -XX:+PrintClassHistogram -XX:+UseG1GC -XX:+UseStringDeduplication -Xms512M -Xmx${java-memory} -Djava.security.auth.login.config=%ARTEMIS_ETC_DIR%\login.config -Dhawtio.disableProxy=true -Dhawtio.offline=true -Dhawtio.realm=activemq -Dhawtio.role=${role} -Dhawtio.rolePrincipalClasses=org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal -Djolokia.policyLocation=%ARTEMIS_INSTANCE_ETC_URI%\jolokia-access. [...]
+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=%ARTE [...]
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
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/bootstrap.xml b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/bootstrap.xml
new file mode 100644
index 0000000000..9576de7c55
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/bootstrap.xml
@@ -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>
+
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/broker.xml b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/broker.xml
new file mode 100644
index 0000000000..c88da8e62f
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/broker.xml
@@ -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>
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/jolokia-access.xml b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/jolokia-access.xml
new file mode 100644
index 0000000000..679523f896
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/jolokia-access.xml
@@ -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>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/logging.properties b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/logging.properties
new file mode 100644
index 0000000000..97980b99c2
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/logging.properties
@@ -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
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/login.config b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/login.config
new file mode 100644
index 0000000000..bcdf92893f
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/login.config
@@ -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";
+};
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/management.xml b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/management.xml
new file mode 100644
index 0000000000..002ee95050
--- /dev/null
+++ b/tests/smoke-tests/src/main/filtered-resources/servers/windowsETC/management.xml
@@ -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>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/CompareUpgradeTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/CompareUpgradeTest.java
new file mode 100644
index 0000000000..80d00dbd44
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/CompareUpgradeTest.java
@@ -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;
+ }
+}
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/UpgradeTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/UpgradeTest.java
new file mode 100644
index 0000000000..75501318ef
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/upgradeTest/UpgradeTest.java
@@ -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());
+ }
+
+ }
+
+}