@Override public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException { TopicMessageStore rc = (TopicMessageStore) storeCache.get(destination); if (rc == null) { TopicMessageStore store = transactionStore.proxy(new JDBCTopicMessageStore(this, getAdapter(), wireFormat, destination, audit)); rc = (TopicMessageStore) storeCache.putIfAbsent(destination, store); if (rc == null) { rc = store; } } return rc; }
String key = getSubscriptionKey(clientId, subscriptionName); if (!subscriberLastRecoveredMap.containsKey(key)) { subscriberLastRecoveredMap.put(key, new LastRecovered()); LOG.trace(this + ", " + key + " existing last recovered: " + lastRecovered); if (isPrioritizedMessages()) { Iterator<LastRecoveredEntry> it = lastRecovered.iterator(); for ( ; it.hasNext() && !recoveredAwareListener.complete(); ) {
@Override public void deleteSubscription(String clientId, String subscriptionName) throws IOException { TransactionContext c = persistenceAdapter.getTransactionContext(); try { adapter.doDeleteSubscription(c, destination, clientId, subscriptionName); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to remove subscription for: " + clientId + ". Reason: " + e, e); } finally { c.close(); resetBatching(clientId, subscriptionName); } }
@Override public void rollback(ConnectionContext context) throws IOException { ((JDBCPersistenceAdapter)persistenceAdapter).rollbackLastAck(context, priority, jdbcTopicMessageStore.getDestination(), subName, clientId); jdbcTopicMessageStore.complete(clientId, subName); }
public void rollbackLastAck(ConnectionContext context, JDBCTopicMessageStore store, MessageAck ack, String subName, String clientId) throws IOException { TransactionContext c = getTransactionContext(context); try { byte priority = (byte) store.getCachedStoreSequenceId(c, store.getDestination(), ack.getLastMessageId())[1]; getAdapter().doClearLastAck(c, store.getDestination(), priority, clientId, subName); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to rollback last ack: " + ack + " on " + store.getDestination() + " for " + subName + ":" + clientId + ". Reason: " + e,e); } finally { c.close(); } }
@Override public void acknowledge(ConnectionContext context, String clientId, String subscriptionName, MessageId messageId, MessageAck ack) throws IOException { if (ack != null && ack.isUnmatchedAck()) { if (LOG.isTraceEnabled()) { LOG.trace("ignoring unmatched selector ack for: " + messageId + ", cleanup will get to this message after subsequent acks."); } return; } TransactionContext c = persistenceAdapter.getTransactionContext(context); try { long[] res = getCachedStoreSequenceId(c, destination, messageId); if (this.isPrioritizedMessages()) { adapter.doSetLastAckWithPriority(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } else { adapter.doSetLastAck(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } if (LOG.isTraceEnabled()) { LOG.trace(clientId + ":" + subscriptionName + " ack, seq: " + res[0] + ", priority: " + res[1] + " mid:" + messageId); } } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to store acknowledgment for: " + clientId + " on message " + messageId + " in container: " + e, e); } finally { c.close(); } }
@Override public int getMessageCount(String clientId, String subscriberName) throws IOException { //Duration duration = new Duration("getMessageCount"); int result = 0; TransactionContext c = persistenceAdapter.getTransactionContext(); try { result = adapter.doGetDurableSubscriberMessageCount(c, destination, clientId, subscriberName, isPrioritizedMessages()); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to get Message Count: " + clientId + ". Reason: " + e, e); } finally { c.close(); } if (LOG.isTraceEnabled()) { LOG.trace(clientId + ":" + subscriberName + ", messageCount: " + result); } //duration.end(); return result; }
public void complete(String clientId, String subscriptionName) { pendingCompletion.remove(getSubscriptionKey(clientId, subscriptionName)); LOG.trace(this + ", completion for: " + getSubscriptionKey(clientId, subscriptionName)); }
@Override public void run(ConnectionContext context) throws IOException { ((JDBCPersistenceAdapter)persistenceAdapter).commitLastAck(context, lastAck, priority, destination, subName, clientId); jdbcTopicMessageStore.complete(clientId, subName); }
@Override protected void onRecovered(Tx tx) { for (RemoveMessageCommand removeMessageCommand: tx.acks) { if (removeMessageCommand instanceof LastAckCommand) { LastAckCommand lastAckCommand = (LastAckCommand) removeMessageCommand; JDBCTopicMessageStore jdbcTopicMessageStore = (JDBCTopicMessageStore) findMessageStore(lastAckCommand.getMessageAck().getDestination()); jdbcTopicMessageStore.pendingCompletion(lastAckCommand.getClientId(), lastAckCommand.getSubName(), lastAckCommand.getSequence(), lastAckCommand.getPriority()); lastAckCommand.setMessageStore(jdbcTopicMessageStore); } else { ((RecoveredRemoveMessageCommand)removeMessageCommand).setMessageStore(findMessageStore(removeMessageCommand.getMessageAck().getDestination())); } } for (AddMessageCommand addMessageCommand : tx.messages) { addMessageCommand.setMessageStore(findMessageStore(addMessageCommand.getMessage().getDestination())); } }
@Override public void acknowledge(ConnectionContext context, String clientId, String subscriptionName, MessageId messageId, MessageAck ack) throws IOException { if (ack != null && ack.isUnmatchedAck()) { if (LOG.isTraceEnabled()) { LOG.trace("ignoring unmatched selector ack for: " + messageId + ", cleanup will get to this message after subsequent acks."); } return; } TransactionContext c = persistenceAdapter.getTransactionContext(context); try { long[] res = getCachedStoreSequenceId(c, destination, messageId); if (this.isPrioritizedMessages()) { adapter.doSetLastAckWithPriority(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } else { adapter.doSetLastAck(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } if (LOG.isTraceEnabled()) { LOG.trace(clientId + ":" + subscriptionName + " ack, seq: " + res[0] + ", priority: " + res[1] + " mid:" + messageId); } } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to store acknowledgment for: " + clientId + " on message " + messageId + " in container: " + e, e); } finally { c.close(); } }
@Override public void addSubscription(SubscriptionInfo subscriptionInfo, boolean retroactive) throws IOException { TransactionContext c = persistenceAdapter.getTransactionContext(); try { c = persistenceAdapter.getTransactionContext(); adapter.doSetSubscriberEntry(c, subscriptionInfo, retroactive, isPrioritizedMessages()); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to lookup subscription for info: " + subscriptionInfo.getClientId() + ". Reason: " + e, e); } finally { c.close(); } }
@Override public void resetBatching(String clientId, String subscriptionName) { String key = getSubscriptionKey(clientId, subscriptionName); if (!pendingCompletion.contains(key)) { subscriberLastRecoveredMap.remove(key); } else { LOG.trace(this + ", skip resetBatch during pending completion for: " + key); } }
@Override public void rollback(ConnectionContext context) throws IOException { ((JDBCPersistenceAdapter)persistenceAdapter).rollbackLastAck(context, priority, jdbcTopicMessageStore.getDestination(), subName, clientId); jdbcTopicMessageStore.complete(clientId, subName); }
public void rollbackLastAck(ConnectionContext context, JDBCTopicMessageStore store, MessageAck ack, String subName, String clientId) throws IOException { TransactionContext c = getTransactionContext(context); try { byte priority = (byte) store.getCachedStoreSequenceId(c, store.getDestination(), ack.getLastMessageId())[1]; getAdapter().doClearLastAck(c, store.getDestination(), priority, clientId, subName); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to rollback last ack: " + ack + " on " + store.getDestination() + " for " + subName + ":" + clientId + ". Reason: " + e,e); } finally { c.close(); } }
@Override public void rollback(ConnectionContext context) throws IOException { JDBCTopicMessageStore jdbcTopicMessageStore = (JDBCTopicMessageStore)topicMessageStore; ((JDBCPersistenceAdapter)persistenceAdapter).rollbackLastAck(context, jdbcTopicMessageStore, ack, subscriptionName, clientId); jdbcTopicMessageStore.complete(clientId, subscriptionName); }
@Override protected void onRecovered(Tx tx) { for (RemoveMessageCommand removeMessageCommand: tx.acks) { if (removeMessageCommand instanceof LastAckCommand) { LastAckCommand lastAckCommand = (LastAckCommand) removeMessageCommand; JDBCTopicMessageStore jdbcTopicMessageStore = (JDBCTopicMessageStore) topicStores.get(lastAckCommand.getMessageAck().getDestination()); jdbcTopicMessageStore.pendingCompletion(lastAckCommand.getClientId(), lastAckCommand.getSubName(), lastAckCommand.getSequence(), lastAckCommand.getPriority()); lastAckCommand.setMessageStore(jdbcTopicMessageStore); } else { // when reading the store we ignore messages with non null XIDs but should include those with XIDS starting in - (pending acks in an xa transaction), // but the sql is non portable to match BLOB with LIKE etc // so we make up for it when we recover the ack ((JDBCPersistenceAdapter)persistenceAdapter).getBrokerService().getRegionBroker().getDestinationMap().get(removeMessageCommand.getMessageAck().getDestination()).getDestinationStatistics().getMessages().increment(); } } for (AddMessageCommand addMessageCommand : tx.messages) { ActiveMQDestination destination = addMessageCommand.getMessage().getDestination(); addMessageCommand.setMessageStore(destination.isQueue() ? queueStores.get(destination) : topicStores.get(destination)); } }
public void pendingCompletion(String clientId, String subscriptionName, long sequenceId, byte priority) { final String key = getSubscriptionKey(clientId, subscriptionName); LastRecovered recovered = new LastRecovered(); recovered.perPriority[isPrioritizedMessages() ? priority : javax.jms.Message.DEFAULT_PRIORITY].recovered = sequenceId; subscriberLastRecoveredMap.put(key, recovered); pendingCompletion.add(key); LOG.trace(this + ", pending completion: " + key + ", last: " + recovered); }
@Override public void acknowledge(ConnectionContext context, String clientId, String subscriptionName, MessageId messageId, MessageAck ack) throws IOException { if (ack != null && ack.isUnmatchedAck()) { if (LOG.isTraceEnabled()) { LOG.trace("ignoring unmatched selector ack for: " + messageId + ", cleanup will get to this message after subsequent acks."); } return; } TransactionContext c = persistenceAdapter.getTransactionContext(context); try { long[] res = getCachedStoreSequenceId(c, destination, messageId); if (this.isPrioritizedMessages()) { adapter.doSetLastAckWithPriority(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } else { adapter.doSetLastAck(c, destination, context != null ? context.getXid() : null, clientId, subscriptionName, res[0], res[1]); } if (LOG.isTraceEnabled()) { LOG.trace(clientId + ":" + subscriptionName + " ack, seq: " + res[0] + ", priority: " + res[1] + " mid:" + messageId); } } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to store acknowledgment for: " + clientId + " on message " + messageId + " in container: " + e, e); } finally { c.close(); } }
@Override public int getMessageCount(String clientId, String subscriberName) throws IOException { //Duration duration = new Duration("getMessageCount"); int result = 0; TransactionContext c = persistenceAdapter.getTransactionContext(); try { result = adapter.doGetDurableSubscriberMessageCount(c, destination, clientId, subscriberName, isPrioritizedMessages()); } catch (SQLException e) { JDBCPersistenceAdapter.log("JDBC Failure: ", e); throw IOExceptionSupport.create("Failed to get Message Count: " + clientId + ". Reason: " + e, e); } finally { c.close(); } if (LOG.isTraceEnabled()) { LOG.trace(clientId + ":" + subscriberName + ", messageCount: " + result); } //duration.end(); return result; }