use of org.apache.activemq.artemis.core.paging.PagingStore in project activemq-artemis by apache.
the class PagingManagerImpl method stop.
@Override
public synchronized void stop() throws Exception {
if (!started) {
return;
}
started = false;
if (scheduledComponent != null) {
this.scheduledComponent.stop();
this.scheduledComponent = null;
}
lock();
try {
for (PagingStore store : stores.values()) {
store.stop();
}
pagingStoreFactory.stop();
} finally {
unlock();
}
}
use of org.apache.activemq.artemis.core.paging.PagingStore in project activemq-artemis by apache.
the class AMQSession method send.
public void send(final ProducerInfo producerInfo, final Message messageSend, final boolean sendProducerAck) throws Exception {
messageSend.setBrokerInTime(System.currentTimeMillis());
final ActiveMQDestination destination = messageSend.getDestination();
final ActiveMQDestination[] actualDestinations;
final int actualDestinationsCount;
if (destination.isComposite()) {
actualDestinations = destination.getCompositeDestinations();
messageSend.setOriginalDestination(destination);
actualDestinationsCount = actualDestinations.length;
} else {
actualDestinations = null;
actualDestinationsCount = 1;
}
final org.apache.activemq.artemis.api.core.Message originalCoreMsg = OpenWireMessageConverter.inbound(messageSend, protocolManagerWireFormat, coreMessageObjectPools);
assert clientId.toString().equals(this.connection.getState().getInfo().getClientId()) : "Session cached clientId must be the same of the connection";
originalCoreMsg.putStringProperty(MessageUtil.CONNECTION_ID_PROPERTY_NAME, clientId);
/* ActiveMQ failover transport will attempt to reconnect after connection failure. Any sent messages that did
* not receive acks will be resent. (ActiveMQ broker handles this by returning a last sequence id received to
* the client). To handle this in Artemis we use a duplicate ID cache. To do this we check to see if the
* message comes from failover connection. If so we add a DUPLICATE_ID to handle duplicates after a resend. */
if (connection.getContext().isFaultTolerant() && !messageSend.getProperties().containsKey(org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID.toString())) {
originalCoreMsg.putStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_DUPLICATE_DETECTION_ID, SimpleString.toSimpleString(messageSend.getMessageId().toString()));
}
final boolean shouldBlockProducer = producerInfo.getWindowSize() > 0 || messageSend.isResponseRequired();
final AtomicInteger count = actualDestinations != null ? new AtomicInteger(actualDestinationsCount) : null;
if (shouldBlockProducer) {
connection.getContext().setDontSendReponse(true);
}
for (int i = 0; i < actualDestinationsCount; i++) {
final ActiveMQDestination dest = actualDestinations != null ? actualDestinations[i] : destination;
final String physicalName = dest.getPhysicalName();
final SimpleString address = SimpleString.toSimpleString(physicalName, coreMessageObjectPools.getAddressStringSimpleStringPool());
// the last coreMsg could be directly the original one -> it avoid 1 copy if actualDestinations > 1 and ANY copy if actualDestinations == 1
final org.apache.activemq.artemis.api.core.Message coreMsg = (i == actualDestinationsCount - 1) ? originalCoreMsg : originalCoreMsg.copy();
coreMsg.setAddress(address);
if (dest.isQueue()) {
checkCachedExistingQueues(address, physicalName, dest.isTemporary());
coreMsg.setRoutingType(RoutingType.ANYCAST);
} else {
coreMsg.setRoutingType(RoutingType.MULTICAST);
}
final PagingStore store = server.getPagingManager().getPageStore(address);
this.connection.disableTtl();
if (shouldBlockProducer) {
sendShouldBlockProducer(producerInfo, messageSend, sendProducerAck, store, dest, count, coreMsg, address);
} else {
// non-persistent messages goes here, by default we stop reading from
// transport
connection.getTransportConnection().setAutoRead(false);
if (!store.checkMemory(enableAutoReadAndTtl)) {
enableAutoReadAndTtl();
throw new ResourceAllocationException("Queue is full " + address);
}
getCoreSession().send(coreMsg, false, dest.isTemporary());
if (count == null || count.decrementAndGet() == 0) {
if (sendProducerAck) {
final ProducerAck ack = new ProducerAck(producerInfo.getProducerId(), messageSend.getSize());
connection.dispatchAsync(ack);
}
}
}
}
}
use of org.apache.activemq.artemis.core.paging.PagingStore in project activemq-artemis by apache.
the class XmlDataExporter method printPagedMessagesAsXML.
/**
* Reads from the page files and prints messages as it finds them (making sure to check acks and transactions
* from the journal).
*/
private void printPagedMessagesAsXML() {
try {
pagingmanager.start();
SimpleString[] stores = pagingmanager.getStoreNames();
for (SimpleString store : stores) {
PagingStore pageStore = pagingmanager.getPageStore(store);
if (pageStore != null) {
File folder = pageStore.getFolder();
ActiveMQServerLogger.LOGGER.debug("Reading page store " + store + " folder = " + folder);
int pageId = (int) pageStore.getFirstPage();
for (int i = 0; i < pageStore.getNumberOfPages(); i++) {
ActiveMQServerLogger.LOGGER.debug("Reading page " + pageId);
Page page = pageStore.createPage(pageId);
page.open();
List<PagedMessage> messages = page.read(storageManager);
page.close();
int messageId = 0;
for (PagedMessage message : messages) {
message.initMessage(storageManager);
long[] queueIDs = message.getQueueIDs();
List<String> queueNames = new ArrayList<>();
for (long queueID : queueIDs) {
PagePosition posCheck = new PagePositionImpl(pageId, messageId);
boolean acked = false;
Set<PagePosition> positions = cursorRecords.get(queueID);
if (positions != null) {
acked = positions.contains(posCheck);
}
if (!acked) {
PersistentQueueBindingEncoding queueBinding = queueBindings.get(queueID);
if (queueBinding != null) {
SimpleString queueName = queueBinding.getQueueName();
queueNames.add(queueName.toString());
}
}
}
if (queueNames.size() > 0 && (message.getTransactionID() == -1 || pgTXs.contains(message.getTransactionID()))) {
printSingleMessageAsXML(message.getMessage().toCore(), queueNames);
}
messageId++;
}
pageId++;
}
} else {
ActiveMQServerLogger.LOGGER.debug("Page store was null");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
use of org.apache.activemq.artemis.core.paging.PagingStore in project activemq-artemis by apache.
the class PagingStoreImplTest method testRestartPage.
@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();
}
use of org.apache.activemq.artemis.core.paging.PagingStore in project activemq-artemis by apache.
the class PagingStoreImplTest method testConcurrentPaging.
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());
}
Aggregations