/*
* 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.client;
import javax.jms.BytesMessage;
import javax.jms.Connection;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger;
import org.apache.activemq.artemis.tests.util.JMSTestBase;
import org.junit.Before;
import org.junit.Test;
/**
* This will perform cleanup tests on paging while using JMS topics
*/
public class JMSPagingFileDeleteTest extends JMSTestBase {
static IntegrationTestLogger log = IntegrationTestLogger.LOGGER;
Topic topic1;
Connection connection;
Session session;
MessageConsumer subscriber1;
MessageConsumer subscriber2;
PagingStore pagingStore;
private static final int MESSAGE_SIZE = 1024;
private static final int PAGE_SIZE = 10 * 1024;
private static final int PAGE_MAX = 20 * 1024;
private static final int RECEIVE_TIMEOUT = 500;
private static final int MESSAGE_NUM = 50;
@Override
protected boolean usePersistence() {
return true;
}
@Override
@Before
public void setUp() throws Exception {
super.setUp();
topic1 = createTopic("topic1");
// Paging Setting
AddressSettings setting = new AddressSettings().setPageSizeBytes(JMSPagingFileDeleteTest.PAGE_SIZE).setMaxSizeBytes(JMSPagingFileDeleteTest.PAGE_MAX);
server.getAddressSettingsRepository().addMatch("#", setting);
}
/**
* Test replicating issue JBPAPP-9603
*
* @throws Exception
*/
@Test
public void testTopicsWithNonDurableSubscription() throws Exception {
connection = null;
try {
for (int repeat = 0; repeat < 2; repeat++) {
connection = cf.createConnection();
connection.setClientID("cid");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(topic1);
subscriber1 = session.createConsumer(topic1);
// -----------------(Step1) Publish Messages to make Paging Files. --------------------
System.out.println("---------- Send messages. ----------");
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(new byte[JMSPagingFileDeleteTest.MESSAGE_SIZE]);
for (int i = 0; i < JMSPagingFileDeleteTest.MESSAGE_NUM; i++) {
producer.send(bytesMessage);
}
System.out.println("Sent " + JMSPagingFileDeleteTest.MESSAGE_NUM + " messages.");
pagingStore = server.getPagingManager().getPageStore(new SimpleString("topic1"));
printPageStoreInfo(pagingStore);
assertTrue(pagingStore.isPaging());
// -----------------(Step2) Closing the connection alone should cleanup pages -------
connection.close();
// note that if we closed subscriber or session the bug wouldn't happen
// as they were already deleting the page-subscription properly
// So, you can't close subscriber1 or session as that would change the test
//subscriber1.close(); // << you can't call this on this test
//session.close(); // << can't call this on this test
long timeout = System.currentTimeMillis() + 5000;
while (timeout > System.currentTimeMillis() && pagingStore.isPaging()) {
Thread.sleep(100);
}
printPageStoreInfo(pagingStore);
assertFalse(pagingStore.isPaging());
}
} finally {
if (connection != null) {
connection.close();
}
}
}
@Test
public void testTopics() throws Exception {
connection = null;
try {
connection = cf.createConnection();
connection.setClientID("cid");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(topic1);
subscriber1 = session.createDurableSubscriber(topic1, "subscriber-1");
subscriber2 = session.createDurableSubscriber(topic1, "subscriber-2");
// -----------------(Step1) Publish Messages to make Paging Files. --------------------
System.out.println("---------- Send messages. ----------");
BytesMessage bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(new byte[JMSPagingFileDeleteTest.MESSAGE_SIZE]);
for (int i = 0; i < JMSPagingFileDeleteTest.MESSAGE_NUM; i++) {
producer.send(bytesMessage);
}
System.out.println("Sent " + JMSPagingFileDeleteTest.MESSAGE_NUM + " messages.");
pagingStore = server.getPagingManager().getPageStore(new SimpleString("topic1"));
printPageStoreInfo(pagingStore);
assertTrue(pagingStore.isPaging());
connection.start();
// -----------------(Step2) Restart the server. --------------------------------------
stopAndStartServer(); // If try this test without restarting server, please comment out this line;
// -----------------(Step3) Subscribe to all the messages from the topic.--------------
System.out.println("---------- Receive all messages. ----------");
for (int i = 0; i < JMSPagingFileDeleteTest.MESSAGE_NUM; i++) {
Message message1 = subscriber1.receive(JMSPagingFileDeleteTest.RECEIVE_TIMEOUT);
assertNotNull(message1);
Message message2 = subscriber2.receive(JMSPagingFileDeleteTest.RECEIVE_TIMEOUT);
assertNotNull(message2);
}
pagingStore = server.getPagingManager().getPageStore(new SimpleString("topic1"));
long timeout = System.currentTimeMillis() + 5000;
while (timeout > System.currentTimeMillis() && pagingStore.isPaging()) {
Thread.sleep(100);
}
assertFalse(pagingStore.isPaging());
printPageStoreInfo(pagingStore);
assertEquals(0, pagingStore.getAddressSize());
// assertEquals(1, pagingStore.getNumberOfPages()); //I expected number of the page is 1, but It was not.
assertFalse(pagingStore.isPaging()); // I expected IsPaging is false, but It was true.
// If the server is not restart, this test pass.
// -----------------(Step4) Publish a message. the message is stored in the paging file.
producer = session.createProducer(topic1);
bytesMessage = session.createBytesMessage();
bytesMessage.writeBytes(new byte[JMSPagingFileDeleteTest.MESSAGE_SIZE]);
producer.send(bytesMessage);
printPageStoreInfo(pagingStore);
timeout = System.currentTimeMillis() + 10000;
while (timeout > System.currentTimeMillis() && pagingStore.getNumberOfPages() != 1) {
Thread.sleep(100);
}
assertEquals(1, pagingStore.getNumberOfPages()); //I expected number of the page is 1, but It was not.
} finally {
if (connection != null) {
connection.close();
}
}
}
private void stopAndStartServer() throws Exception {
System.out.println("---------- Restart server. ----------");
connection.close();
jmsServer.stop();
jmsServer.start();
jmsServer.activated();
registerConnectionFactory();
printPageStoreInfo(pagingStore);
reconnect();
}
private void reconnect() throws Exception {
connection = cf.createConnection();
connection.setClientID("cid");
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
subscriber1 = session.createDurableSubscriber(topic1, "subscriber-1");
subscriber2 = session.createDurableSubscriber(topic1, "subscriber-2");
connection.start();
}
private void printPageStoreInfo(PagingStore pagingStore) throws Exception {
System.out.println("---------- Paging Store Info ----------");
System.out.println(" CurrentPage = " + pagingStore.getCurrentPage());
System.out.println(" FirstPage = " + pagingStore.getFirstPage());
System.out.println(" Number of Pages = " + pagingStore.getNumberOfPages());
System.out.println(" Address Size = " + pagingStore.getAddressSize());
System.out.println(" Is Paging = " + pagingStore.isPaging());
}
}