public void route(final ServerMessage message, final RoutingContext context) throws Exception { // We must make a copy of the message, otherwise things like returning credits to the page won't // work // properly on ack, since the original address will be overwritten // TODO we can optimise this so it doesn't copy if it's not routed anywhere else if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace("Diverting message " + message + " into " + this); } long id = storageManager.generateUniqueID(); ServerMessage copy = message.copy(id); copy.finishCopy(); // This will set the original MessageId, and the original address copy.setOriginalHeaders(message, null, false); copy.setAddress(forwardAddress); if (transformer != null) { copy = transformer.transform(copy); } postOffice.route(copy, context.getTransaction(), false); }
public synchronized void xaPrepare(final Xid xid) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot commit, session is currently doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.getTransaction(xid); if (isTrace) { HornetQServerLogger.LOGGER.trace("xaprepare into " + ", xid=" + xid + ", tx= " + tx); } if (theTx == null) { final String msg = "Cannot find xid in resource manager: " + xid; throw new HornetQXAException(XAException.XAER_NOTA, msg); } else { if (theTx.getState() == Transaction.State.SUSPENDED) { throw new HornetQXAException( XAException.XAER_PROTO, "Cannot prepare transaction, it is suspended " + xid); } else if (theTx.getState() == Transaction.State.PREPARED) { HornetQServerLogger.LOGGER.info("ignoring prepare on xid as already called :" + xid); } else { theTx.prepare(); } } } }
/** * Activates several cluster services. Used by backups on failover. * * @throws Exception */ public synchronized void activate() throws Exception { if (state != State.STARTED && state != State.DEPLOYED) return; if (backup) { backup = false; deployConfiguredBridges(); for (BroadcastGroup broadcastGroup : broadcastGroups.values()) { try { broadcastGroup.start(); } catch (Exception e) { HornetQServerLogger.LOGGER.unableToStartBroadcastGroup(e, broadcastGroup.getName()); } } for (ClusterConnection clusterConnection : clusterConnections.values()) { try { clusterConnection.activate(); } catch (Exception e) { HornetQServerLogger.LOGGER.unableToStartClusterConnection(e, clusterConnection.getName()); } } for (Bridge bridge : bridges.values()) { try { bridge.start(); } catch (Exception e) { HornetQServerLogger.LOGGER.unableToStartBridge(e, bridge.getName()); } } } }
public void nodeDown(final long eventUID, final String nodeID) { if (stopping) { return; } if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( this + " receiving nodeDown for nodeID=" + nodeID, new Exception("trace")); } if (nodeID.equals(nodeManager.getNodeId().toString())) { return; } // Remove the flow record for that node MessageFlowRecord record = records.remove(nodeID); if (record != null) { try { if (isTrace) { HornetQServerLogger.LOGGER.trace("Closing clustering record " + record); } record.close(); } catch (Exception e) { HornetQServerLogger.LOGGER.errorClosingFlowRecord(e); } } }
public synchronized void freeze(final CoreRemotingConnection connectionToKeepOpen) { if (!started) return; failureCheckAndFlushThread.close(false); for (Acceptor acceptor : acceptors) { try { acceptor.pause(); } catch (Exception e) { HornetQServerLogger.LOGGER.errorStoppingAcceptor(); } } HashMap<Object, ConnectionEntry> connectionEntries = new HashMap<Object, ConnectionEntry>(connections); // Now we ensure that no connections will process any more packets after this method is // complete then send a disconnect packet for (Entry<Object, ConnectionEntry> entry : connectionEntries.entrySet()) { RemotingConnection conn = entry.getValue().connection; if (conn.equals(connectionToKeepOpen)) continue; if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace("Sending connection.disconnection packet to " + conn); } if (!conn.isClient()) { conn.disconnect(false); connections.remove(entry.getKey()); } } }
public synchronized void xaStart(final Xid xid) throws Exception { if (tx != null) { HornetQServerLogger.LOGGER.xidReplacedOnXStart(tx.getXid().toString(), xid.toString()); try { if (tx.getState() != Transaction.State.PREPARED) { // we don't want to rollback anything prepared here if (tx.getXid() != null) { resourceManager.removeTransaction(tx.getXid()); } tx.rollback(); } } catch (Exception e) { HornetQServerLogger.LOGGER.debug( "An exception happened while we tried to debug the previous tx, we can ignore this exception", e); } } tx = newTransaction(xid); if (isTrace) { HornetQServerLogger.LOGGER.trace("xastart into tx= " + tx); } boolean added = resourceManager.putTransaction(xid, tx); if (!added) { final String msg = "Cannot start, there is already a xid " + tx.getXid(); throw new HornetQXAException(XAException.XAER_DUPID, msg); } }
/** This method is synchronized because we want it to be atomic with the cursors being used */ private long checkMinPage(Collection<PageSubscription> cursorList) { long minPage = Long.MAX_VALUE; for (PageSubscription cursor : cursorList) { long firstPage = cursor.getFirstPage(); if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( this.pagingStore.getAddress() + " has a cursor " + cursor + " with first page=" + firstPage); } // the cursor will return -1 if the cursor is empty if (firstPage >= 0 && firstPage < minPage) { minPage = firstPage; } } if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug(this.pagingStore.getAddress() + " has minPage=" + minPage); } return minPage; }
public synchronized void xaRollback(final Xid xid) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot roll back, session is currently doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.removeTransaction(xid); if (isTrace) { HornetQServerLogger.LOGGER.trace("xarollback into " + theTx); } if (theTx == null) { // checked heuristic committed transactions if (resourceManager.getHeuristicCommittedTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURCOM, "transaction has ben heuristically committed: " + xid); } // checked heuristic rolled back transactions else if (resourceManager.getHeuristicRolledbackTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURRB, "transaction has ben heuristically rolled back: " + xid); } else { if (isTrace) { HornetQServerLogger.LOGGER.trace( "xarollback into " + theTx + ", xid=" + xid + " forcing a rollback regular"); } try { // jbpapp-8845 // This could have happened because the TX timed out, // at this point we would be better on rolling back this session as a way to prevent // consumers from holding their messages this.rollback(false); } catch (Exception e) { HornetQServerLogger.LOGGER.warn(e.getMessage(), e); } throw new HornetQXAException( XAException.XAER_NOTA, "Cannot find xid in resource manager: " + xid); } } else { if (theTx.getState() == Transaction.State.SUSPENDED) { if (isTrace) { HornetQServerLogger.LOGGER.trace( "xarollback into " + theTx + " sending tx back as it was suspended"); } // Put it back resourceManager.putTransaction(xid, tx); throw new HornetQXAException( XAException.XAER_PROTO, "Cannot rollback transaction, it is suspended " + xid); } else { doRollback(false, false, theTx); } } } }
public void markAsRollbackOnly(final HornetQException exception1) { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug("Marking Transaction " + this.id + " as rollback only"); } state = State.ROLLBACK_ONLY; this.exception = exception1; }
public void waitContextCompletion() { try { if (!context.waitCompletion(10000)) { HornetQServerLogger.LOGGER.errorCompletingContext(new Exception("warning")); } } catch (Exception e) { HornetQServerLogger.LOGGER.warn(e.getMessage(), e); } }
/** * Notifies the backup that the live server is stopping. * * <p>This notification allows the backup to skip quorum voting (or any other measure to avoid * 'split-brain') and do a faster fail-over. * * @return */ public OperationContext sendLiveIsStopping(final LiveStopping finalMessage) { HornetQServerLogger.LOGGER.warn( "LIVE IS STOPPING?!? message=" + finalMessage + " enabled=" + enabled); if (enabled) { HornetQServerLogger.LOGGER.warn( "LIVE IS STOPPING?!? message=" + finalMessage + " " + enabled); return sendReplicatePacket(new ReplicationLiveIsStoppingMessage(finalMessage)); } return null; }
private synchronized void doConsumerCreated(final ClientMessage message) throws Exception { if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace( ClusterConnectionImpl.this + " Consumer created " + message); } if (!message.containsProperty(ManagementHelper.HDR_DISTANCE)) { throw new IllegalStateException("distance is null"); } if (!message.containsProperty(ManagementHelper.HDR_CLUSTER_NAME)) { throw new IllegalStateException("clusterName is null"); } Integer distance = message.getIntProperty(ManagementHelper.HDR_DISTANCE); SimpleString clusterName = message.getSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME); message.putIntProperty(ManagementHelper.HDR_DISTANCE, distance + 1); SimpleString filterString = message.getSimpleStringProperty(ManagementHelper.HDR_FILTERSTRING); RemoteQueueBinding binding = bindings.get(clusterName); if (binding == null) { throw new IllegalStateException( "Cannot find binding for " + clusterName + " on " + ClusterConnectionImpl.this); } binding.addConsumer(filterString); // Need to propagate the consumer add TypedProperties props = new TypedProperties(); props.putSimpleStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress()); props.putSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME, clusterName); props.putSimpleStringProperty(ManagementHelper.HDR_ROUTING_NAME, binding.getRoutingName()); props.putIntProperty(ManagementHelper.HDR_DISTANCE, distance + 1); Queue theQueue = (Queue) binding.getBindable(); props.putIntProperty(ManagementHelper.HDR_CONSUMER_COUNT, theQueue.getConsumerCount()); if (filterString != null) { props.putSimpleStringProperty(ManagementHelper.HDR_FILTERSTRING, filterString); } Notification notification = new Notification(null, CONSUMER_CREATED, props); managementService.sendNotification(notification); }
public void connectionFailed(final HornetQException me, boolean failedOver) { try { HornetQServerLogger.LOGGER.clientConnectionFailed(name); close(true); HornetQServerLogger.LOGGER.clientConnectionFailedClearingSession(name); } catch (Throwable t) { HornetQServerLogger.LOGGER.errorClosingConnection(this); } }
public void bufferReceived(final Object connectionID, final HornetQBuffer buffer) { ConnectionEntry conn = connections.get(connectionID); if (conn != null) { conn.connection.bufferReceived(connectionID, buffer); } else { if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace( "ConnectionID = " + connectionID + " was already closed, so ignoring packet"); } } }
public void stop() throws Exception { if (!started) { return; } stopping = true; if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug(this + "::stopping ClusterConnection"); } if (serverLocator != null) { serverLocator.removeClusterTopologyListener(this); } HornetQServerLogger.LOGGER.debug( "Cluster connection being stopped for node" + nodeManager.getNodeId() + ", server = " + this.server + " serverLocator = " + serverLocator); synchronized (this) { for (MessageFlowRecord record : records.values()) { try { record.close(); } catch (Exception ignore) { } } } if (managementService != null) { TypedProperties props = new TypedProperties(); props.putSimpleStringProperty(new SimpleString("name"), name); Notification notification = new Notification( nodeManager.getNodeId().toString(), NotificationType.CLUSTER_CONNECTION_STOPPED, props); managementService.sendNotification(notification); } executor.execute( new Runnable() { public void run() { synchronized (ClusterConnectionImpl.this) { closeLocator(serverLocator); serverLocator = null; } } }); started = false; }
private void doBindingRemoved(final ClientMessage message) throws Exception { if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace( ClusterConnectionImpl.this + " Removing binding " + message); } if (!message.containsProperty(ManagementHelper.HDR_CLUSTER_NAME)) { throw new IllegalStateException("clusterName is null"); } SimpleString clusterName = message.getSimpleStringProperty(ManagementHelper.HDR_CLUSTER_NAME); removeBinding(clusterName); }
public synchronized void run() { // if the reference was busy during the previous iteration, handle it now if (current != null) { try { HandleStatus status = handle(current); if (status == HandleStatus.BUSY) { return; } if (status == HandleStatus.HANDLED) { proceedDeliver(current); } current = null; } catch (Exception e) { HornetQServerLogger.LOGGER.errorBrowserHandlingMessage(e, current); return; } } MessageReference ref = null; HandleStatus status; while (true) { try { ref = null; synchronized (messageQueue) { if (!iterator.hasNext()) { break; } ref = iterator.next(); status = handle(ref); } if (status == HandleStatus.HANDLED) { proceedDeliver(ref); } else if (status == HandleStatus.BUSY) { // keep a reference on the current message reference // to handle it next time the browser deliverer is executed current = ref; break; } } catch (Exception e) { HornetQServerLogger.LOGGER.errorBrowserHandlingMessage(e, ref); break; } } }
public ServerLocatorInternal createServerLocator() { if (tcConfigs != null && tcConfigs.length > 0) { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( ClusterConnectionImpl.this + "Creating a serverLocator for " + Arrays.toString(tcConfigs)); } ServerLocatorImpl locator = new ServerLocatorImpl(topology, true, tcConfigs); locator.setClusterConnection(true); return locator; } return null; }
public void createQueue( final SimpleString address, final SimpleString name, final SimpleString filterString, final boolean temporary, final boolean durable) throws Exception { if (durable) { // make sure the user has privileges to create this queue securityStore.check(address, CheckType.CREATE_DURABLE_QUEUE, this); } else { securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this); } Queue queue = server.createQueue(address, name, filterString, durable, temporary); if (temporary) { // Temporary queue in core simply means the queue will be deleted if // the remoting connection // dies. It does not mean it will get deleted automatically when the // session is closed. // It is up to the user to delete the queue when finished with it TempQueueCleanerUpper cleaner = new TempQueueCleanerUpper(server, name); remotingConnection.addCloseListener(cleaner); remotingConnection.addFailureListener(cleaner); tempQueueCleannerUppers.put(name, cleaner); } if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug( "Queue " + name + " created on address " + name + " with filter=" + filterString + " temporary = " + temporary + " durable=" + durable + " on session user="******", connection=" + this.remotingConnection); } }
private void run() { try { if (HornetQServerLogger.LOGGER.isDebugEnabled()) { HornetQServerLogger.LOGGER.debug("deleting temporary queue " + bindingName); } try { server.destroyQueue(bindingName, null, false); } catch (HornetQException e) { // that's fine.. it can happen due to queue already been deleted HornetQServerLogger.LOGGER.debug(e.getMessage(), e); } } catch (Exception e) { HornetQServerLogger.LOGGER.errorRemovingTempQueue(e, bindingName); } }
@Override public void connectionFailed(final HornetQException me, boolean failedOver) { if (me.getType() == HornetQExceptionType.DISCONNECTED) { // Backup has shut down - no need to log a stack trace HornetQServerLogger.LOGGER.replicationStopOnBackupShutdown(); } else { HornetQServerLogger.LOGGER.replicationStopOnBackupFail(me); } try { stop(); } catch (Exception e) { HornetQServerLogger.LOGGER.errorStoppingReplication(e); } }
public LinkedList<MessageReference> cancelRefs( final boolean failed, final boolean lastConsumedAsDelivered, final Transaction tx) throws Exception { boolean performACK = lastConsumedAsDelivered; try { if (largeMessageDeliverer != null) { largeMessageDeliverer.finish(); } } catch (Throwable e) { HornetQServerLogger.LOGGER.errorResttingLargeMessage(e, largeMessageDeliverer); } finally { largeMessageDeliverer = null; } LinkedList<MessageReference> refs = new LinkedList<MessageReference>(); if (!deliveringRefs.isEmpty()) { for (MessageReference ref : deliveringRefs) { if (isTrace) { HornetQServerLogger.LOGGER.trace( "Cancelling reference for messageID = " + ref.getMessage().getMessageID() + ", ref = " + ref); } if (performACK) { acknowledge(false, tx, ref.getMessage().getMessageID()); performACK = false; } else { if (!failed) { // We don't decrement delivery count if the client failed, since there's a possibility // that refs // were actually delivered but we just didn't get any acks for them // before failure ref.decrementDeliveryCount(); } refs.add(ref); } } deliveringRefs.clear(); } return refs; }
public synchronized void xaFailed(final Xid xid) throws Exception { if (tx != null) { final String msg = "Cannot start, session is already doing work in a transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { tx = newTransaction(xid); tx.markAsRollbackOnly( new HornetQException("Can't commit as a Failover happened during the operation")); if (isTrace) { HornetQServerLogger.LOGGER.trace("xastart into tx= " + tx); } boolean added = resourceManager.putTransaction(xid, tx); if (!added) { final String msg = "Cannot start, there is already a xid " + tx.getXid(); throw new HornetQXAException(XAException.XAER_DUPID, msg); } } }
/** * @param ref * @param message */ private void deliverStandardMessage(final MessageReference ref, final ServerMessage message) { int packetSize = callback.sendMessage(message, id, ref.getDeliveryCount()); if (availableCredits != null) { availableCredits.addAndGet(-packetSize); if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace( this + "::FlowControl::delivery standard taking " + packetSize + " from credits, available now is " + availableCredits); } } }
public void setTransferring(final boolean transferring) { synchronized (lock) { // This is to make sure that the delivery process has finished any pending delivery // otherwise a message may sneak in on the client while we are trying to stop the consumer lockDelivery.writeLock().lock(); try { this.transferring = transferring; } finally { lockDelivery.writeLock().unlock(); } } // Outside the lock if (transferring) { // And we must wait for any force delivery to be executed - this is executed async so we add a // future to the // executor and // wait for it to complete FutureLatch future = new FutureLatch(); messageQueue.getExecutor().execute(future); boolean ok = future.await(10000); if (!ok) { HornetQServerLogger.LOGGER.errorTransferringConsumer(); } } if (!transferring) { promptDelivery(); } }
public void close() throws Exception { if (isTrace) { HornetQServerLogger.LOGGER.trace("Stopping bridge " + bridge); } isClosed = true; clearBindings(); if (disconnected) { bridge.disconnect(); } bridge.stop(); bridge .getExecutor() .execute( new Runnable() { public void run() { try { if (disconnected) { targetLocator.cleanup(); } else { targetLocator.close(); } } catch (Exception ignored) { HornetQServerLogger.LOGGER.debug(ignored.getMessage(), ignored); } } }); }
public void connectionDestroyed(final Object connectionID) { if (isTrace) { HornetQServerLogger.LOGGER.trace( "Connection removed " + connectionID + " from server " + this.server, new Exception("trace")); } ConnectionEntry conn = connections.get(connectionID); if (conn != null) { // Bit of a hack - find a better way to do this List<FailureListener> failureListeners = conn.connection.getFailureListeners(); boolean empty = true; for (FailureListener listener : failureListeners) { if (listener instanceof ServerSessionImpl) { empty = false; break; } } // We only destroy the connection if the connection has no sessions attached to it // Otherwise it means the connection has died without the sessions being closed first // so we need to keep them for ttl, in case re-attachment occurs if (empty) { connections.remove(connectionID); conn.connection.destroy(); } } }
public void sendLarge(final MessageInternal message) throws Exception { // need to create the LargeMessage before continue long id = storageManager.generateUniqueID(); LargeServerMessage largeMsg = storageManager.createLargeMessage(id, message); if (HornetQServerLogger.LOGGER.isTraceEnabled()) { HornetQServerLogger.LOGGER.trace("sendLarge::" + largeMsg); } if (currentLargeMessage != null) { HornetQServerLogger.LOGGER.replacingIncompleteLargeMessage( currentLargeMessage.getMessageID()); } currentLargeMessage = largeMsg; }
public synchronized void xaCommit(final Xid xid, final boolean onePhase) throws Exception { if (tx != null && tx.getXid().equals(xid)) { final String msg = "Cannot commit, session is currently doing work in transaction " + tx.getXid(); throw new HornetQXAException(XAException.XAER_PROTO, msg); } else { Transaction theTx = resourceManager.removeTransaction(xid); if (isTrace) { HornetQServerLogger.LOGGER.trace("XAcommit into " + theTx + ", xid=" + xid); } if (theTx == null) { // checked heuristic committed transactions if (resourceManager.getHeuristicCommittedTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURCOM, "transaction has been heuristically committed: " + xid); } // checked heuristic rolled back transactions else if (resourceManager.getHeuristicRolledbackTransactions().contains(xid)) { throw new HornetQXAException( XAException.XA_HEURRB, "transaction has been heuristically rolled back: " + xid); } else { if (isTrace) { HornetQServerLogger.LOGGER.trace( "XAcommit into " + theTx + ", xid=" + xid + " cannot find it"); } throw new HornetQXAException( XAException.XAER_NOTA, "Cannot find xid in resource manager: " + xid); } } else { if (theTx.getState() == Transaction.State.SUSPENDED) { // Put it back resourceManager.putTransaction(xid, theTx); throw new HornetQXAException( XAException.XAER_PROTO, "Cannot commit transaction, it is suspended " + xid); } else { theTx.commit(onePhase); } } } }
public PageCache getPageCache(final long pageId) { try { boolean needToRead = false; PageCache cache = null; synchronized (softCache) { if (pageId > pagingStore.getCurrentWritingPage()) { return null; } cache = softCache.get(pageId); if (cache == null) { if (!pagingStore.checkPageFileExists((int) pageId)) { return null; } cache = createPageCache(pageId); needToRead = true; // anyone reading from this cache will have to wait reading to finish first // we also want only one thread reading this cache cache.lock(); if (isTrace) { HornetQServerLogger.LOGGER.trace( "adding " + pageId + " into cursor = " + this.pagingStore.getAddress()); } softCache.put(pageId, cache); } } // Reading is done outside of the synchronized block, however // the page stays locked until the entire reading is finished if (needToRead) { Page page = null; try { page = pagingStore.createPage((int) pageId); storageManager.beforePageRead(); page.open(); List<PagedMessage> pgdMessages = page.read(storageManager); cache.setMessages(pgdMessages.toArray(new PagedMessage[pgdMessages.size()])); } finally { try { if (page != null) { page.close(); } } catch (Throwable ignored) { } storageManager.afterPageRead(); cache.unlock(); } } return cache; } catch (Exception e) { throw new RuntimeException( "Couldn't complete paging due to an IO Exception on Paging - " + e.getMessage(), e); } }