/* * 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.stress.journal; import java.util.ArrayList; import java.util.Random; 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.server.ActiveMQServer; import org.apache.activemq.artemis.api.core.RoutingType; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.activemq.artemis.utils.RandomUtil; import org.junit.Test; /** * Simulates the journal being updated, compacted cleared up, * and having multiple restarts, * To make sure the journal would survive at multiple restarts of the server */ public class JournalRestartStressTest extends ActiveMQTestBase { // Constants ----------------------------------------------------- // Attributes ---------------------------------------------------- // Static -------------------------------------------------------- // Constructors -------------------------------------------------- // Public -------------------------------------------------------- @Test public void testLoad() throws Throwable { ActiveMQServer server2 = createServer(true, false); server2.getConfiguration().setJournalFileSize(10 * 1024 * 1024); server2.getConfiguration().setJournalMinFiles(10); server2.getConfiguration().setJournalCompactMinFiles(3); server2.getConfiguration().setJournalCompactPercentage(50); for (int i = 0; i < 10; i++) { server2.start(); ServerLocator locator = createInVMNonHALocator().setMinLargeMessageSize(1024 * 1024).setBlockOnDurableSend(false); ClientSessionFactory sf = createSessionFactory(locator); ClientSession session = sf.createSession(true, true); try { session.createQueue("slow-queue", RoutingType.MULTICAST, "slow-queue"); } catch (Exception ignored) { } session.start(); ClientConsumer consumer = session.createConsumer("slow-queue"); while (true) { System.out.println("Received message from previous"); ClientMessage msg = consumer.receiveImmediate(); if (msg == null) { break; } msg.acknowledge(); } session.close(); produceMessages(sf, 30000); server2.stop(); } } // Package protected --------------------------------------------- /** * @param sf * @param NMSGS * @throws ActiveMQException * @throws InterruptedException * @throws Throwable */ private void produceMessages(final ClientSessionFactory sf, final int NMSGS) throws Throwable { final int TIMEOUT = 5000; System.out.println("sending " + NMSGS + " messages"); final ClientSession sessionSend = sf.createSession(true, true); ClientProducer prod2 = sessionSend.createProducer("slow-queue"); try { sessionSend.createQueue("Queue", "Queue", true); } catch (Exception ignored) { } final ClientSession sessionReceive = sf.createSession(true, true); sessionReceive.start(); final ArrayList<Throwable> errors = new ArrayList<>(); Thread tReceive = new Thread() { @Override public void run() { try { ClientConsumer consumer = sessionReceive.createConsumer("Queue"); for (int i = 0; i < NMSGS; i++) { if (i % 500 == 0) { double percent = (double) i / (double) NMSGS; System.out.println("msgs " + i + " of " + NMSGS + ", " + (int) (percent * 100) + "%"); Thread.sleep(100); } ClientMessage msg = consumer.receive(TIMEOUT); if (msg == null) { errors.add(new Exception("Didn't receive msgs")); break; } msg.acknowledge(); } } catch (Exception e) { errors.add(e); } } }; tReceive.start(); ClientProducer prod = sessionSend.createProducer("Queue"); Random random = new Random(); for (int i = 0; i < NMSGS; i++) { ClientMessage msg = sessionSend.createMessage(true); int size = RandomUtil.randomPositiveInt() % 10024; if (size == 0) { size = 10 * 1024; } byte[] buffer = new byte[size]; random.nextBytes(buffer); msg.getBodyBuffer().writeBytes(buffer); prod.send(msg); if (i % 5000 == 0) { prod2.send(msg); System.out.println("Sending slow message"); } } tReceive.join(); sessionReceive.close(); sessionSend.close(); sf.close(); for (Throwable e : errors) { throw e; } } // Protected ----------------------------------------------------- // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }