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 2020/07/30 13:33:07 UTC
[activemq-artemis] 02/03: ARTEMIS-2858 DNS Tests on reconnects and
backups
This is an automated email from the ASF dual-hosted git repository.
clebertsuconic pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git
commit c00b210629aeda71837f2233252d0e314cc49482
Author: Clebert Suconic <cl...@apache.org>
AuthorDate: Wed Jul 29 11:33:22 2020 -0400
ARTEMIS-2858 DNS Tests on reconnects and backups
There are no fixes as part of this test addition. As I wrote this test as I was debugging DNS issues.
---
.../apache/activemq/artemis/util/ServerUtil.java | 71 +-
.../activemq/artemis/utils}/network/NetUtil.java | 27 +-
.../artemis/utils}/network/NetUtilResource.java | 2 +-
.../artemis/tests/util/ActiveMQTestBase.java | 17 +-
.../failover/NetworkFailureFailoverTest.java | 4 +-
.../ActiveMQServerControlUsingCoreTest.java | 5 +
tests/smoke-tests/pom.xml | 91 +++
.../servers/dnsswitch-replicated-backup/broker.xml | 133 ++++
.../dnsswitch-replicated-backup/management.xml | 20 +
.../broker.xml | 133 ++++
.../management.xml | 20 +
.../servers/dnsswitch-replicated-main/broker.xml | 133 ++++
.../dnsswitch-replicated-main/management.xml | 20 +
.../main/resources/servers/dnsswitch/broker.xml | 182 +++++
.../main/resources/servers/dnsswitch2/broker.xml | 182 +++++
.../artemis/tests/smoke/common/SmokeTestBase.java | 6 +
.../tests/smoke/dnsswitch/DNSSwitchTest.java | 837 +++++++++++++++++++++
17 files changed, 1843 insertions(+), 40 deletions(-)
diff --git a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
index 087a1b1..7c8675b 100644
--- a/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
+++ b/artemis-cli/src/main/java/org/apache/activemq/artemis/util/ServerUtil.java
@@ -48,41 +48,62 @@ public class ServerUtil {
* @throws Exception
*/
public static Process startServer(String artemisInstance, String serverName, int id, int timeout) throws Exception {
- boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().trim().startsWith("win");
+ final Process process = internalStartServer(artemisInstance, serverName);
- ProcessBuilder builder = null;
- if (IS_WINDOWS) {
- builder = new ProcessBuilder("cmd", "/c", "artemis.cmd", "run");
- } else {
- builder = new ProcessBuilder("./artemis", "run");
+ // wait for start
+ if (timeout != 0) {
+ waitForServerToStart(id, timeout);
}
- builder.directory(new File(artemisInstance + "/bin"));
-
- final Process process = builder.start();
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- process.destroy();
- }
- });
-
- ProcessLogger outputLogger = new ProcessLogger(true, process.getInputStream(), serverName, false);
- outputLogger.start();
+ return process;
+ }
- // Adding a reader to System.err, so the VM won't hang on a System.err.println as identified on this forum thread:
- // http://www.jboss.org/index.html?module=bb&op=viewtopic&t=151815
- ProcessLogger errorLogger = new ProcessLogger(true, process.getErrorStream(), serverName, true);
- errorLogger.start();
+ public static Process startServer(String artemisInstance, String serverName, String uri, int timeout) throws Exception {
+ final Process process = internalStartServer(artemisInstance, serverName);
// wait for start
if (timeout != 0) {
- waitForServerToStart(id, timeout);
+ waitForServerToStart(uri, timeout);
}
return process;
}
+ private static Process internalStartServer(String artemisInstance,
+ String serverName) throws IOException, ClassNotFoundException {
+ try {
+ boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().trim().startsWith("win");
+
+ ProcessBuilder builder = null;
+ if (IS_WINDOWS) {
+ builder = new ProcessBuilder("cmd", "/c", "artemis.cmd", "run");
+ } else {
+ builder = new ProcessBuilder("./artemis", "run");
+ }
+
+ builder.directory(new File(artemisInstance + "/bin"));
+
+ final Process process = builder.start();
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ process.destroy();
+ }
+ });
+
+ ProcessLogger outputLogger = new ProcessLogger(true, process.getInputStream(), serverName, false);
+ outputLogger.start();
+
+ // Adding a reader to System.err, so the VM won't hang on a System.err.println as identified on this forum thread:
+ // http://www.jboss.org/index.html?module=bb&op=viewtopic&t=151815
+ ProcessLogger errorLogger = new ProcessLogger(true, process.getErrorStream(), serverName, true);
+ errorLogger.start();
+ return process;
+ } catch (IOException e) {
+ throw new IOException("Cannot start server at " + artemisInstance, e);
+ }
+ }
+
public static boolean waitForServerToStart(int id, int timeout) throws InterruptedException {
return waitForServerToStart("tcp://localhost:" + (61616 + id), timeout);
}
@@ -119,7 +140,9 @@ public class ServerUtil {
server.destroy();
}
server.waitFor();
- Thread.sleep(1000);
+ if (!forcibly) {
+ Thread.sleep(1000);
+ }
}
}
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtil.java b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtil.java
similarity index 90%
rename from tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtil.java
rename to artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtil.java
index 124face..489d47b 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtil.java
+++ b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtil.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.activemq.artemis.tests.util.network;
+package org.apache.activemq.artemis.utils.network;
import java.io.BufferedReader;
import java.io.IOException;
@@ -100,7 +100,7 @@ public class NetUtil {
while (iter.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
try {
- netDown(entry.getKey(), entry.getValue());
+ netDown(entry.getKey(), entry.getValue(), true);
} catch (Exception e) {
e.printStackTrace();
}
@@ -125,20 +125,31 @@ public class NetUtil {
}
public static void netDown(String ip) throws Exception {
- String device = networks.remove(ip);
- Assert.assertNotNull("ip " + ip + "wasn't set up before", device);
- netDown(ip, device);
+ netDown(ip, false);
+ }
+
+ public static void netDown(String ip, boolean force) throws Exception {
+ String device = networks.remove(ip);
+ if (!force) {
+ // in case the netDown is coming from a different VM (spawned tests)
+ Assert.assertNotNull("ip " + ip + "wasn't set up before", device);
+ }
+ netDown(ip, device, force);
}
- private static void netDown(String ip, String device) throws Exception {
+ private static void netDown(String ip, String device, boolean force) throws Exception {
if (osUsed == OS.MAC) {
if (runCommand("sudo", "-n", "ifconfig", "lo0", "-alias", ip) != 0) {
- Assert.fail("Cannot sudo ifconfig for ip " + ip);
+ if (!force) {
+ Assert.fail("Cannot sudo ifconfig for ip " + ip);
+ }
}
} else if (osUsed == OS.LINUX) {
if (runCommand("sudo", "-n", "ifconfig", device, "down") != 0) {
- Assert.fail("Cannot sudo ifconfig for ip " + ip);
+ if (!force) {
+ Assert.fail("Cannot sudo ifconfig for ip " + ip);
+ }
}
} else {
Assert.fail("OS not supported");
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtilResource.java b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtilResource.java
similarity index 94%
rename from tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtilResource.java
rename to artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtilResource.java
index 0f2abd9..b58f3f6 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/util/network/NetUtilResource.java
+++ b/artemis-commons/src/test/java/org/apache/activemq/artemis/utils/network/NetUtilResource.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.activemq.artemis.tests.util.network;
+package org.apache.activemq.artemis.utils.network;
import org.junit.rules.ExternalResource;
diff --git a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
index 981e38e..d1adf59 100644
--- a/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
+++ b/artemis-server/src/test/java/org/apache/activemq/artemis/tests/util/ActiveMQTestBase.java
@@ -1127,24 +1127,22 @@ public abstract class ActiveMQTestBase extends Assert {
assertFalse(store.isPaging());
}
- protected Topology waitForTopology(final ActiveMQServer server, final int nodes) throws Exception {
+ protected static Topology waitForTopology(final ActiveMQServer server, final int nodes) throws Exception {
return waitForTopology(server, nodes, -1, WAIT_TIMEOUT);
}
- protected Topology waitForTopology(final ActiveMQServer server,
+ protected static Topology waitForTopology(final ActiveMQServer server,
final int nodes,
final int backups) throws Exception {
return waitForTopology(server, nodes, backups, WAIT_TIMEOUT);
}
- protected Topology waitForTopology(final ActiveMQServer server,
+ protected static Topology waitForTopology(final ActiveMQServer server,
final int liveNodes,
final int backupNodes,
final long timeout) throws Exception {
logger.debug("waiting for " + liveNodes + " on the topology for server = " + server);
- long start = System.currentTimeMillis();
-
Set<ClusterConnection> ccs = server.getClusterManager().getClusterConnections();
if (ccs.size() != 1) {
@@ -1153,6 +1151,15 @@ public abstract class ActiveMQTestBase extends Assert {
Topology topology = server.getClusterManager().getDefaultConnection(null).getTopology();
+ return waitForTopology(topology, timeout, liveNodes, backupNodes);
+ }
+
+ protected static Topology waitForTopology(Topology topology,
+ long timeout,
+ int liveNodes,
+ int backupNodes) throws Exception {
+ final long start = System.currentTimeMillis();
+
int liveNodesCount = 0;
int backupNodesCount = 0;
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java
index fc1f5bc..8bae6e8 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/cluster/failover/NetworkFailureFailoverTest.java
@@ -45,8 +45,8 @@ import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
import org.apache.activemq.artemis.core.server.cluster.impl.MessageLoadBalancingType;
import org.apache.activemq.artemis.tests.util.Wait;
import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
-import org.apache.activemq.artemis.tests.util.network.NetUtil;
-import org.apache.activemq.artemis.tests.util.network.NetUtilResource;
+import org.apache.activemq.artemis.utils.network.NetUtil;
+import org.apache.activemq.artemis.utils.network.NetUtilResource;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Rule;
diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
index 4b8138b..95f0513 100644
--- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
+++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/management/ActiveMQServerControlUsingCoreTest.java
@@ -121,6 +121,11 @@ public class ActiveMQServerControlUsingCoreTest extends ActiveMQServerControlTes
}
@Override
+ public boolean isActive() {
+ return (Boolean) proxy.retrieveAttributeValue("active");
+ }
+
+ @Override
public String createQueue(String address,
String routingType,
String name,
diff --git a/tests/smoke-tests/pom.xml b/tests/smoke-tests/pom.xml
index 604495b..ee0a5a9 100644
--- a/tests/smoke-tests/pom.xml
+++ b/tests/smoke-tests/pom.xml
@@ -221,6 +221,97 @@
</execution>
<execution>
<phase>test-compile</phase>
+ <id>create-dnsswitch</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/servers/dnsswitch</configuration>
+ <allowAnonymous>true</allowAnonymous>
+ <user>admin</user>
+ <password>admin</password>
+ <instance>${basedir}/target/dnsswitch</instance>
+ </configuration>
+ </execution>
+ <execution>
+ <phase>test-compile</phase>
+ <id>create-dnsswitch2</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/servers/dnsswitch2</configuration>
+ <allowAnonymous>true</allowAnonymous>
+ <user>admin</user>
+ <password>admin</password>
+ <instance>${basedir}/target/dnsswitch2</instance>
+ </configuration>
+ </execution>
+ <execution>
+ <phase>test-compile</phase>
+ <id>create-dnsswitch-main</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/servers/dnsswitch-replicated-main</configuration>
+ <allowAnonymous>true</allowAnonymous>
+ <user>admin</user>
+ <password>admin</password>
+ <noWeb>true</noWeb>
+ <instance>${basedir}/target/dnsswitch-replicated-main</instance>
+ <args>
+ <arg>--java-options</arg>
+ <!-- notice these files are only available on dnsswitch, so this is not a copy and paste error
+ where I really meant dnsswitch here -->
+ <arg>-Djdk.net.hosts.file=${basedir}/target/dnsswitch/etc/hosts.conf -Djava.security.properties=${basedir}/target/dnsswitch/etc/zerocache.security -Djava.rmi.server.hostname=localhost</arg>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <phase>test-compile</phase>
+ <id>create-dnsswitch-main-noretrydns</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/servers/dnsswitch-replicated-main-noretrydns</configuration>
+ <allowAnonymous>true</allowAnonymous>
+ <user>admin</user>
+ <password>admin</password>
+ <noWeb>true</noWeb>
+ <instance>${basedir}/target/dnsswitch-replicated-main-noretrydns</instance>
+ <args>
+ <arg>--java-options</arg>
+ <!-- notice these files are only available on dnsswitch, so this is not a copy and paste error
+ where I really meant dnsswitch here -->
+ <arg>-Djdk.net.hosts.file=${basedir}/target/dnsswitch/etc/hosts.conf -Djava.security.properties=${basedir}/target/dnsswitch/etc/noretrydns.security -Djava.rmi.server.hostname=localhost</arg>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <phase>test-compile</phase>
+ <id>create-dnsswitch-backup</id>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ <configuration>
+ <configuration>${basedir}/target/classes/servers/dnsswitch-replicated-backup</configuration>
+ <allowAnonymous>true</allowAnonymous>
+ <user>admin</user>
+ <password>admin</password>
+ <noWeb>true</noWeb>
+ <instance>${basedir}/target/dnsswitch-replicated-backup</instance>
+ <args>
+ <arg>--java-options</arg>
+ <!-- notice these files are only available on dnsswitch, so this is not a copy and paste error
+ where I really meant dnsswitch here -->
+ <arg>-Djdk.net.hosts.file=${basedir}/target/dnsswitch/etc/hosts.conf -Djava.security.properties=${basedir}/target/dnsswitch/etc/zerocache.security -Djava.rmi.server.hostname=localhost</arg>
+ </args>
+ </configuration>
+ </execution>
+ <execution>
+ <phase>test-compile</phase>
<id>create-maxConsumers</id>
<goals>
<goal>create</goal>
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/broker.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/broker.xml
new file mode 100644
index 0000000..36a07a6
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/broker.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+
+ <core xmlns="urn:activemq:core">
+
+ <name>backup</name>
+
+ <bindings-directory>./data/bindings</bindings-directory>
+
+ <journal-directory>./data/journal</journal-directory>
+
+ <large-messages-directory>./data/largemessages</large-messages-directory>
+
+ <paging-directory>./data/paging</paging-directory>
+
+ <ha-policy>
+ <replication>
+ <slave>
+ <group-name>a</group-name>
+ <allow-failback>true</allow-failback>
+ </slave>
+ </replication>
+ </ha-policy>
+
+ <connectors>
+ <!-- Connector used to be announced through cluster connections and notifications -->
+ <connector name="artemis">tcp://SECOND:61616</connector>
+ <connector name="main">tcp://FIRST:61616</connector>
+ </connectors>
+
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="artemis">tcp://SECOND:61616</acceptor>
+ </acceptors>
+
+ <cluster-user>admin</cluster-user>
+
+ <cluster-password>password</cluster-password>
+
+ <cluster-connections>
+ <cluster-connection name="my-cluster">
+ <connector-ref>artemis</connector-ref>
+ <message-load-balancing>OFF</message-load-balancing>
+ <max-hops>1</max-hops>
+ <static-connectors>
+ <connector-ref>main</connector-ref>
+ </static-connectors>
+ </cluster-connection>
+ </cluster-connections>
+
+ <!-- Other config -->
+
+ <security-settings>
+ <!--security for example queue-->
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="amq, guest"/>
+ <permission type="deleteNonDurableQueue" roles="amq, guest"/>
+ <permission type="createDurableQueue" roles="amq, guest"/>
+ <permission type="deleteDurableQueue" roles="amq, guest"/>
+ <permission type="createAddress" roles="amq, guest"/>
+ <permission type="deleteAddress" roles="amq, guest"/>
+ <permission type="consume" roles="amq, guest"/>
+ <permission type="browse" roles="amq, guest"/>
+ <permission type="send" roles="amq, guest"/>
+ <!-- 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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </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>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <max-size-bytes>10MB</max-size-bytes>
+ <page-size-bytes>1MB</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </address-setting>
+ </address-settings>
+
+ <addresses>
+ <address name="exampleTopic">
+ <multicast>
+ </multicast>
+ </address>
+ <address name="exampleQueue">
+ <anycast>
+ <queue name="exampleQueue"/>
+ </anycast>
+ </address>
+ </addresses>
+ </core>
+</configuration>
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/management.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/management.xml
new file mode 100644
index 0000000..14bbaf2
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-backup/management.xml
@@ -0,0 +1,20 @@
+<?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.org/schema">
+ <connector connector-port="10199" connector-host="localhost"/>
+</management-context>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/broker.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/broker.xml
new file mode 100644
index 0000000..bb5995e
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/broker.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+
+ <core xmlns="urn:activemq:core">
+
+ <name>live</name>
+
+ <bindings-directory>./data/bindings</bindings-directory>
+
+ <journal-directory>./data/journal</journal-directory>
+
+ <large-messages-directory>./data/largemessages</large-messages-directory>
+
+ <paging-directory>./data/paging</paging-directory>
+
+ <ha-policy>
+ <replication>
+ <master>
+ <group-name>a</group-name>
+ <check-for-live-server>true</check-for-live-server>
+ <vote-on-replication-failure>true</vote-on-replication-failure>
+ </master>
+ </replication>
+ </ha-policy>
+
+ <connectors>
+ <!-- Connector used to be announced through cluster connections and notifications -->
+ <connector name="artemis">tcp://FIRST:61616</connector>
+ <connector name="backup">tcp://SECOND:61616</connector>
+ </connectors>
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="artemis">tcp://FIRST:61616</acceptor>
+ </acceptors>
+
+ <cluster-user>admin</cluster-user>
+
+ <cluster-password>password</cluster-password>
+
+ <cluster-connections>
+ <cluster-connection name="my-cluster">
+ <connector-ref>artemis</connector-ref>
+ <message-load-balancing>OFF</message-load-balancing>
+ <max-hops>1</max-hops>
+ <static-connectors>
+ <connector-ref>backup</connector-ref>
+ </static-connectors>
+ </cluster-connection>
+ </cluster-connections>
+
+ <!-- Other config -->
+
+ <security-settings>
+ <!--security for example queue-->
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="amq, guest"/>
+ <permission type="deleteNonDurableQueue" roles="amq, guest"/>
+ <permission type="createDurableQueue" roles="amq, guest"/>
+ <permission type="deleteDurableQueue" roles="amq, guest"/>
+ <permission type="createAddress" roles="amq, guest"/>
+ <permission type="deleteAddress" roles="amq, guest"/>
+ <permission type="consume" roles="amq, guest"/>
+ <permission type="browse" roles="amq, guest"/>
+ <permission type="send" roles="amq, guest"/>
+ <!-- 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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </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>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <max-size-bytes>10MB</max-size-bytes>
+ <page-size-bytes>1MB</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </address-setting>
+ </address-settings>
+
+ <addresses>
+ <address name="exampleTopic">
+ <multicast>
+ </multicast>
+ </address>
+ <address name="exampleQueue">
+ <anycast>
+ <queue name="exampleQueue"/>
+ </anycast>
+ </address>
+ </addresses>
+ </core>
+</configuration>
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/management.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/management.xml
new file mode 100644
index 0000000..576f1e5
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main-noretrydns/management.xml
@@ -0,0 +1,20 @@
+<?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.org/schema">
+ <connector connector-port="10099" connector-host="localhost"/>
+</management-context>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/broker.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/broker.xml
new file mode 100644
index 0000000..bb5995e
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/broker.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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" xsi:schemaLocation="urn:activemq /schema/artemis-server.xsd">
+
+ <core xmlns="urn:activemq:core">
+
+ <name>live</name>
+
+ <bindings-directory>./data/bindings</bindings-directory>
+
+ <journal-directory>./data/journal</journal-directory>
+
+ <large-messages-directory>./data/largemessages</large-messages-directory>
+
+ <paging-directory>./data/paging</paging-directory>
+
+ <ha-policy>
+ <replication>
+ <master>
+ <group-name>a</group-name>
+ <check-for-live-server>true</check-for-live-server>
+ <vote-on-replication-failure>true</vote-on-replication-failure>
+ </master>
+ </replication>
+ </ha-policy>
+
+ <connectors>
+ <!-- Connector used to be announced through cluster connections and notifications -->
+ <connector name="artemis">tcp://FIRST:61616</connector>
+ <connector name="backup">tcp://SECOND:61616</connector>
+ </connectors>
+
+ <!-- Acceptors -->
+ <acceptors>
+ <acceptor name="artemis">tcp://FIRST:61616</acceptor>
+ </acceptors>
+
+ <cluster-user>admin</cluster-user>
+
+ <cluster-password>password</cluster-password>
+
+ <cluster-connections>
+ <cluster-connection name="my-cluster">
+ <connector-ref>artemis</connector-ref>
+ <message-load-balancing>OFF</message-load-balancing>
+ <max-hops>1</max-hops>
+ <static-connectors>
+ <connector-ref>backup</connector-ref>
+ </static-connectors>
+ </cluster-connection>
+ </cluster-connections>
+
+ <!-- Other config -->
+
+ <security-settings>
+ <!--security for example queue-->
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="amq, guest"/>
+ <permission type="deleteNonDurableQueue" roles="amq, guest"/>
+ <permission type="createDurableQueue" roles="amq, guest"/>
+ <permission type="deleteDurableQueue" roles="amq, guest"/>
+ <permission type="createAddress" roles="amq, guest"/>
+ <permission type="deleteAddress" roles="amq, guest"/>
+ <permission type="consume" roles="amq, guest"/>
+ <permission type="browse" roles="amq, guest"/>
+ <permission type="send" roles="amq, guest"/>
+ <!-- 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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </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>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <max-size-bytes>10MB</max-size-bytes>
+ <page-size-bytes>1MB</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </address-setting>
+ </address-settings>
+
+ <addresses>
+ <address name="exampleTopic">
+ <multicast>
+ </multicast>
+ </address>
+ <address name="exampleQueue">
+ <anycast>
+ <queue name="exampleQueue"/>
+ </anycast>
+ </address>
+ </addresses>
+ </core>
+</configuration>
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/management.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/management.xml
new file mode 100644
index 0000000..576f1e5
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch-replicated-main/management.xml
@@ -0,0 +1,20 @@
+<?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.org/schema">
+ <connector connector-port="10099" connector-host="localhost"/>
+</management-context>
\ No newline at end of file
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch/broker.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch/broker.xml
new file mode 100644
index 0000000..de9a37e
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch/broker.xml
@@ -0,0 +1,182 @@
+<?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"
+ 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>
+
+ <journal-datasync>true</journal-datasync>
+
+ <journal-min-files>2</journal-min-files>
+
+ <journal-pool-files>-1</journal-pool-files>
+
+ <journal-buffer-size>10485760</journal-buffer-size>
+
+ <!--
+ You can specify the NIC you want to use to verify if the network
+ <network-check-NIC>theNickName</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> -->
+
+
+
+ <!--
+ This value was determined through a calculation.
+ Your system could perform 0.15 writes per millisecond
+ on the current journal configuration.
+ That translates as a sync write every 6488000 nanoseconds
+ -->
+ <journal-buffer-timeout>6488000</journal-buffer-timeout>
+
+
+ <!-- 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>
+
+ <!-- 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>
+
+ -->
+ <global-max-size>100Mb</global-max-size>
+
+ <acceptors>
+ <!-- Acceptor for every supported protocol -->
+ <acceptor name="artemis">tcp://192.0.2.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
+
+ </acceptors>
+
+
+ <security-settings>
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="guest"/>
+ <permission type="deleteNonDurableQueue" roles="guest"/>
+ <permission type="createDurableQueue" roles="guest"/>
+ <permission type="deleteDurableQueue" roles="guest"/>
+ <permission type="createAddress" roles="guest"/>
+ <permission type="deleteAddress" roles="guest"/>
+ <permission type="consume" roles="guest"/>
+ <permission type="browse" roles="guest"/>
+ <permission type="send" roles="guest"/>
+ <!-- we need this otherwise ./artemis data imp wouldn't work -->
+ <permission type="manage" roles="guest"/>
+ </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> -->
+ <max-size-bytes>1M</max-size-bytes>
+ <page-size-bytes>50000</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </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>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <!-- <max-size-bytes>-1</max-size-bytes> -->
+ <page-size-bytes>50000</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </address-setting>
+ </address-settings>
+
+ <addresses>
+ <address name="DLQ">
+ <anycast>
+ <queue name="DLQ" />
+ </anycast>
+ </address>
+ <address name="ExpiryQueue">
+ <anycast>
+ <queue name="ExpiryQueue" />
+ </anycast>
+ </address>
+
+ </addresses>
+
+ </core>
+</configuration>
diff --git a/tests/smoke-tests/src/main/resources/servers/dnsswitch2/broker.xml b/tests/smoke-tests/src/main/resources/servers/dnsswitch2/broker.xml
new file mode 100644
index 0000000..7dd8850
--- /dev/null
+++ b/tests/smoke-tests/src/main/resources/servers/dnsswitch2/broker.xml
@@ -0,0 +1,182 @@
+<?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"
+ 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>
+
+ <journal-datasync>true</journal-datasync>
+
+ <journal-min-files>2</journal-min-files>
+
+ <journal-pool-files>-1</journal-pool-files>
+
+ <journal-buffer-size>10485760</journal-buffer-size>
+
+ <!--
+ You can specify the NIC you want to use to verify if the network
+ <network-check-NIC>theNickName</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> -->
+
+
+
+ <!--
+ This value was determined through a calculation.
+ Your system could perform 0.15 writes per millisecond
+ on the current journal configuration.
+ That translates as a sync write every 6488000 nanoseconds
+ -->
+ <journal-buffer-timeout>6488000</journal-buffer-timeout>
+
+
+ <!-- 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>
+
+ <!-- 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>
+
+ -->
+ <global-max-size>100Mb</global-max-size>
+
+ <acceptors>
+ <!-- Acceptor for every supported protocol -->
+ <acceptor name="artemis">tcp://192.0.3.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300</acceptor>
+
+ </acceptors>
+
+
+ <security-settings>
+ <security-setting match="#">
+ <permission type="createNonDurableQueue" roles="guest"/>
+ <permission type="deleteNonDurableQueue" roles="guest"/>
+ <permission type="createDurableQueue" roles="guest"/>
+ <permission type="deleteDurableQueue" roles="guest"/>
+ <permission type="createAddress" roles="guest"/>
+ <permission type="deleteAddress" roles="guest"/>
+ <permission type="consume" roles="guest"/>
+ <permission type="browse" roles="guest"/>
+ <permission type="send" roles="guest"/>
+ <!-- we need this otherwise ./artemis data imp wouldn't work -->
+ <permission type="manage" roles="guest"/>
+ </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> -->
+ <max-size-bytes>1M</max-size-bytes>
+ <page-size-bytes>50000</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </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>
+ <!-- with -1 only the global-max-size is in use for limiting -->
+ <!-- <max-size-bytes>-1</max-size-bytes> -->
+ <page-size-bytes>50000</page-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>
+ <auto-create-jms-queues>true</auto-create-jms-queues>
+ <auto-create-jms-topics>true</auto-create-jms-topics>
+ </address-setting>
+ </address-settings>
+
+ <addresses>
+ <address name="DLQ">
+ <anycast>
+ <queue name="DLQ" />
+ </anycast>
+ </address>
+ <address name="ExpiryQueue">
+ <anycast>
+ <queue name="ExpiryQueue" />
+ </anycast>
+ </address>
+
+ </addresses>
+
+ </core>
+</configuration>
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
index e35ffa5..543de50 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/common/SmokeTestBase.java
@@ -70,4 +70,10 @@ public class SmokeTestBase extends ActiveMQTestBase {
return process;
}
+ public Process startServer(String serverName, String uri, int timeout) throws Exception {
+ Process process = ServerUtil.startServer(getServerLocation(serverName), serverName, uri, timeout);
+ addProcess(process);
+ return process;
+ }
+
}
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
new file mode 100644
index 0000000..31a76d0
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/dnsswitch/DNSSwitchTest.java
@@ -0,0 +1,837 @@
+/*
+ * 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.dnsswitch;
+
+import javax.jms.Connection;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.management.MBeanServerInvocationHandler;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
+import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
+import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
+import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
+import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
+import org.apache.activemq.artemis.util.ServerUtil;
+import org.apache.activemq.artemis.utils.SpawnedVMSupport;
+import org.apache.activemq.artemis.utils.Wait;
+import org.apache.activemq.artemis.utils.network.NetUtil;
+import org.apache.activemq.artemis.utils.network.NetUtilResource;
+import org.jboss.logging.Logger;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+/**
+ * Validating connection retry scenarios where the DNS had changes
+ */
+public class DNSSwitchTest extends SmokeTestBase {
+
+ private static boolean USING_SPAWN = true;
+ public static final File ETC_HOSTS = new File("/etc/hosts");
+
+ private static File ETC_BACKUP;
+
+ private static final String JMX_SERVER_HOSTNAME = "localhost";
+ private static final int JMX_SERVER_PORT_0 = 10099;
+ private static final int JMX_SERVER_PORT_1 = 10199;
+
+ static String liveURI = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT_0 + "/jmxrmi";
+ static String backupURI = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT_1 + "/jmxrmi";
+
+ static ObjectNameBuilder liveNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), "live", true);
+ static ObjectNameBuilder backupNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), "backup", true);
+
+ // This is a more intrusive option to use with JDK 8
+ // Instead of using a separate jdk hsots, which is not supported on jdk8,
+ // with this option set to true we would use the original /etc/hosts
+ private static boolean USE_ETC_HOSTS = System.getProperty("java.version").startsWith("1.8");
+
+ private static final Logger logger = Logger.getLogger(DNSSwitchTest.class);
+
+ private static final String SERVER_NAME_0 = "dnsswitch";
+ private static final String SERVER_NAME_1 = "dnsswitch2";
+ private static final String SERVER_STANDARD = "standard";
+ private static final String SERVER_LIVE = "dnsswitch-replicated-main";
+ private static final String SERVER_LIVE_NORETRYDNS = "dnsswitch-replicated-main-noretrydns";
+ private static final String SERVER_BACKUP = "dnsswitch-replicated-backup";
+
+ // 192.0.2.0 is reserved for documentation (and testing on this case).
+ private static final String FIRST_IP = "192.0.2.0";
+ private static final String SECOND_IP = "192.0.3.0";
+ private static final String THIRD_IP = "192.0.3.0";
+ private static final String FOURTH_IP = "192.0.4.0";
+
+ private static String serverLocation;
+
+ @Rule
+ public NetUtilResource netUtilResource = new NetUtilResource();
+
+ private static JMXConnector newJMXFactory(String uri) throws Throwable {
+ return JMXConnectorFactory.connect(new JMXServiceURL(uri));
+ }
+
+ private static ActiveMQServerControl getServerControl(String uri,
+ ObjectNameBuilder builder,
+ long timeout) throws Throwable {
+ long expireLoop = System.currentTimeMillis() + timeout;
+ Throwable lastException = null;
+ do {
+ try {
+ JMXConnector connector = newJMXFactory(uri);
+
+ ActiveMQServerControl serverControl = MBeanServerInvocationHandler.newProxyInstance(connector.getMBeanServerConnection(), builder.getActiveMQServerObjectName(), ActiveMQServerControl.class, false);
+ serverControl.isActive(); // making one call to make sure it's working
+ return serverControl;
+ } catch (Throwable e) {
+ System.err.println("Retrying error : " + e.getMessage());
+ lastException = e;
+ Thread.sleep(500);
+ }
+ }
+ while (expireLoop > System.currentTimeMillis());
+
+ throw lastException;
+ }
+
+ @BeforeClass
+ public static void beforeClassMethod() throws Exception {
+ serverLocation = getServerLocation(SERVER_NAME_0);
+ // Before anything we must copy the jave security and change what we need for no cache
+ // this will be used to spawn new tests
+ generateNoCacheSecurity(serverLocation);
+ generateNoRetrySecurity(serverLocation);
+ if (USE_ETC_HOSTS) {
+ Assert.assertTrue("If you want to run this test, you must do 'sudo chmod 666 " + ETC_HOSTS + "'", ETC_HOSTS.canWrite());
+ File tmpDirectory = new File(System.getProperty("java.io.tmpdir"));
+ ETC_BACKUP = new File(tmpDirectory, "etcHostsBackup");
+
+ if (!ETC_BACKUP.exists()) {
+ Files.copy(ETC_HOSTS.toPath(), ETC_BACKUP.toPath(), StandardCopyOption.COPY_ATTRIBUTES);
+ }
+ }
+ NetUtil.failIfNotSudo();
+ }
+
+ private static File getETCBackup() {
+
+ if (ETC_BACKUP == null) {
+ File tmpDirectory = new File(System.getProperty("java.io.tmpdir"));
+ ETC_BACKUP = new File(tmpDirectory, "etcHostsBackup");
+ }
+
+ Assert.assertTrue(ETC_BACKUP.exists());
+
+ return ETC_BACKUP;
+ }
+
+ @AfterClass
+ public static void afterClassMethod() throws Exception {
+
+ if (USE_ETC_HOSTS && ETC_BACKUP != null) {
+ Assert.assertTrue(ETC_BACKUP.exists());
+ try {
+ recoverETCHosts();
+ } finally {
+ ETC_BACKUP.delete();
+ ETC_BACKUP = null;
+ }
+
+ }
+
+ }
+
+ private static void recoverETCHosts() throws IOException {
+ // it seems silly to use a FileInputStream / FileOutputStream to copy
+ // a file these days, but on this case we have authorization to write on the file
+ // but not to replace the file in any way.
+ // So, Files.copy is not acceptable.
+ // I could use a library that was doing the same here
+ // but I didn't bother about it and simply went to the simplest way possible
+ FileInputStream inputStream = new FileInputStream(getETCBackup());
+ FileOutputStream outputStream = new FileOutputStream(ETC_HOSTS);
+ byte[] buffer = new byte[4 * 1024];
+ int bytes;
+ try {
+ while ((bytes = inputStream.read(buffer)) > 0) {
+ outputStream.write(buffer, 0, bytes);
+ }
+ } finally {
+ inputStream.close();
+ outputStream.close();
+ }
+ }
+
+ private static void generateNoCacheSecurity(String serverLocation) throws Exception {
+ File outputSecurity = new File(serverLocation + File.separator + "etc" + File.separator + "zerocache.security");
+ generateSecurity(outputSecurity, "networkaddress.cache.ttl", "0", "networkaddress.cache.negative.ttl", "0");
+ }
+
+ private static void generateNoRetrySecurity(String serverLocation) throws Exception {
+ File outputSecurity = new File(serverLocation + File.separator + "etc" + File.separator + "noretrydns.security");
+ generateSecurity(outputSecurity, "networkaddress.cache.ttl", "-1", "networkaddress.cache.negative.ttl", "-1");
+ }
+
+ private static void generateSecurity(File outputSecurity, String... overrideParameters) throws IOException {
+
+ Assert.assertTrue("You must send pairs as overrideParameters", overrideParameters.length % 2 == 0);
+
+ File security = new File(System.getProperty("java.home") + File.separator + "lib" + File.separator + "security" + File.separator + "java.security");
+ Properties securityProperties = new Properties();
+ securityProperties.load(new FileInputStream(security));
+
+ for (int i = 0; i < overrideParameters.length; i += 2) {
+ securityProperties.setProperty(overrideParameters[i], overrideParameters[i + 1]);
+ }
+
+ securityProperties.store(new FileOutputStream(outputSecurity), "# generated by DNSSwitchTest");
+ }
+
+ private static final String hostsFile = System.getProperty("jdk.net.hosts.file");
+
+ @Before
+ public void before() throws Exception {
+ cleanupData(SERVER_NAME_0);
+ cleanupData(SERVER_NAME_1);
+ cleanupData(SERVER_STANDARD);
+ cleanupData(SERVER_LIVE);
+ cleanupData(SERVER_LIVE_NORETRYDNS);
+ cleanupData(SERVER_BACKUP);
+ }
+
+ @Test
+ public void testBackupRedefinition() throws Throwable {
+ System.out.println(System.getProperty("java.security.properties"));
+
+ spawnRun(serverLocation, "testBackupRedefinition", getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP));
+ }
+
+ public static void testBackupRedefinition(String[] args) throws Throwable {
+ NetUtil.netUp(FIRST_IP);
+ NetUtil.netUp(SECOND_IP);
+ // NetUtil.netUp(THIRD_IP);
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+
+ //System.out.println("Waiting here");
+ //Thread.sleep(300_000);
+
+ Process serverLive = null;
+ Process serverBackup = null;
+
+ try {
+ serverLive = ServerUtil.startServer(args[1], "live", "tcp://FIRST:61616", 30_000);
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ connectAndWaitBackup();
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ NetUtil.netDown(SECOND_IP, true);
+ serverBackup.destroyForcibly();
+
+ Thread.sleep(1000); // wait some time at least until a reconnection is in place
+
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ // waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 0);
+
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ ActiveMQServerControl backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+ connectAndWaitBackup();
+
+ //waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ //System.out.println("I'm here!!!");
+ //Thread.sleep(300_000);
+
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://FIRST:61616?ha=true");
+ Assert.assertTrue(connectionFactory.getServerLocator().isHA());
+ Connection connection = connectionFactory.createConnection();
+ waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+
+ Queue queue = session.createQueue("test");
+
+ MessageProducer producer = session.createProducer(queue);
+
+ producer.send(session.createTextMessage("hello"));
+ session.commit();
+
+ NetUtil.netUp(THIRD_IP);
+ serverLive.destroyForcibly();
+
+ Wait.assertTrue(backupControl::isActive);
+
+ MessageConsumer consumer = null;
+ int errors = 0;
+ while (true) {
+ try {
+ consumer = session.createConsumer(queue);
+ connection.start();
+ TextMessage message = (TextMessage) consumer.receive(5000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("hello", message.getText());
+ session.commit();
+ break;
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors++;
+ Assert.assertTrue(errors < 20); // I would accept one or two errors, but the code must connect itself
+ connection.close();
+ connectionFactory = new ActiveMQConnectionFactory("tcp://SECOND:61616?ha=true");
+ connection = connectionFactory.createConnection();
+ connection.start();
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ }
+ }
+
+ } finally {
+ if (serverLive != null) {
+ serverLive.destroyForcibly();
+ }
+ if (serverBackup != null) {
+ serverBackup.destroyForcibly();
+ }
+
+ }
+
+ }
+
+
+ @Test
+ public void testBackupRedefinition2() throws Throwable {
+ System.out.println(System.getProperty("java.security.properties"));
+
+ spawnRun(serverLocation, "testBackupRedefinition2", getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP));
+ }
+
+ public static void testBackupRedefinition2(String[] args) throws Throwable {
+ NetUtil.netUp(FIRST_IP);
+ NetUtil.netUp(SECOND_IP);
+ NetUtil.netUp(THIRD_IP);
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+
+ //System.out.println("Waiting here");
+ //Thread.sleep(300_000);
+
+ Process serverLive = null;
+ Process serverBackup = null;
+
+ try {
+ serverLive = ServerUtil.startServer(args[1], "live", "tcp://FIRST:61616", 30_000);
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ connectAndWaitBackup();
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ NetUtil.netDown(SECOND_IP, true);
+ serverBackup.destroyForcibly();
+
+ Thread.sleep(1000); // wait some time at least until a reconnection is in place
+
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ // waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 0);
+
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ ActiveMQServerControl backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+ serverBackup.destroyForcibly();
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+ connectAndWaitBackup();
+
+ backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+ //waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ //System.out.println("I'm here!!!");
+ //Thread.sleep(300_000);
+
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://FIRST:61616?ha=true");
+ Assert.assertTrue(connectionFactory.getServerLocator().isHA());
+ Connection connection = connectionFactory.createConnection();
+ waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+
+ Queue queue = session.createQueue("test");
+
+ MessageProducer producer = session.createProducer(queue);
+
+ producer.send(session.createTextMessage("hello"));
+ session.commit();
+
+ NetUtil.netUp(THIRD_IP);
+ serverLive.destroyForcibly();
+
+ Wait.assertTrue(backupControl::isActive);
+
+ MessageConsumer consumer = null;
+ int errors = 0;
+ while (true) {
+ try {
+ consumer = session.createConsumer(queue);
+ connection.start();
+ TextMessage message = (TextMessage) consumer.receive(5000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("hello", message.getText());
+ session.commit();
+ break;
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors++;
+ Assert.assertTrue(errors < 20); // I would accept one or two errors, but the code must connect itself
+ connection.close();
+ connectionFactory = new ActiveMQConnectionFactory("tcp://SECOND:61616?ha=true");
+ connection = connectionFactory.createConnection();
+ connection.start();
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ }
+ }
+
+ } finally {
+ if (serverBackup != null) {
+ serverBackup.destroyForcibly();
+ }
+ if (serverLive != null) {
+ serverLive.destroyForcibly();
+ }
+ }
+
+ }
+
+
+ @Test
+ public void testBackupRedefinition3() throws Throwable {
+ System.out.println(System.getProperty("java.security.properties"));
+
+ spawnRun(serverLocation, "testBackupRedefinition2", getServerLocation(SERVER_LIVE), getServerLocation(SERVER_BACKUP));
+ }
+
+ public static void testBackupRedefinition3(String[] args) throws Throwable {
+ NetUtil.netUp(FIRST_IP);
+ NetUtil.netUp(SECOND_IP);
+ NetUtil.netUp(THIRD_IP);
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+
+ //System.out.println("Waiting here");
+ //Thread.sleep(300_000);
+
+ Process serverLive = null;
+ Process serverBackup = null;
+
+ try {
+ serverLive = ServerUtil.startServer(args[1], "live", "tcp://FIRST:61616", 30_000);
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ connectAndWaitBackup();
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ NetUtil.netDown(SECOND_IP, true);
+ serverBackup.destroyForcibly();
+
+ Thread.sleep(1000); // wait some time at least until a reconnection is in place
+
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ // waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 0);
+
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+
+ ActiveMQServerControl backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+ serverBackup.destroyForcibly();
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+ connectAndWaitBackup();
+
+ backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+ //waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ //System.out.println("I'm here!!!");
+ //Thread.sleep(300_000);
+
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://FIRST:61616?ha=true");
+ Assert.assertTrue(connectionFactory.getServerLocator().isHA());
+ Connection connection = connectionFactory.createConnection();
+ waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+
+ Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
+
+ Queue queue = session.createQueue("test");
+
+ MessageProducer producer = session.createProducer(queue);
+
+ producer.send(session.createTextMessage("hello"));
+ session.commit();
+
+ NetUtil.netUp(THIRD_IP);
+ serverLive.destroyForcibly();
+
+ Wait.assertTrue(backupControl::isActive);
+
+ MessageConsumer consumer = null;
+ int errors = 0;
+ while (true) {
+ try {
+ consumer = session.createConsumer(queue);
+ connection.start();
+ TextMessage message = (TextMessage) consumer.receive(5000);
+ Assert.assertNotNull(message);
+ Assert.assertEquals("hello", message.getText());
+ session.commit();
+ break;
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors++;
+ Assert.assertTrue(errors < 20); // I would accept one or two errors, but the code must connect itself
+ connection.close();
+ connectionFactory = new ActiveMQConnectionFactory("tcp://SECOND:61616?ha=true");
+ connection = connectionFactory.createConnection();
+ connection.start();
+ session = connection.createSession(true, Session.SESSION_TRANSACTED);
+ }
+ }
+
+ } finally {
+ if (serverBackup != null) {
+ serverBackup.destroyForcibly();
+ }
+ if (serverLive != null) {
+ serverLive.destroyForcibly();
+ }
+
+
+ }
+
+ }
+
+
+ @Test
+ public void testCantReachBack() throws Throwable {
+ System.out.println(System.getProperty("java.security.properties"));
+
+ spawnRun(serverLocation, "testCantReachBack", getServerLocation(SERVER_LIVE_NORETRYDNS), getServerLocation(SERVER_BACKUP));
+ }
+
+ public static void testCantReachBack(String[] args) throws Throwable {
+ NetUtil.netUp(FIRST_IP);
+ NetUtil.netUp(SECOND_IP);
+
+ // notice there's no THIRD_IP anywhere
+ saveConf(hostsFile, FIRST_IP, "FIRST", THIRD_IP, "SECOND");
+
+ Process serverLive = null;
+ Process serverBackup = null;
+
+ try {
+ serverLive = ServerUtil.startServer(args[1], "live", "tcp://FIRST:61616", 30_000);
+ ActiveMQServerControl liveControl = getServerControl(liveURI, liveNameBuilder, 20_000);
+
+ Wait.assertTrue(liveControl::isStarted);
+
+ // notice the first server does not know about this server at all
+ saveConf(hostsFile, FIRST_IP, "FIRST", SECOND_IP, "SECOND");
+ serverBackup = ServerUtil.startServer(args[2], "backup", "tcp://SECOND:61716", 0);
+ ActiveMQServerControl backupControl = getServerControl(backupURI, backupNameBuilder, 20_000);
+
+ Wait.assertTrue(backupControl::isStarted);
+ Wait.assertTrue(backupControl::isReplicaSync);
+
+ connectAndWaitBackup();
+
+ } finally {
+ if (serverBackup != null) {
+ serverBackup.destroyForcibly();
+ }
+ if (serverLive != null) {
+ serverLive.destroyForcibly();
+ }
+
+
+ }
+
+ }
+
+ private static void connectAndWaitBackup() throws Exception {
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://FIRST:61616?ha=true");
+ Assert.assertTrue(connectionFactory.getServerLocator().isHA());
+ Connection connection = connectionFactory.createConnection();
+ waitForTopology(connectionFactory.getServerLocator().getTopology(), 60_000, 1, 1);
+ connection.close();
+ }
+
+ @Test
+ public void testFailoverDifferentIPRedefinition() throws Throwable {
+
+ spawnRun(serverLocation, "testFailoverDifferentIPRedefinition", serverLocation, getServerLocation(SERVER_NAME_1));
+ }
+
+ public static void testFailoverDifferentIPRedefinition(String[] arg) throws Throwable {
+ NetUtil.netUp(FIRST_IP);
+ NetUtil.netUp(SECOND_IP);
+
+ saveConf(hostsFile, FIRST_IP, "test");
+ Process server = null;
+ Process server2 = null;
+ try {
+ server = ServerUtil.startServer(arg[1], "original-server", "tcp://test:61616", 5000);
+
+ ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://test:61616?initialConnectAttempts=500&retryInterval=100&connect-timeout-millis=100&reconnectAttempts=500&connectionTTL=1000");
+
+ Connection connection = factory.createConnection();
+
+ server.destroyForcibly();
+ NetUtil.netDown(FIRST_IP, true);
+
+ CountDownLatch latchConnect = new CountDownLatch(1);
+ AtomicInteger errors = new AtomicInteger(0);
+
+ Thread connecting = new Thread(() -> {
+ try {
+ latchConnect.countDown();
+ Connection connection2 = factory.createConnection();
+ connection2.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+ });
+
+ connecting.start();
+
+ Assert.assertTrue(latchConnect.await(5, TimeUnit.SECONDS));
+
+ Thread.sleep(500);
+
+ server = ServerUtil.startServer(arg[2], "new-server", "tcp://" + SECOND_IP + ":61616", 5000);
+
+ saveConf(hostsFile, SECOND_IP, "test");
+ connecting.join(5000);
+ Assert.assertFalse(connecting.isAlive());
+ Assert.assertEquals(0, errors.get());
+ } finally {
+ if (server != null)
+ server.destroyForcibly();
+ if (server2 != null)
+ server2.destroyForcibly();
+ }
+
+ }
+
+ @Test
+ public void testInitialConnector() throws Throwable {
+ ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://test:61616?initialConnectAttempts=500&retryInterval=100&connect-timeout-millis=100");
+ startServer(SERVER_STANDARD, 0, 30000);
+
+ String location = getServerLocation(SERVER_NAME_0);
+
+ spawnRun(location, "testInitialConnector");
+ // If you eed to debug the test, comment out spawnRun, and call the method directly
+ // you will need to add roperties on the JDK for that
+ // Add the properties you need
+ // testInitialConnector("testInitialConnector", location);
+ }
+
+ // called with reflection
+ public static void testInitialConnector(String... arg) throws Throwable {
+ saveConf(hostsFile, "192.0.0.3", "test");
+ validateIP("test", "192.0.0.3");
+
+ AtomicInteger errors = new AtomicInteger(0);
+
+ CountDownLatch initialConnectTried = new CountDownLatch(1);
+
+ ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://test:61616?initialConnectAttempts=500&retryInterval=100&connect-timeout-millis=100");
+ Thread connecting = new Thread(() -> {
+ try {
+ initialConnectTried.countDown();
+ Connection connection = factory.createConnection();
+ connection.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ errors.incrementAndGet();
+ }
+ });
+
+ connecting.start();
+
+ Assert.assertTrue(initialConnectTried.await(10, TimeUnit.SECONDS));
+
+ Thread.sleep(1000);
+
+ saveConf(hostsFile, "127.0.0.1", "test");
+ validateIP("test", "127.0.0.1");
+ connecting.join(10_000);
+
+ Connection connection = factory.createConnection();
+ connection.close();
+
+ Assert.assertEquals(0, errors.get());
+
+ Assert.assertFalse(connecting.isAlive());
+ }
+
+ // This test is just validating the DNS is not being cached on the separte VM
+ @Test
+ public void testSimpleResolution() throws Throwable {
+ spawnRun(serverLocation, "testSimpleResolution");
+ }
+
+ // called with reflection
+ public static void testSimpleResolution(String[] arg) throws Throwable {
+ // This is just to validate the DNS hosts is picking up the right host
+ saveConf(hostsFile, "192.0.0.1", "test");
+ validateIP("test", "192.0.0.1");
+
+ // and it should not cache anything if the right properties are in place
+ saveConf(hostsFile, "192.0.0.3", "test");
+ validateIP("test", "192.0.0.3");
+ }
+
+ /**
+ * it will continue the test on a spwned VM with the properties we need for this test
+ */
+ private void spawnRun(String location, String... args) throws Throwable {
+ // We have to run part of the test on a separate VM, as we need VM settings to tweak the DNS
+
+ String securityProperties = System.getProperty("java.security.properties");
+
+ if (securityProperties != null && securityProperties.equals(location + "/etc/zerocache.security3")) {
+ System.out.println("No need to spawn a VM, the zerocache is already in place");
+ System.setProperty("artemis.config.location", location);
+ USING_SPAWN = false;
+ main(args);
+ } else {
+
+ securityProperties = "-Djava.security.properties=" + location + "/etc/zerocache.security";
+ String hostProperties = "-Djdk.net.hosts.file=" + location + "/etc/hosts.conf";
+ String configLocation = "-Dartemis.config.location=" + location;
+ String temporaryLocation = "-Djava.io.tmpdir=" + System.getProperty("java.io.tmpdir");
+
+ logger.info("if you would like to run without Spawn for debugging purposes, add these properties to your VM arguments on this test: " + securityProperties + " " + hostProperties);
+ Process p = SpawnedVMSupport.spawnVM(DNSSwitchTest.class.getName(), new String[]{securityProperties, hostProperties, configLocation, temporaryLocation}, args);
+ addProcess(p);
+ Assert.assertEquals(1, p.waitFor());
+ }
+ }
+
+ public static void saveConf(String fileName, String... hostDefinition) throws Exception {
+ if (USE_ETC_HOSTS) {
+ recoverETCHosts();
+ saveConf(ETC_HOSTS, true, hostDefinition);
+ } else {
+ saveConf(new File(fileName), false, hostDefinition);
+ }
+ }
+
+ public static void saveConf(File fileName, boolean append, String... hostDefinition) throws Exception {
+ PrintWriter writer = new PrintWriter(new FileOutputStream(fileName, append));
+ Assert.assertTrue("you must send pairs", hostDefinition.length % 2 == 0);
+
+ if (USE_ETC_HOSTS) {
+ writer.println();
+ writer.println("# this was generated by DNSSwitchTest. Make sure you recover from your backup");
+ }
+
+ for (int i = 0; i < hostDefinition.length; i += 2) {
+ writer.println(hostDefinition[i] + " " + hostDefinition[i + 1]);
+ }
+ writer.close();
+ }
+
+ private static void validateIP(String host, String ip) {
+ InetSocketAddress inetSocketAddress;
+ inetSocketAddress = new InetSocketAddress(host, 8080);
+ // And this is to validate no cache
+ Assert.assertEquals(ip, inetSocketAddress.getAddress().getHostAddress());
+ }
+
+ // This main method will be used with spawnRun to continue the test on a separate VM
+ public static void main(String[] arg) throws Throwable {
+ try {
+
+ String methodName = arg[0];
+
+ Method methodReflection = DNSSwitchTest.class.getMethod(methodName, arg.getClass());
+ methodReflection.invoke(null, new Object[]{arg});
+
+ if (USING_SPAWN) {
+ NetUtil.cleanup();
+ System.exit(1);
+ }
+ } catch (InvocationTargetException e) {
+ e.getCause().printStackTrace();
+ if (USING_SPAWN) {
+ NetUtil.cleanup();
+ System.exit(2);
+ } else {
+ throw e;
+ }
+ } catch (Throwable e) {
+ e.printStackTrace();
+ if (USING_SPAWN) {
+ NetUtil.cleanup();
+ System.exit(2);
+ } else {
+ throw e;
+ }
+ }
+ }
+
+}