/*
* 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.unit.core.paging.impl;
import java.io.File;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import org.apache.activemq.artemis.api.core.ActiveMQBuffer;
import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.io.SequentialFileFactory;
import org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory;
import org.apache.activemq.artemis.core.message.impl.CoreMessage;
import org.apache.activemq.artemis.core.message.impl.CoreMessagePersister;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.paging.PagingStoreFactory;
import org.apache.activemq.artemis.core.paging.cursor.PageCursorProvider;
import org.apache.activemq.artemis.core.paging.cursor.impl.PageCursorProviderImpl;
import org.apache.activemq.artemis.core.paging.impl.Page;
import org.apache.activemq.artemis.core.paging.impl.PageTransactionInfoImpl;
import org.apache.activemq.artemis.core.paging.impl.PagingStoreImpl;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.persistence.impl.nullpm.NullStorageManager;
import org.apache.activemq.artemis.core.protocol.core.impl.CoreProtocolManagerFactory;
import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.impl.RoutingContextImpl;
import org.apache.activemq.artemis.core.settings.HierarchicalRepository;
import org.apache.activemq.artemis.core.settings.impl.AddressFullMessagePolicy;
import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
import org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessagePersister;
import org.apache.activemq.artemis.protocol.amqp.broker.ProtonProtocolManagerFactory;
import org.apache.activemq.artemis.spi.core.protocol.MessagePersister;
import org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.FakeSequentialFileFactory;
import org.apache.activemq.artemis.tests.unit.util.FakePagingManager;
import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
import org.apache.activemq.artemis.utils.ActiveMQThreadFactory;
import org.apache.activemq.artemis.utils.ExecutorFactory;
import org.apache.activemq.artemis.utils.RandomUtil;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class PagingStoreImplTest extends ActiveMQTestBase {
static {
MessagePersister.registerPersister(CoreProtocolManagerFactory.ID, CoreMessagePersister.getInstance());
MessagePersister.registerPersister(ProtonProtocolManagerFactory.ID, AMQPMessagePersister.getInstance());
}
private static final SimpleString destinationTestName = new SimpleString("test");
private final ReadLock lock = new ReentrantReadWriteLock().readLock();
protected ExecutorService executor;
@Test
public void testAddAndRemoveMessages() {
long id1 = RandomUtil.randomLong();
long id2 = RandomUtil.randomLong();
PageTransactionInfo trans = new PageTransactionInfoImpl(id2);
trans.setRecordID(id1);
// anything between 2 and 100
int nr1 = RandomUtil.randomPositiveInt() % 98 + 2;
for (int i = 0; i < nr1; i++) {
trans.increment(1, 0);
}
Assert.assertEquals(nr1, trans.getNumberOfMessages());
ActiveMQBuffer buffer = ActiveMQBuffers.fixedBuffer(trans.getEncodeSize());
trans.encode(buffer);
PageTransactionInfo trans2 = new PageTransactionInfoImpl(id1);
trans2.decode(buffer);
Assert.assertEquals(id2, trans2.getTransactionID());
Assert.assertEquals(nr1, trans2.getNumberOfMessages());
}
@Test
public void testDoubleStart() throws Exception {
SequentialFileFactory factory = new FakeSequentialFileFactory();
PagingStore storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, new FakeStoreFactory(factory), PagingStoreImplTest.destinationTestName, new AddressSettings().setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE), getExecutorFactory().getExecutor(), true);
storeImpl.start();
// this is not supposed to throw an exception.
// As you could have start being called twice as Stores are dynamically
// created, on a multi-thread environment
storeImpl.start();
storeImpl.stop();
}
@Test
public void testPageWithNIO() throws Exception {
ActiveMQTestBase.recreateDirectory(getTestDir());
testConcurrentPaging(new NIOSequentialFileFactory(new File(getTestDir()), 1), 1);
}
@Test
public void testStore() throws Exception {
SequentialFileFactory factory = new FakeSequentialFileFactory();
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
AddressSettings addressSettings = new AddressSettings().setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
PagingStore storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, PagingStoreImplTest.destinationTestName, addressSettings, getExecutorFactory().getExecutor(), true);
storeImpl.start();
Assert.assertEquals(0, storeImpl.getNumberOfPages());
storeImpl.startPaging();
Assert.assertEquals(1, storeImpl.getNumberOfPages());
List<ActiveMQBuffer> buffers = new ArrayList<>();
ActiveMQBuffer buffer = createRandomBuffer(0, 10);
buffers.add(buffer);
SimpleString destination = new SimpleString("test");
Message msg = createMessage(1, storeImpl, destination, buffer);
Assert.assertTrue(storeImpl.isPaging());
final RoutingContextImpl ctx = new RoutingContextImpl(null);
Assert.assertTrue(storeImpl.page(msg, ctx.getTransaction(), ctx.getContextListing(storeImpl.getStoreName()), lock));
Assert.assertEquals(1, storeImpl.getNumberOfPages());
storeImpl.sync();
storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, PagingStoreImplTest.destinationTestName, addressSettings, getExecutorFactory().getExecutor(), true);
storeImpl.start();
Assert.assertEquals(1, storeImpl.getNumberOfPages());
}
@Test
public void testDepageOnCurrentPage() throws Exception {
SequentialFileFactory factory = new FakeSequentialFileFactory();
SimpleString destination = new SimpleString("test");
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
PagingStoreImpl storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, PagingStoreImplTest.destinationTestName, new AddressSettings().setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE), getExecutorFactory().getExecutor(), true);
storeImpl.start();
Assert.assertEquals(0, storeImpl.getNumberOfPages());
storeImpl.startPaging();
List<ActiveMQBuffer> buffers = new ArrayList<>();
int numMessages = 10;
for (int i = 0; i < numMessages; i++) {
ActiveMQBuffer buffer = createRandomBuffer(i + 1L, 10);
buffers.add(buffer);
Message msg = createMessage(i, storeImpl, destination, buffer);
final RoutingContextImpl ctx = new RoutingContextImpl(null);
Assert.assertTrue(storeImpl.page(msg, ctx.getTransaction(), ctx.getContextListing(storeImpl.getStoreName()), lock));
}
Assert.assertEquals(1, storeImpl.getNumberOfPages());
storeImpl.sync();
Page page = storeImpl.depage();
page.open();
List<PagedMessage> msg = page.read(new NullStorageManager());
Assert.assertEquals(numMessages, msg.size());
Assert.assertEquals(1, storeImpl.getNumberOfPages());
page = storeImpl.depage();
Assert.assertNull(page);
Assert.assertEquals(0, storeImpl.getNumberOfPages());
for (int i = 0; i < numMessages; i++) {
ActiveMQBuffer horn1 = buffers.get(i);
ActiveMQBuffer horn2 = msg.get(i).getMessage().toCore().getBodyBuffer();
horn1.resetReaderIndex();
horn2.resetReaderIndex();
for (int j = 0; j < horn1.writerIndex(); j++) {
Assert.assertEquals(horn1.readByte(), horn2.readByte());
}
}
}
@Test
public void testDepageMultiplePages() throws Exception {
SequentialFileFactory factory = new FakeSequentialFileFactory();
SimpleString destination = new SimpleString("test");
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
PagingStoreImpl store = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, PagingStoreImplTest.destinationTestName, new AddressSettings().setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE), getExecutorFactory().getExecutor(), true);
store.start();
Assert.assertEquals(0, store.getNumberOfPages());
store.startPaging();
Assert.assertEquals(1, store.getNumberOfPages());
List<ActiveMQBuffer> buffers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
ActiveMQBuffer buffer = createRandomBuffer(i + 1L, 10);
buffers.add(buffer);
if (i == 5) {
store.forceAnotherPage();
}
Message msg = createMessage(i, store, destination, buffer);
final RoutingContextImpl ctx = new RoutingContextImpl(null);
Assert.assertTrue(store.page(msg, ctx.getTransaction(), ctx.getContextListing(store.getStoreName()), lock));
}
Assert.assertEquals(2, store.getNumberOfPages());
store.sync();
int sequence = 0;
for (int pageNr = 0; pageNr < 2; pageNr++) {
Page page = store.depage();
System.out.println("numberOfPages = " + store.getNumberOfPages());
page.open();
List<PagedMessage> msg = page.read(new NullStorageManager());
page.close();
Assert.assertEquals(5, msg.size());
for (int i = 0; i < 5; i++) {
Assert.assertEquals(sequence++, msg.get(i).getMessage().getMessageID());
ActiveMQTestBase.assertEqualsBuffers(18, buffers.get(pageNr * 5 + i), msg.get(i).getMessage().toCore().getBodyBuffer());
}
}
Assert.assertEquals(1, store.getNumberOfPages());
Assert.assertTrue(store.isPaging());
Message msg = createMessage(1, store, destination, buffers.get(0));
final RoutingContextImpl ctx = new RoutingContextImpl(null);
Assert.assertTrue(store.page(msg, ctx.getTransaction(), ctx.getContextListing(store.getStoreName()), lock));
Page newPage = store.depage();
newPage.open();
Assert.assertEquals(1, newPage.read(new NullStorageManager()).size());
newPage.delete(null);
Assert.assertEquals(1, store.getNumberOfPages());
Assert.assertTrue(store.isPaging());
Assert.assertNull(store.depage());
Assert.assertFalse(store.isPaging());
{
final RoutingContextImpl ctx2 = new RoutingContextImpl(null);
Assert.assertFalse(store.page(msg, ctx2.getTransaction(), ctx2.getContextListing(store.getStoreName()), lock));
}
store.startPaging();
{
final RoutingContextImpl ctx2 = new RoutingContextImpl(null);
Assert.assertTrue(store.page(msg, ctx2.getTransaction(), ctx2.getContextListing(store.getStoreName()), lock));
}
Page page = store.depage();
page.open();
List<PagedMessage> msgs = page.read(new NullStorageManager());
Assert.assertEquals(1, msgs.size());
Assert.assertEquals(1L, msgs.get(0).getMessage().getMessageID());
ActiveMQTestBase.assertEqualsBuffers(18, buffers.get(0), msgs.get(0).getMessage().toCore().getBodyBuffer());
Assert.assertEquals(1, store.getNumberOfPages());
Assert.assertTrue(store.isPaging());
Assert.assertNull(store.depage());
Assert.assertEquals(0, store.getNumberOfPages());
page.open();
}
@Test
public void testConcurrentDepage() throws Exception {
SequentialFileFactory factory = new FakeSequentialFileFactory(1, false);
testConcurrentPaging(factory, 10);
}
protected void testConcurrentPaging(final SequentialFileFactory factory,
final int numberOfThreads) throws Exception {
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
final int MAX_SIZE = 1024 * 10;
final AtomicLong messageIdGenerator = new AtomicLong(0);
final AtomicInteger aliveProducers = new AtomicInteger(numberOfThreads);
final CountDownLatch latchStart = new CountDownLatch(numberOfThreads);
final ConcurrentHashMap<Long, Message> buffers = new ConcurrentHashMap<>();
final ArrayList<Page> readPages = new ArrayList<>();
AddressSettings settings = new AddressSettings().setPageSizeBytes(MAX_SIZE).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
final PagingStore storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, new SimpleString("test"), settings, getExecutorFactory().getExecutor(), true);
storeImpl.start();
Assert.assertEquals(0, storeImpl.getNumberOfPages());
// Marked the store to be paged
storeImpl.startPaging();
Assert.assertEquals(1, storeImpl.getNumberOfPages());
final SimpleString destination = new SimpleString("test");
class WriterThread extends Thread {
Exception e;
@Override
public void run() {
try {
boolean firstTime = true;
while (true) {
long id = messageIdGenerator.incrementAndGet();
// Each thread will Keep paging until all the messages are depaged.
// This is possible because the depage thread is not actually reading the pages.
// Just using the internal API to remove it from the page file system
Message msg = createMessage(id, storeImpl, destination, createRandomBuffer(id, 5));
final RoutingContextImpl ctx2 = new RoutingContextImpl(null);
if (storeImpl.page(msg, ctx2.getTransaction(), ctx2.getContextListing(storeImpl.getStoreName()), lock)) {
buffers.put(id, msg);
} else {
break;
}
if (firstTime) {
// We have at least one data paged. So, we can start depaging now
latchStart.countDown();
firstTime = false;
}
}
} catch (Exception e1) {
e1.printStackTrace();
this.e = e1;
} finally {
aliveProducers.decrementAndGet();
}
}
}
final class ReaderThread extends Thread {
Exception e;
@Override
public void run() {
try {
// Wait every producer to produce at least one message
ActiveMQTestBase.waitForLatch(latchStart);
while (aliveProducers.get() > 0) {
Page page = storeImpl.depage();
if (page != null) {
readPages.add(page);
}
}
} catch (Exception e1) {
e1.printStackTrace();
this.e = e1;
}
}
}
WriterThread[] producerThread = new WriterThread[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
producerThread[i] = new WriterThread();
producerThread[i].start();
}
ReaderThread consumer = new ReaderThread();
consumer.start();
for (int i = 0; i < numberOfThreads; i++) {
producerThread[i].join();
if (producerThread[i].e != null) {
throw producerThread[i].e;
}
}
consumer.join();
if (consumer.e != null) {
throw consumer.e;
}
final ConcurrentMap<Long, Message> buffers2 = new ConcurrentHashMap<>();
for (Page page : readPages) {
page.open();
List<PagedMessage> msgs = page.read(new NullStorageManager());
page.close();
for (PagedMessage msg : msgs) {
long id = msg.getMessage().toCore().getBodyBuffer().readLong();
msg.getMessage().toCore().getBodyBuffer().resetReaderIndex();
Message msgWritten = buffers.remove(id);
buffers2.put(id, msg.getMessage());
Assert.assertNotNull(msgWritten);
Assert.assertEquals(msg.getMessage().getAddress(), msgWritten.getAddress());
ActiveMQTestBase.assertEqualsBuffers(10, msgWritten.toCore().getBodyBuffer(), msg.getMessage().toCore().getBodyBuffer());
}
}
Assert.assertEquals(0, buffers.size());
List<String> files = factory.listFiles("page");
Assert.assertTrue(files.size() != 0);
for (String file : files) {
SequentialFile fileTmp = factory.createSequentialFile(file);
fileTmp.open();
Assert.assertTrue("The page file size (" + fileTmp.size() + ") shouldn't be > " + MAX_SIZE, fileTmp.size() <= MAX_SIZE);
fileTmp.close();
}
PagingStore storeImpl2 = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, new SimpleString("test"), settings, getExecutorFactory().getExecutor(), true);
storeImpl2.start();
int numberOfPages = storeImpl2.getNumberOfPages();
Assert.assertTrue(numberOfPages != 0);
storeImpl2.startPaging();
storeImpl2.startPaging();
Assert.assertEquals(numberOfPages, storeImpl2.getNumberOfPages());
long lastMessageId = messageIdGenerator.incrementAndGet();
Message lastMsg = createMessage(lastMessageId, storeImpl, destination, createRandomBuffer(lastMessageId, 5));
storeImpl2.forceAnotherPage();
final RoutingContextImpl ctx = new RoutingContextImpl(null);
storeImpl2.page(lastMsg, ctx.getTransaction(), ctx.getContextListing(storeImpl2.getStoreName()), lock);
buffers2.put(lastMessageId, lastMsg);
Page lastPage = null;
while (true) {
Page page = storeImpl2.depage();
if (page == null) {
break;
}
lastPage = page;
page.open();
List<PagedMessage> msgs = page.read(new NullStorageManager());
page.close();
for (PagedMessage msg : msgs) {
long id = msg.getMessage().toCore().getBodyBuffer().readLong();
Message msgWritten = buffers2.remove(id);
Assert.assertNotNull(msgWritten);
Assert.assertEquals(msg.getMessage().getAddress(), msgWritten.getAddress());
ActiveMQTestBase.assertEqualsByteArrays(msgWritten.toCore().getBodyBuffer().writerIndex(), msgWritten.toCore().getBodyBuffer().toByteBuffer().array(), msg.getMessage().toCore().getBodyBuffer().toByteBuffer().array());
}
}
lastPage.open();
List<PagedMessage> lastMessages = lastPage.read(new NullStorageManager());
lastPage.close();
Assert.assertEquals(1, lastMessages.size());
lastMessages.get(0).getMessage().toCore().getBodyBuffer().resetReaderIndex();
Assert.assertEquals(lastMessages.get(0).getMessage().toCore().getBodyBuffer().readLong(), lastMessageId);
Assert.assertEquals(0, buffers2.size());
Assert.assertEquals(0, storeImpl.getAddressSize());
}
@Test
public void testRestartPage() throws Throwable {
clearDataRecreateServerDirs();
SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
final int MAX_SIZE = 1024 * 10;
AddressSettings settings = new AddressSettings().setPageSizeBytes(MAX_SIZE).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
final PagingStore storeImpl = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, new SimpleString("test"), settings, getExecutorFactory().getExecutor(), true);
storeImpl.start();
Assert.assertEquals(0, storeImpl.getNumberOfPages());
// Marked the store to be paged
storeImpl.startPaging();
storeImpl.depage();
Assert.assertNull(storeImpl.getCurrentPage());
storeImpl.startPaging();
Assert.assertNotNull(storeImpl.getCurrentPage());
storeImpl.stop();
}
@Test
public void testOrderOnPaging() throws Throwable {
clearDataRecreateServerDirs();
SequentialFileFactory factory = new NIOSequentialFileFactory(new File(getPageDir()), 1);
PagingStoreFactory storeFactory = new FakeStoreFactory(factory);
final int MAX_SIZE = 1024 * 10;
AddressSettings settings = new AddressSettings().setPageSizeBytes(MAX_SIZE).setAddressFullMessagePolicy(AddressFullMessagePolicy.PAGE);
final PagingStore store = new PagingStoreImpl(PagingStoreImplTest.destinationTestName, null, 100, createMockManager(), createStorageManagerMock(), factory, storeFactory, new SimpleString("test"), settings, getExecutorFactory().getExecutor(), false);
store.start();
Assert.assertEquals(0, store.getNumberOfPages());
// Marked the store to be paged
store.startPaging();
final CountDownLatch producedLatch = new CountDownLatch(1);
Assert.assertEquals(1, store.getNumberOfPages());
final SimpleString destination = new SimpleString("test");
final long NUMBER_OF_MESSAGES = 100000;
final List<Throwable> errors = new ArrayList<>();
class WriterThread extends Thread {
WriterThread() {
super("PageWriter");
}
@Override
public void run() {
try {
for (long i = 0; i < NUMBER_OF_MESSAGES; i++) {
// Each thread will Keep paging until all the messages are depaged.
// This is possible because the depage thread is not actually reading the pages.
// Just using the internal API to remove it from the page file system
Message msg = createMessage(i, store, destination, createRandomBuffer(i, 1024));
msg.putLongProperty("count", i);
final RoutingContextImpl ctx2 = new RoutingContextImpl(null);
while (!store.page(msg, ctx2.getTransaction(), ctx2.getContextListing(store.getStoreName()), lock)) {
store.startPaging();
}
if (i == 0) {
producedLatch.countDown();
}
}
} catch (Throwable e) {
e.printStackTrace();
errors.add(e);
}
}
}
class ReaderThread extends Thread {
ReaderThread() {
super("PageReader");
}
@Override
public void run() {
try {
long msgsRead = 0;
while (msgsRead < NUMBER_OF_MESSAGES) {
Page page = store.depage();
if (page != null) {
page.open();
List<PagedMessage> messages = page.read(new NullStorageManager());
for (PagedMessage pgmsg : messages) {
Message msg = pgmsg.getMessage();
Assert.assertEquals(msgsRead++, msg.getMessageID());
Assert.assertEquals(msg.getMessageID(), msg.getLongProperty("count").longValue());
}
page.close();
page.delete(null);
} else {
System.out.println("Depaged!!!! numerOfMessages = " + msgsRead + " of " + NUMBER_OF_MESSAGES);
Thread.sleep(500);
}
}
} catch (Throwable e) {
e.printStackTrace();
errors.add(e);
}
}
}
WriterThread producerThread = new WriterThread();
producerThread.start();
ReaderThread consumer = new ReaderThread();
consumer.start();
producerThread.join();
consumer.join();
store.stop();
for (Throwable e : errors) {
throw e;
}
}
/**
* @return
*/
protected PagingManager createMockManager() {
return new FakePagingManager();
}
private StorageManager createStorageManagerMock() {
return new NullStorageManager();
}
private ExecutorFactory getExecutorFactory() {
return new ExecutorFactory() {
@Override
public Executor getExecutor() {
return executor;
}
};
}
private CoreMessage createMessage(final long id,
final PagingStore store,
final SimpleString destination,
final ActiveMQBuffer buffer) {
CoreMessage msg = new CoreMessage(id, 50 + buffer.capacity());
msg.setAddress(destination);
msg.setContext(store);
msg.getBodyBuffer().resetReaderIndex();
msg.getBodyBuffer().resetWriterIndex();
msg.getBodyBuffer().writeBytes(buffer, buffer.capacity());
return msg;
}
protected ActiveMQBuffer createRandomBuffer(final long id, final int size) {
return RandomUtil.randomBuffer(size, id);
}
// Protected ----------------------------------------------------
@Override
@Before
public void setUp() throws Exception {
super.setUp();
executor = Executors.newSingleThreadExecutor(ActiveMQThreadFactory.defaultThreadFactory());
}
@Override
@After
public void tearDown() throws Exception {
executor.shutdown();
super.tearDown();
}
static final class FakeStoreFactory implements PagingStoreFactory {
final SequentialFileFactory factory;
FakeStoreFactory() {
factory = new FakeSequentialFileFactory();
}
FakeStoreFactory(final SequentialFileFactory factory) {
this.factory = factory;
}
@Override
public SequentialFileFactory newFileFactory(final SimpleString destinationName) throws Exception {
return factory;
}
@Override
public PagingStore newStore(final SimpleString destinationName, final AddressSettings addressSettings) {
return null;
}
@Override
public List<PagingStore> reloadStores(final HierarchicalRepository<AddressSettings> addressSettingsRepository) throws Exception {
return null;
}
@Override
public PageCursorProvider newCursorProvider(PagingStore store,
StorageManager storageManager,
AddressSettings addressSettings,
Executor executor) {
return new PageCursorProviderImpl(store, storageManager, executor, addressSettings.getPageCacheMaxSize());
}
@Override
public void setPagingManager(final PagingManager manager) {
}
@Override
public void stop() throws InterruptedException {
}
@Override
public void injectMonitor(FileStoreMonitor monitor) throws Exception {
}
public void beforePageRead() throws Exception {
}
public void afterPageRead() throws Exception {
}
public ByteBuffer allocateDirectBuffer(final int size) {
return ByteBuffer.allocateDirect(size);
}
public void freeDirectuffer(final ByteBuffer buffer) {
}
}
}