/* * 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.integration.cluster.failover; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.api.core.TransportConfiguration; import org.apache.activemq.artemis.api.core.client.ClientConsumer; import org.apache.activemq.artemis.api.core.client.ClientMessage; import org.apache.activemq.artemis.api.core.client.ClientProducer; import org.apache.activemq.artemis.api.core.client.ClientSession; import org.apache.activemq.artemis.api.core.client.ClientSessionFactory; import org.apache.activemq.artemis.api.core.client.ServerLocator; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; import org.apache.activemq.artemis.core.client.impl.ServerLocatorImpl; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.jms.client.ActiveMQTextMessage; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.junit.Assert; public abstract class MultipleBackupsFailoverTestBase extends ActiveMQTestBase { IntegrationTestLogger log = IntegrationTestLogger.LOGGER; protected abstract boolean isNetty(); protected int waitForNewLive(long seconds, boolean waitForNewBackup, Map<Integer, TestableServer> servers, int... nodes) { long time = System.currentTimeMillis(); long toWait = seconds * 1000; int newLive = -1; while (true) { for (int node : nodes) { TestableServer backupServer = servers.get(node); if (newLive == -1 && backupServer.isActive()) { newLive = node; } else if (newLive != -1) { if (waitForNewBackup) { if (node != newLive && servers.get(node).isStarted()) { return newLive; } } else { return newLive; } } } try { Thread.sleep(100); } catch (InterruptedException e) { // ignore } if (System.currentTimeMillis() > (time + toWait)) { Assert.fail("backup server never started"); } } } protected ClientSession sendAndConsume(final ClientSessionFactory sf, final boolean createQueue) throws Exception { ClientSession session = sf.createSession(false, true, true); if (createQueue) { session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, false); } ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS); final int numMessages = 1000; for (int i = 0; i < numMessages; i++) { ClientMessage message = session.createMessage(ActiveMQTextMessage.TYPE, false, 0, System.currentTimeMillis(), (byte) 1); message.putIntProperty(new SimpleString("count"), i); message.getBodyBuffer().writeString("aardvarks"); producer.send(message); } ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS); session.start(); for (int i = 0; i < numMessages; i++) { ClientMessage message2 = consumer.receive(10000); Assert.assertNotNull(message2); Assert.assertEquals("aardvarks", message2.getBodyBuffer().readString()); Assert.assertEquals(i, message2.getObjectProperty(new SimpleString("count"))); message2.acknowledge(); } ClientMessage message3 = consumer.receiveImmediate(); Assert.assertNull(message3); return session; } protected ClientSessionFactoryInternal createSessionFactoryAndWaitForTopology(ServerLocator locator, int topologyMembers) throws Exception { return createSessionFactoryAndWaitForTopology(locator, topologyMembers, null); } protected ClientSessionFactoryInternal createSessionFactoryAndWaitForTopology(ServerLocator locator, int topologyMembers, ActiveMQServer server) throws Exception { ClientSessionFactoryInternal sf; CountDownLatch countDownLatch = new CountDownLatch(topologyMembers); FailoverTestBase.LatchClusterTopologyListener topListener = new FailoverTestBase.LatchClusterTopologyListener(countDownLatch); locator.addClusterTopologyListener(topListener); sf = (ClientSessionFactoryInternal) locator.createSessionFactory(); addSessionFactory(sf); boolean ok = countDownLatch.await(5, TimeUnit.SECONDS); locator.removeClusterTopologyListener(topListener); if (!ok) { if (server != null) { log.info("failed topology, Topology on server = " + server.getClusterManager().describe()); } } Assert.assertTrue("expected " + topologyMembers + " members", ok); return sf; } public ServerLocator getServerLocator(int... nodes) { TransportConfiguration[] configs = new TransportConfiguration[nodes.length]; for (int i = 0, configsLength = configs.length; i < configsLength; i++) { configs[i] = createTransportConfiguration(isNetty(), false, generateParams(nodes[i], isNetty())); } return addServerLocator(new ServerLocatorImpl(true, configs)); } }