/* * 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.HashMap; 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.ServerLocator; import org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryInternal; import org.apache.activemq.artemis.core.config.Configuration; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.Queue; import org.apache.activemq.artemis.core.settings.impl.AddressSettings; import org.apache.activemq.artemis.tests.integration.cluster.util.SameProcessActiveMQServer; import org.apache.activemq.artemis.tests.integration.cluster.util.TestableServer; import org.apache.activemq.artemis.tests.util.TransportConfigurationUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * A PagingFailoverTest * <br> * TODO: validate replication failover also */ public class PagingFailoverTest extends FailoverTestBase { // Constants ----------------------------------------------------- private static final SimpleString ADDRESS = new SimpleString("SimpleAddress"); private ServerLocator locator; private ClientSession session; private ClientSessionFactoryInternal sf; // Static -------------------------------------------------------- // Constructors -------------------------------------------------- // Public -------------------------------------------------------- @Override @Before public void setUp() throws Exception { super.setUp(); locator = getServerLocator(); } @Test public void testPageFailBeforeConsume() throws Exception { internalTestPage(false, true); } @Test public void testPage() throws Exception { internalTestPage(false, false); } @Test public void testPageTransactioned() throws Exception { internalTestPage(true, false); } @Test public void testPageTransactionedFailBeforeConsume() throws Exception { internalTestPage(true, true); } public void internalTestPage(final boolean transacted, final boolean failBeforeConsume) throws Exception { locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(-1); sf = createSessionFactoryAndWaitForTopology(locator, 2); session = addClientSession(sf.createSession(!transacted, !transacted, 0)); session.createQueue(PagingFailoverTest.ADDRESS, PagingFailoverTest.ADDRESS, true); ClientProducer prod = session.createProducer(PagingFailoverTest.ADDRESS); final int TOTAL_MESSAGES = 2000; for (int i = 0; i < TOTAL_MESSAGES; i++) { if (transacted && i % 10 == 0) { session.commit(); } ClientMessage msg = session.createMessage(true); msg.putIntProperty(new SimpleString("key"), i); prod.send(msg); } session.commit(); if (failBeforeConsume) { crash(session); waitForBackup(null, 5); } session.close(); session = sf.createSession(!transacted, !transacted, 0); session.start(); ClientConsumer cons = session.createConsumer(PagingFailoverTest.ADDRESS); final int MIDDLE = TOTAL_MESSAGES / 2; for (int i = 0; i < MIDDLE; i++) { ClientMessage msg = cons.receive(20000); Assert.assertNotNull(msg); msg.acknowledge(); if (transacted && i % 10 == 0) { session.commit(); } Assert.assertEquals(i, msg.getObjectProperty(new SimpleString("key"))); } session.commit(); cons.close(); Thread.sleep(1000); if (!failBeforeConsume) { crash(session); // failSession(session, latch); } session.close(); session = sf.createSession(true, true, 0); cons = session.createConsumer(PagingFailoverTest.ADDRESS); session.start(); for (int i = MIDDLE; i < TOTAL_MESSAGES; i++) { ClientMessage msg = cons.receive(5000); Assert.assertNotNull(msg); msg.acknowledge(); int result = (Integer) msg.getObjectProperty(new SimpleString("key")); Assert.assertEquals(i, result); } } @Test public void testExpireMessage() throws Exception { locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true).setReconnectAttempts(-1); ClientSessionFactoryInternal sf = createSessionFactoryAndWaitForTopology(locator, 2); session = sf.createSession(true, true, 0); session.createQueue(PagingFailoverTest.ADDRESS, PagingFailoverTest.ADDRESS, true); ClientProducer prod = session.createProducer(PagingFailoverTest.ADDRESS); final int TOTAL_MESSAGES = 1000; for (int i = 0; i < TOTAL_MESSAGES; i++) { ClientMessage msg = session.createMessage(true); msg.putIntProperty(new SimpleString("key"), i); msg.setExpiration(System.currentTimeMillis() + 1000); prod.send(msg); } crash(session); session.close(); Queue queue = backupServer.getServer().locateQueue(ADDRESS); long timeout = System.currentTimeMillis() + 60000; while (timeout > System.currentTimeMillis() && queue.getPageSubscription().isPaging()) { Thread.sleep(100); // Simulating what would happen on expire queue.expireReferences(); } Assert.assertFalse(queue.getPageSubscription().isPaging()); } // Package protected --------------------------------------------- // Protected ----------------------------------------------------- @Override protected TransportConfiguration getAcceptorTransportConfiguration(final boolean live) { return TransportConfigurationUtils.getInVMAcceptor(live); } @Override protected TransportConfiguration getConnectorTransportConfiguration(final boolean live) { return TransportConfigurationUtils.getInVMConnector(live); } @Override protected ActiveMQServer createServer(final boolean realFiles, final Configuration configuration) { return addServer(createInVMFailoverServer(true, configuration, PAGE_SIZE, PAGE_MAX, new HashMap<String, AddressSettings>(), nodeManager, 2)); } @Override protected TestableServer createTestableServer(Configuration config) { return new SameProcessActiveMQServer(createServer(true, config)); } }