/** * Reserves files (with the given fileID) in the specified journal, and places a {@link * FileWrapperJournal} in place to store messages while synchronization is going on. * * @param packet * @throws Exception * @return if the incoming packet indicates the synchronization is finished then return an * acknowledgement otherwise return an empty response */ private ReplicationResponseMessageV2 handleStartReplicationSynchronization( final ReplicationStartSyncMessage packet) throws Exception { ReplicationResponseMessageV2 replicationResponseMessage = new ReplicationResponseMessageV2(); if (activation.isRemoteBackupUpToDate()) { throw ActiveMQMessageBundle.BUNDLE.replicationBackupUpToDate(); } synchronized (this) { if (!started) return replicationResponseMessage; if (packet.isSynchronizationFinished()) { finishSynchronization(packet.getNodeID()); replicationResponseMessage.setSynchronizationIsFinishedAcknowledgement(true); return replicationResponseMessage; } switch (packet.getDataType()) { case LargeMessages: for (long msgID : packet.getFileIds()) { createLargeMessage(msgID, true); } break; case JournalBindings: case JournalMessages: if (wantedFailBack && !packet.isServerToFailBack()) { ActiveMQServerLogger.LOGGER.autoFailBackDenied(); } final JournalContent journalContent = SyncDataType.getJournalContentType(packet.getDataType()); final Journal journal = journalsHolder.get(journalContent); if (packet.getNodeID() != null) { // At the start of replication, we still do not know which is the nodeID that the live // uses. // This is the point where the backup gets this information. backupQuorum.liveIDSet(packet.getNodeID()); } Map<Long, JournalSyncFile> mapToFill = filesReservedForSync.get(journalContent); for (Entry<Long, JournalFile> entry : journal.createFilesForBackupSync(packet.getFileIds()).entrySet()) { mapToFill.put(entry.getKey(), new JournalSyncFile(entry.getValue())); } FileWrapperJournal syncJournal = new FileWrapperJournal(journal); registerJournal(journalContent.typeByte, syncJournal); break; default: throw ActiveMQMessageBundle.BUNDLE.replicationUnhandledDataType(); } } return replicationResponseMessage; }
@Override public int moveMessages( final int flushLimit, final String filterStr, final String otherQueueName, final boolean rejectDuplicates) throws Exception { checkStarted(); clearIO(); try { Filter filter = FilterImpl.createFilter(filterStr); Binding binding = postOffice.getBinding(new SimpleString(otherQueueName)); if (binding == null) { throw ActiveMQMessageBundle.BUNDLE.noQueueFound(otherQueueName); } int retValue = queue.moveReferences(flushLimit, filter, binding.getAddress(), rejectDuplicates); return retValue; } finally { blockOnIO(); } }
public void connectionCreated( final ActiveMQComponent component, final Connection connection, final String protocol) { if (connections.putIfAbsent(connection.getID(), (NettyServerConnection) connection) != null) { throw ActiveMQMessageBundle.BUNDLE.connectionExists(connection.getID()); } listener.connectionCreated(component, connection, protocol); }
public void compareJournalInformation(final JournalLoadInformation[] journalInformation) throws ActiveMQException { if (!activation.isRemoteBackupUpToDate()) { throw ActiveMQMessageBundle.BUNDLE.journalsNotInSync(); } if (journalLoadInformation == null || journalLoadInformation.length != journalInformation.length) { throw ActiveMQMessageBundle.BUNDLE.replicationTooManyJournals(); } for (int i = 0; i < journalInformation.length; i++) { if (!journalInformation[i].equals(journalLoadInformation[i])) { ActiveMQServerLogger.LOGGER.journalcomparisonMismatch( journalParametersToString(journalInformation)); throw ActiveMQMessageBundle.BUNDLE.replicationTooManyJournals(); } } }
@Override public void handlePacket(final Packet packet) { PacketImpl response = new ReplicationResponseMessage(); final byte type = packet.getType(); try { if (!started) { return; } if (type == PacketImpl.REPLICATION_APPEND) { handleAppendAddRecord((ReplicationAddMessage) packet); } else if (type == PacketImpl.REPLICATION_APPEND_TX) { handleAppendAddTXRecord((ReplicationAddTXMessage) packet); } else if (type == PacketImpl.REPLICATION_DELETE) { handleAppendDelete((ReplicationDeleteMessage) packet); } else if (type == PacketImpl.REPLICATION_DELETE_TX) { handleAppendDeleteTX((ReplicationDeleteTXMessage) packet); } else if (type == PacketImpl.REPLICATION_PREPARE) { handlePrepare((ReplicationPrepareMessage) packet); } else if (type == PacketImpl.REPLICATION_COMMIT_ROLLBACK) { handleCommitRollback((ReplicationCommitMessage) packet); } else if (type == PacketImpl.REPLICATION_PAGE_WRITE) { handlePageWrite((ReplicationPageWriteMessage) packet); } else if (type == PacketImpl.REPLICATION_PAGE_EVENT) { handlePageEvent((ReplicationPageEventMessage) packet); } else if (type == PacketImpl.REPLICATION_LARGE_MESSAGE_BEGIN) { handleLargeMessageBegin((ReplicationLargeMessageBeginMessage) packet); } else if (type == PacketImpl.REPLICATION_LARGE_MESSAGE_WRITE) { handleLargeMessageWrite((ReplicationLargeMessageWriteMessage) packet); } else if (type == PacketImpl.REPLICATION_LARGE_MESSAGE_END) { handleLargeMessageEnd((ReplicationLargeMessageEndMessage) packet); } else if (type == PacketImpl.REPLICATION_START_FINISH_SYNC) { response = handleStartReplicationSynchronization((ReplicationStartSyncMessage) packet); } else if (type == PacketImpl.REPLICATION_SYNC_FILE) { handleReplicationSynchronization((ReplicationSyncFileMessage) packet); } else if (type == PacketImpl.REPLICATION_SCHEDULED_FAILOVER) { handleLiveStopping((ReplicationLiveIsStoppingMessage) packet); } else if (type == PacketImpl.BACKUP_REGISTRATION_FAILED) { handleFatalError((BackupReplicationStartFailedMessage) packet); } else { ActiveMQServerLogger.LOGGER.invalidPacketForReplication(packet); } } catch (ActiveMQException e) { ActiveMQServerLogger.LOGGER.errorHandlingReplicationPacket(e, packet); response = new ActiveMQExceptionMessage(e); } catch (Exception e) { ActiveMQServerLogger.LOGGER.errorHandlingReplicationPacket(e, packet); response = new ActiveMQExceptionMessage(ActiveMQMessageBundle.BUNDLE.replicationUnhandledError(e)); } channel.send(response); }
/** * Receives 'raw' journal/page/large-message data from live server for synchronization of logs. * * @param msg * @throws Exception */ private synchronized void handleReplicationSynchronization(ReplicationSyncFileMessage msg) throws Exception { Long id = Long.valueOf(msg.getId()); byte[] data = msg.getData(); SequentialFile channel1; switch (msg.getFileType()) { case LARGE_MESSAGE: { ReplicatedLargeMessage largeMessage = lookupLargeMessage(id, false); if (!(largeMessage instanceof LargeServerMessageInSync)) { ActiveMQServerLogger.LOGGER.largeMessageIncompatible(); return; } LargeServerMessageInSync largeMessageInSync = (LargeServerMessageInSync) largeMessage; channel1 = largeMessageInSync.getSyncFile(); break; } case PAGE: { Page page = getPage(msg.getPageStore(), (int) msg.getId()); channel1 = page.getFile(); break; } case JOURNAL: { JournalSyncFile journalSyncFile = filesReservedForSync.get(msg.getJournalContent()).get(id); FileChannel channel2 = journalSyncFile.getChannel(); if (data == null) { channel2.close(); return; } channel2.write(ByteBuffer.wrap(data)); return; } default: throw ActiveMQMessageBundle.BUNDLE.replicationUnhandledFileType(msg.getFileType()); } if (data == null) { channel1.close(); return; } if (!channel1.isOpen()) { channel1.open(); } channel1.writeDirect(ByteBuffer.wrap(data), true); }
@Override public boolean changeMessagePriority(final long messageID, final int newPriority) throws Exception { checkStarted(); clearIO(); try { if (newPriority < 0 || newPriority > 9) { throw ActiveMQMessageBundle.BUNDLE.invalidNewPriority(newPriority); } return queue.changeReferencePriority(messageID, (byte) newPriority); } finally { blockOnIO(); } }
public QueueInfo( final SimpleString routingName, final SimpleString clusterName, final SimpleString address, final SimpleString filterString, final long id, final int distance) { if (routingName == null) { throw ActiveMQMessageBundle.BUNDLE.routeNameIsNull(); } if (clusterName == null) { throw ActiveMQMessageBundle.BUNDLE.clusterNameIsNull(); } if (address == null) { throw ActiveMQMessageBundle.BUNDLE.addressIsNull(); } this.routingName = routingName; this.clusterName = clusterName; this.address = address; this.filterString = filterString; this.id = id; this.distance = distance; }
@Override public int changeMessagesPriority(final String filterStr, final int newPriority) throws Exception { checkStarted(); clearIO(); try { if (newPriority < 0 || newPriority > 9) { throw ActiveMQMessageBundle.BUNDLE.invalidNewPriority(newPriority); } Filter filter = FilterImpl.createFilter(filterStr); return queue.changeReferencesPriority(filter, (byte) newPriority); } finally { blockOnIO(); } }
@Override public boolean moveMessage( final long messageID, final String otherQueueName, final boolean rejectDuplicates) throws Exception { checkStarted(); clearIO(); try { Binding binding = postOffice.getBinding(new SimpleString(otherQueueName)); if (binding == null) { throw ActiveMQMessageBundle.BUNDLE.noQueueFound(otherQueueName); } return queue.moveReference(messageID, binding.getAddress(), rejectDuplicates); } finally { blockOnIO(); } }
@Override public void onNotification(Notification notification) { if (!(notification.getType() instanceof CoreNotificationType)) return; CoreNotificationType type = (CoreNotificationType) notification.getType(); TypedProperties props = notification.getProperties(); switch (type) { case BINDING_ADDED: { if (!props.containsProperty(ManagementHelper.HDR_BINDING_TYPE)) { throw ActiveMQMessageBundle.BUNDLE.bindingTypeNotSpecified(); } Integer bindingType = props.getIntProperty(ManagementHelper.HDR_BINDING_TYPE); if (bindingType == BindingType.DIVERT_INDEX) { return; } SimpleString address = props.getSimpleStringProperty(ManagementHelper.HDR_ADDRESS); destinations.add(address.toString()); break; } case BINDING_REMOVED: { SimpleString address = props.getSimpleStringProperty(ManagementHelper.HDR_ADDRESS); destinations.remove(address.toString()); break; } default: // ignore all others break; } }
@Override public boolean page( ServerMessage message, final Transaction tx, RouteContextList listCtx, final ReadLock managerLock) throws Exception { if (!running) { throw new IllegalStateException("PagingStore(" + getStoreName() + ") not initialized"); } boolean full = isFull(); if (addressFullMessagePolicy == AddressFullMessagePolicy.DROP || addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) { if (full) { if (!printedDropMessagesWarning) { printedDropMessagesWarning = true; ActiveMQServerLogger.LOGGER.pageStoreDropMessages(storeName, sizeInBytes.get(), maxSize); } if (message.isLargeMessage()) { ((LargeServerMessage) message).deleteFile(); } if (addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) { throw ActiveMQMessageBundle.BUNDLE.addressIsFull(address.toString()); } // Address is full, we just pretend we are paging, and drop the data return true; } else { return false; } } else if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK) { return false; } // We need to ensure a read lock, as depage could change the paging state lock.readLock().lock(); try { // First check done concurrently, to avoid synchronization and increase throughput if (!paging) { return false; } } finally { lock.readLock().unlock(); } managerLock.lock(); try { lock.writeLock().lock(); try { if (!paging) { return false; } if (!message.isDurable()) { // The address should never be transient when paging (even for non-persistent messages // when paging) // This will force everything to be persisted message.forceAddress(address); } final long transactionID = tx == null ? -1 : tx.getID(); PagedMessage pagedMessage = new PagedMessageImpl(message, routeQueues(tx, listCtx), transactionID); if (message.isLargeMessage()) { ((LargeServerMessage) message).setPaged(); } int bytesToWrite = pagedMessage.getEncodeSize() + Page.SIZE_RECORD; if (currentPageSize.addAndGet(bytesToWrite) > pageSize && currentPage.getNumberOfMessages() > 0) { // Make sure nothing is currently validating or using currentPage openNewPage(); currentPageSize.addAndGet(bytesToWrite); } if (tx != null) { installPageTransaction(tx, listCtx); } // the apply counter will make sure we write a record on journal // especially on the case for non transactional sends and paging // doing this will give us a possibility of recovering the page counters applyPageCounters(tx, getCurrentPage(), listCtx); currentPage.write(pagedMessage); if (tx == null && syncNonTransactional && message.isDurable()) { sync(); } if (isTrace) { ActiveMQServerLogger.LOGGER.trace( "Paging message " + pagedMessage + " on pageStore " + this.getStoreName() + " pageId=" + currentPage.getPageId()); } return true; } finally { lock.writeLock().unlock(); } } finally { managerLock.unlock(); } }
private void handleCreateSession(final CreateSessionMessage request) { boolean incompatibleVersion = false; Packet response; try { Version version = server.getVersion(); if (!version.isCompatible(request.getVersion())) { throw ActiveMQMessageBundle.BUNDLE.incompatibleClientServer(); } if (!server.isStarted()) { throw ActiveMQMessageBundle.BUNDLE.serverNotStarted(); } // XXX HORNETQ-720 Taylor commented out this test. Should be verified. /*if (!server.checkActivate()) { throw new ActiveMQException(ActiveMQException.SESSION_CREATION_REJECTED, "Server will not accept create session requests"); }*/ if (connection.getClientVersion() == 0) { connection.setClientVersion(request.getVersion()); } else if (connection.getClientVersion() != request.getVersion()) { ActiveMQServerLogger.LOGGER.incompatibleVersionAfterConnect( request.getVersion(), connection.getClientVersion()); } Channel channel = connection.getChannel(request.getSessionChannelID(), request.getWindowSize()); ActiveMQPrincipal activeMQPrincipal = null; if (request.getUsername() == null) { activeMQPrincipal = connection.getDefaultActiveMQPrincipal(); } ServerSession session = server.createSession( request.getName(), activeMQPrincipal == null ? request.getUsername() : activeMQPrincipal.getUserName(), activeMQPrincipal == null ? request.getPassword() : activeMQPrincipal.getPassword(), request.getMinLargeMessageSize(), connection, request.isAutoCommitSends(), request.isAutoCommitAcks(), request.isPreAcknowledge(), request.isXA(), request.getDefaultAddress(), new CoreSessionCallback(request.getName(), protocolManager, channel, connection), true); ServerSessionPacketHandler handler = new ServerSessionPacketHandler(session, server.getStorageManager(), channel); channel.setHandler(handler); // TODO - where is this removed? protocolManager.addSessionHandler(request.getName(), handler); response = new CreateSessionResponseMessage(server.getVersion().getIncrementingVersion()); } catch (ActiveMQException e) { if (e.getType() == ActiveMQExceptionType.INCOMPATIBLE_CLIENT_SERVER_VERSIONS) { incompatibleVersion = true; logger.debug("Sending ActiveMQException after Incompatible client", e); } else { ActiveMQServerLogger.LOGGER.failedToCreateSession(e); } response = new ActiveMQExceptionMessage(e); } catch (Exception e) { ActiveMQServerLogger.LOGGER.failedToCreateSession(e); response = new ActiveMQExceptionMessage(new ActiveMQInternalErrorException()); } // send the exception to the client and destroy // the connection if the client and server versions // are not compatible if (incompatibleVersion) { channel1.sendAndFlush(response); } else { channel1.send(response); } }