use of org.apache.activemq.artemis.core.server.MessageReference in project activemq-artemis by apache.
the class AbstractJournalStorageManager method loadPreparedTransactions.
private void loadPreparedTransactions(final PostOffice postOffice, final PagingManager pagingManager, final ResourceManager resourceManager, final Map<Long, QueueBindingInfo> queueInfos, final List<PreparedTransactionInfo> preparedTransactions, final Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap, final Map<Long, PageSubscription> pageSubscriptions, final Set<Pair<Long, Long>> pendingLargeMessages, JournalLoader journalLoader) throws Exception {
// recover prepared transactions
for (PreparedTransactionInfo preparedTransaction : preparedTransactions) {
XidEncoding encodingXid = new XidEncoding(preparedTransaction.getExtraData());
Xid xid = encodingXid.xid;
Transaction tx = new TransactionImpl(preparedTransaction.getId(), xid, this);
List<MessageReference> referencesToAck = new ArrayList<>();
Map<Long, Message> messages = new HashMap<>();
// first get any sent messages for this tx and recreate
for (RecordInfo record : preparedTransaction.getRecords()) {
byte[] data = record.data;
ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(data);
byte recordType = record.getUserRecordType();
switch(recordType) {
case JournalRecordIds.ADD_LARGE_MESSAGE:
{
messages.put(record.id, parseLargeMessage(messages, buff));
break;
}
case JournalRecordIds.ADD_MESSAGE:
{
break;
}
case JournalRecordIds.ADD_MESSAGE_PROTOCOL:
{
Message message = MessagePersister.getInstance().decode(buff, null);
messages.put(record.id, message);
break;
}
case JournalRecordIds.ADD_REF:
{
long messageID = record.id;
RefEncoding encoding = new RefEncoding();
encoding.decode(buff);
Message message = messages.get(messageID);
if (message == null) {
throw new IllegalStateException("Cannot find message with id " + messageID);
}
journalLoader.handlePreparedSendMessage(message, tx, encoding.queueID);
break;
}
case JournalRecordIds.ACKNOWLEDGE_REF:
{
long messageID = record.id;
RefEncoding encoding = new RefEncoding();
encoding.decode(buff);
journalLoader.handlePreparedAcknowledge(messageID, referencesToAck, encoding.queueID);
break;
}
case JournalRecordIds.PAGE_TRANSACTION:
{
PageTransactionInfo pageTransactionInfo = new PageTransactionInfoImpl();
pageTransactionInfo.decode(buff);
if (record.isUpdate) {
PageTransactionInfo pgTX = pagingManager.getTransaction(pageTransactionInfo.getTransactionID());
pgTX.reloadUpdate(this, pagingManager, tx, pageTransactionInfo.getNumberOfMessages());
} else {
pageTransactionInfo.setCommitted(false);
tx.putProperty(TransactionPropertyIndexes.PAGE_TRANSACTION, pageTransactionInfo);
pagingManager.addTransaction(pageTransactionInfo);
tx.addOperation(new FinishPageMessageOperation());
}
break;
}
case SET_SCHEDULED_DELIVERY_TIME:
{
break;
}
case DUPLICATE_ID:
{
// We need load the duplicate ids at prepare time too
DuplicateIDEncoding encoding = new DuplicateIDEncoding();
encoding.decode(buff);
DuplicateIDCache cache = postOffice.getDuplicateIDCache(encoding.address);
cache.load(tx, encoding.duplID);
break;
}
case ACKNOWLEDGE_CURSOR:
{
CursorAckRecordEncoding encoding = new CursorAckRecordEncoding();
encoding.decode(buff);
encoding.position.setRecordID(record.id);
PageSubscription sub = locateSubscription(encoding.queueID, pageSubscriptions, queueInfos, pagingManager);
if (sub != null) {
sub.reloadPreparedACK(tx, encoding.position);
referencesToAck.add(new PagedReferenceImpl(encoding.position, null, sub));
} else {
ActiveMQServerLogger.LOGGER.journalCannotFindQueueReloadingACK(encoding.queueID);
}
break;
}
case PAGE_CURSOR_COUNTER_VALUE:
{
ActiveMQServerLogger.LOGGER.journalPAGEOnPrepared();
break;
}
case PAGE_CURSOR_COUNTER_INC:
{
PageCountRecordInc encoding = new PageCountRecordInc();
encoding.decode(buff);
PageSubscription sub = locateSubscription(encoding.getQueueID(), pageSubscriptions, queueInfos, pagingManager);
if (sub != null) {
sub.getCounter().applyIncrementOnTX(tx, record.id, encoding.getValue(), encoding.getPersistentSize());
sub.notEmpty();
} else {
ActiveMQServerLogger.LOGGER.journalCannotFindQueueReloadingACK(encoding.getQueueID());
}
break;
}
default:
{
ActiveMQServerLogger.LOGGER.journalInvalidRecordType(recordType);
}
}
}
for (RecordInfo recordDeleted : preparedTransaction.getRecordsToDelete()) {
byte[] data = recordDeleted.data;
if (data.length > 0) {
ActiveMQBuffer buff = ActiveMQBuffers.wrappedBuffer(data);
byte b = buff.readByte();
switch(b) {
case ADD_LARGE_MESSAGE_PENDING:
{
long messageID = buff.readLong();
if (!pendingLargeMessages.remove(new Pair<>(recordDeleted.id, messageID))) {
ActiveMQServerLogger.LOGGER.largeMessageNotFound(recordDeleted.id);
}
installLargeMessageConfirmationOnTX(tx, recordDeleted.id);
break;
}
default:
ActiveMQServerLogger.LOGGER.journalInvalidRecordTypeOnPreparedTX(b);
}
}
}
journalLoader.handlePreparedTransaction(tx, referencesToAck, xid, resourceManager);
}
}
use of org.apache.activemq.artemis.core.server.MessageReference in project activemq-artemis by apache.
the class QueueControlImpl method browse.
@Override
public CompositeData[] browse(String filter) throws Exception {
checkStarted();
clearIO();
try {
int pageSize = addressSettingsRepository.getMatch(queue.getName().toString()).getManagementBrowsePageSize();
int currentPageSize = 0;
ArrayList<CompositeData> c = new ArrayList<>();
Filter thefilter = FilterImpl.createFilter(filter);
queue.flushExecutor();
try (LinkedListIterator<MessageReference> iterator = queue.browserIterator()) {
try {
while (iterator.hasNext() && currentPageSize++ < pageSize) {
MessageReference ref = iterator.next();
if (thefilter == null || thefilter.match(ref.getMessage())) {
c.add(OpenTypeSupport.convert(ref));
}
}
} catch (NoSuchElementException ignored) {
// this could happen through paging browsing
}
CompositeData[] rc = new CompositeData[c.size()];
c.toArray(rc);
return rc;
}
} catch (ActiveMQException e) {
throw new IllegalStateException(e.getMessage());
} finally {
blockOnIO();
}
}
use of org.apache.activemq.artemis.core.server.MessageReference in project activemq-artemis by apache.
the class BridgeImpl method sendAcknowledged.
// Consumer implementation ---------------------------------------
@Override
public void sendAcknowledged(final Message message) {
if (logger.isTraceEnabled()) {
logger.trace("BridgeImpl::sendAcknowledged received confirmation for message " + message);
}
if (active) {
try {
final MessageReference ref;
synchronized (refs) {
ref = refs.remove(message.getMessageID());
}
if (ref != null) {
if (logger.isTraceEnabled()) {
logger.trace("BridgeImpl::sendAcknowledged bridge " + this + " Acking " + ref + " on queue " + ref.getQueue());
}
ref.getQueue().acknowledge(ref);
pendingAcks.countDown();
} else {
if (logger.isTraceEnabled()) {
logger.trace("BridgeImpl::sendAcknowledged bridge " + this + " could not find reference for message " + message);
}
}
} catch (Exception e) {
ActiveMQServerLogger.LOGGER.bridgeFailedToAck(e);
}
}
}
use of org.apache.activemq.artemis.core.server.MessageReference in project activemq-artemis by apache.
the class MQTTRetainMessageManager method addRetainedMessagesToQueue.
// SEND to Queue.
void addRetainedMessagesToQueue(Queue queue, String address) throws Exception {
// The address filter that matches all retained message queues.
String retainAddress = MQTTUtil.convertMQTTAddressFilterToCoreRetain(address, session.getWildcardConfiguration());
BindingQueryResult bindingQueryResult = session.getServerSession().executeBindingQuery(new SimpleString(retainAddress));
// Iterate over all matching retain queues and add the queue
Transaction tx = session.getServerSession().newTransaction();
try {
synchronized (queue) {
for (SimpleString retainedQueueName : bindingQueryResult.getQueueNames()) {
Queue retainedQueue = session.getServer().locateQueue(retainedQueueName);
try (LinkedListIterator<MessageReference> i = retainedQueue.iterator()) {
if (i.hasNext()) {
Message message = i.next().getMessage().copy(session.getServer().getStorageManager().generateID());
sendToQueue(message, queue, tx);
}
}
}
}
} catch (Throwable t) {
tx.rollback();
throw t;
}
tx.commit();
}
use of org.apache.activemq.artemis.core.server.MessageReference in project activemq-artemis by apache.
the class InterruptedLargeMessageTest method testRestartBeforeDelete.
@Test
public void testRestartBeforeDelete() throws Exception {
class NoPostACKQueue extends QueueImpl {
NoPostACKQueue(long id, SimpleString address, SimpleString name, Filter filter, SimpleString user, PageSubscription pageSubscription, boolean durable, boolean temporary, boolean autoCreated, ScheduledExecutorService scheduledExecutor, PostOffice postOffice, StorageManager storageManager, HierarchicalRepository<AddressSettings> addressSettingsRepository, ArtemisExecutor executor) {
super(id, address, name, filter, pageSubscription, user, durable, temporary, autoCreated, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, executor, null, null);
}
@Override
public void postAcknowledge(final MessageReference ref) {
System.out.println("Ignoring postACK on message " + ref);
}
@Override
public void deliverScheduledMessages() {
}
}
final class NoPostACKQueueFactory implements QueueFactory {
final StorageManager storageManager;
final PostOffice postOffice;
final ScheduledExecutorService scheduledExecutor;
final HierarchicalRepository<AddressSettings> addressSettingsRepository;
final ExecutorFactory execFactory;
NoPostACKQueueFactory(StorageManager storageManager, PostOffice postOffice, ScheduledExecutorService scheduledExecutor, HierarchicalRepository<AddressSettings> addressSettingsRepository, final ExecutorFactory execFactory) {
this.storageManager = storageManager;
this.postOffice = postOffice;
this.scheduledExecutor = scheduledExecutor;
this.addressSettingsRepository = addressSettingsRepository;
this.execFactory = execFactory;
}
@Override
public Queue createQueueWith(final QueueConfig config) {
return new NoPostACKQueue(config.id(), config.address(), config.name(), config.filter(), config.user(), config.pageSubscription(), config.isDurable(), config.isTemporary(), config.isAutoCreated(), scheduledExecutor, postOffice, storageManager, addressSettingsRepository, execFactory.getExecutor());
}
@Deprecated
@Override
public Queue createQueue(long persistenceID, SimpleString address, SimpleString name, Filter filter, PageSubscription pageSubscription, SimpleString user, boolean durable, boolean temporary, boolean autoCreated) {
return new NoPostACKQueue(persistenceID, address, name, filter, user, pageSubscription, durable, temporary, autoCreated, scheduledExecutor, postOffice, storageManager, addressSettingsRepository, execFactory.getExecutor());
}
/* (non-Javadoc)
* @see org.apache.activemq.artemis.core.server.QueueFactory#setPostOffice(org.apache.activemq.artemis.core.postoffice.PostOffice)
*/
@Override
public void setPostOffice(PostOffice postOffice) {
}
}
ClientSession session = null;
LargeMessageTestInterceptorIgnoreLastPacket.disableInterrupt();
ActiveMQServer server = createServer(true, isNetty());
server.start();
QueueFactory original = server.getQueueFactory();
((ActiveMQServerImpl) server).replaceQueueFactory(new NoPostACKQueueFactory(server.getStorageManager(), server.getPostOffice(), server.getScheduledPool(), server.getAddressSettingsRepository(), server.getExecutorFactory()));
locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true);
ClientSessionFactory sf = createSessionFactory(locator);
session = sf.createSession(false, true, true);
session.createQueue(ADDRESS, ADDRESS, true);
ClientProducer producer = session.createProducer(ADDRESS);
for (int i = 0; i < 10; i++) {
Message clientFile = createLargeClientMessageStreaming(session, LARGE_MESSAGE_SIZE, true);
producer.send(clientFile);
}
session.commit();
session.close();
session = sf.createSession(false, false);
ClientConsumer cons = session.createConsumer(ADDRESS);
session.start();
for (int i = 0; i < 10; i++) {
ClientMessage msg = cons.receive(5000);
Assert.assertNotNull(msg);
msg.saveToOutputStream(new java.io.OutputStream() {
@Override
public void write(int b) throws IOException {
}
});
msg.acknowledge();
session.commit();
}
((ActiveMQServerImpl) server).replaceQueueFactory(original);
server.fail(false);
server.start();
server.stop();
validateNoFilesOnLargeDir();
}
Aggregations