use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.
the class ProtonServerReceiverContext method onMessage.
/*
* called when Proton receives a message to be delivered via a Delivery.
*
* This may be called more than once per deliver so we have to cache the buffer until we have received it all.
*
* */
@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
Receiver receiver;
try {
if (!delivery.isReadable()) {
return;
}
if (delivery.isPartial()) {
return;
}
receiver = ((Receiver) delivery.getLink());
Transaction tx = null;
byte[] data;
data = new byte[delivery.available()];
receiver.recv(data, 0, data.length);
receiver.advance();
if (delivery.getRemoteState() instanceof TransactionalState) {
TransactionalState txState = (TransactionalState) delivery.getRemoteState();
tx = this.sessionSPI.getTransaction(txState.getTxnId(), false);
}
sessionSPI.serverSend(this, tx, receiver, delivery, address, delivery.getMessageFormat(), data);
flow(amqpCredits, minCreditRefresh);
} catch (Exception e) {
log.warn(e.getMessage(), e);
Rejected rejected = new Rejected();
ErrorCondition condition = new ErrorCondition();
if (e instanceof ActiveMQSecurityException) {
condition.setCondition(AmqpError.UNAUTHORIZED_ACCESS);
} else {
condition.setCondition(Symbol.valueOf("failed"));
}
condition.setDescription(e.getMessage());
rejected.setError(condition);
connection.lock();
try {
delivery.disposition(rejected);
delivery.settle();
} finally {
connection.unlock();
}
}
}
use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.
the class ServerConsumerImpl method close.
@Override
public void close(final boolean failed) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("ServerConsumerImpl::" + this + " being closed with failed=" + failed, new Exception("trace"));
}
if (server.hasBrokerPlugins()) {
server.callBrokerPlugins(plugin -> plugin.beforeCloseConsumer(this, failed));
}
setStarted(false);
LargeMessageDeliverer del = largeMessageDeliverer;
if (del != null) {
del.finish();
}
removeItself();
LinkedList<MessageReference> refs = cancelRefs(failed, false, null);
Iterator<MessageReference> iter = refs.iterator();
Transaction tx = new TransactionImpl(storageManager);
while (iter.hasNext()) {
MessageReference ref = iter.next();
if (logger.isTraceEnabled()) {
logger.trace("ServerConsumerImpl::" + this + " cancelling reference " + ref);
}
ref.getQueue().cancel(tx, ref, true);
}
tx.rollback();
messageQueue.recheckRefCount(session.getSessionContext());
if (!browseOnly) {
TypedProperties props = new TypedProperties();
props.putSimpleStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress());
props.putSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME, binding.getClusterName());
props.putSimpleStringProperty(ManagementHelper.HDR_ROUTING_NAME, binding.getRoutingName());
props.putSimpleStringProperty(ManagementHelper.HDR_FILTERSTRING, filter == null ? null : filter.getFilterString());
props.putIntProperty(ManagementHelper.HDR_DISTANCE, binding.getDistance());
props.putIntProperty(ManagementHelper.HDR_CONSUMER_COUNT, messageQueue.getConsumerCount());
// HORNETQ-946
props.putSimpleStringProperty(ManagementHelper.HDR_USER, SimpleString.toSimpleString(session.getUsername()));
props.putSimpleStringProperty(ManagementHelper.HDR_REMOTE_ADDRESS, SimpleString.toSimpleString(((ServerSessionImpl) session).getRemotingConnection().getRemoteAddress()));
props.putSimpleStringProperty(ManagementHelper.HDR_SESSION_NAME, SimpleString.toSimpleString(session.getName()));
Notification notification = new Notification(null, CoreNotificationType.CONSUMER_CLOSED, props);
managementService.sendNotification(notification);
}
if (server.hasBrokerPlugins()) {
server.callBrokerPlugins(plugin -> plugin.afterCloseConsumer(this, failed));
}
}
use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.
the class PageCursorStressTest method testLazyCommit.
@Test
public void testLazyCommit() throws Exception {
PagingStoreImpl pageStore = lookupPageStore(ADDRESS);
pageStore.startPaging();
final int NUM_MESSAGES = 100;
final int messageSize = 100 * 1024;
PageCursorProvider cursorProvider = this.server.getPagingManager().getPageStore(ADDRESS).getCursorProvider();
System.out.println("cursorProvider = " + cursorProvider);
PageSubscription cursor = this.server.getPagingManager().getPageStore(ADDRESS).getCursorProvider().getSubscription(queue.getID());
LinkedListIterator<PagedReference> iterator = cursor.iterator();
System.out.println("Cursor: " + cursor);
StorageManager storage = this.server.getStorageManager();
long pgtxLazy = storage.generateID();
Transaction txLazy = pgMessages(storage, pageStore, pgtxLazy, 0, NUM_MESSAGES, messageSize);
addMessages(100, NUM_MESSAGES, messageSize);
System.out.println("Number of pages - " + pageStore.getNumberOfPages());
// First consume what's already there without any tx as nothing was committed
for (int i = 100; i < 200; i++) {
PagedReference pos = iterator.next();
assertNotNull("Null at position " + i, pos);
assertEquals(i, pos.getMessage().getIntProperty("key").intValue());
cursor.ack(pos);
}
assertNull(iterator.next());
txLazy.commit();
storage.waitOnOperations();
for (int i = 0; i < 100; i++) {
PagedReference pos = iterator.next();
assertNotNull("Null at position " + i, pos);
assertEquals(i, pos.getMessage().getIntProperty("key").intValue());
cursor.ack(pos);
}
assertNull(iterator.next());
waitCleanup();
server.stop();
createServer();
waitCleanup();
assertEquals(1, lookupPageStore(ADDRESS).getNumberOfPages());
}
use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.
the class PostOfficeJournalLoader method recoverPendingPageCounters.
/**
* This method will recover the counters after failures making sure the page counter doesn't get out of sync
*
* @param pendingNonTXPageCounter
* @throws Exception
*/
@Override
public void recoverPendingPageCounters(List<PageCountPending> pendingNonTXPageCounter) throws Exception {
// We need a structure of the following
// Address -> PageID -> QueueID -> List<PageCountPending>
// The following loop will sort the records according to the hierarchy we need
Transaction txRecoverCounter = new TransactionImpl(storageManager);
Map<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> perAddressMap = generateMapsOnPendingCount(queues, pendingNonTXPageCounter, txRecoverCounter);
for (Map.Entry<SimpleString, Map<Long, Map<Long, List<PageCountPending>>>> addressPageMapEntry : perAddressMap.entrySet()) {
PagingStore store = pagingManager.getPageStore(addressPageMapEntry.getKey());
Map<Long, Map<Long, List<PageCountPending>>> perPageMap = addressPageMapEntry.getValue();
// We have already generated this before, so it can't be null
assert (perPageMap != null);
for (Long pageId : perPageMap.keySet()) {
Map<Long, List<PageCountPending>> perQueue = perPageMap.get(pageId);
// This can't be true!
assert (perQueue != null);
if (store.checkPageFileExists(pageId.intValue())) {
// on this case we need to recalculate the records
Page pg = store.createPage(pageId.intValue());
pg.open();
List<PagedMessage> pgMessages = pg.read(storageManager);
Map<Long, AtomicInteger> countsPerQueueOnPage = new HashMap<>();
Map<Long, AtomicLong> sizePerQueueOnPage = new HashMap<>();
for (PagedMessage pgd : pgMessages) {
if (pgd.getTransactionID() <= 0) {
for (long q : pgd.getQueueIDs()) {
AtomicInteger countQ = countsPerQueueOnPage.get(q);
AtomicLong sizeQ = sizePerQueueOnPage.get(q);
if (countQ == null) {
countQ = new AtomicInteger(0);
countsPerQueueOnPage.put(q, countQ);
}
if (sizeQ == null) {
sizeQ = new AtomicLong(0);
sizePerQueueOnPage.put(q, sizeQ);
}
countQ.incrementAndGet();
if (pgd.getPersistentSize() > 0) {
sizeQ.addAndGet(pgd.getPersistentSize());
}
}
}
}
for (Map.Entry<Long, List<PageCountPending>> entry : perQueue.entrySet()) {
for (PageCountPending record : entry.getValue()) {
logger.debug("Deleting pg tempCount " + record.getID());
storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID());
}
PageSubscriptionCounter counter = store.getCursorProvider().getSubscription(entry.getKey()).getCounter();
AtomicInteger value = countsPerQueueOnPage.get(entry.getKey());
AtomicLong sizeValue = sizePerQueueOnPage.get(entry.getKey());
if (value == null) {
logger.debug("Page " + entry.getKey() + " wasn't open, so we will just ignore");
} else {
logger.debug("Replacing counter " + value.get());
counter.increment(txRecoverCounter, value.get(), sizeValue.get());
}
}
} else {
// on this case the page file didn't exist, we just remove all the records since the page is already gone
logger.debug("Page " + pageId + " didn't exist on address " + addressPageMapEntry.getKey() + ", so we are just removing records");
for (List<PageCountPending> records : perQueue.values()) {
for (PageCountPending record : records) {
logger.debug("Removing pending page counter " + record.getID());
storageManager.deletePendingPageCounter(txRecoverCounter.getID(), record.getID());
txRecoverCounter.setContainsPersistent();
}
}
}
}
}
txRecoverCounter.commit();
}
use of org.apache.activemq.artemis.core.transaction.Transaction in project activemq-artemis by apache.
the class QueueImpl method purgeAfterRollback.
private void purgeAfterRollback(LinkedList<MessageReference> refs) {
try {
Transaction transaction = new TransactionImpl(storageManager);
for (MessageReference reference : refs) {
// post ack will decrement this, so need to inc
incDelivering(reference);
acknowledge(transaction, reference, AckReason.KILLED);
}
transaction.commit();
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
Aggregations