use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.
the class JournalImpl method checkControlFile.
/**
* @throws Exception
*/
private void checkControlFile() throws Exception {
ArrayList<String> dataFiles = new ArrayList<>();
ArrayList<String> newFiles = new ArrayList<>();
ArrayList<Pair<String, String>> renames = new ArrayList<>();
SequentialFile controlFile = AbstractJournalUpdateTask.readControlFile(fileFactory, dataFiles, newFiles, renames);
if (controlFile != null) {
for (String dataFile : dataFiles) {
SequentialFile file = fileFactory.createSequentialFile(dataFile);
if (file.exists()) {
file.delete();
}
}
for (String newFile : newFiles) {
SequentialFile file = fileFactory.createSequentialFile(newFile);
if (file.exists()) {
final String originalName = file.getFileName();
final String newName = originalName.substring(0, originalName.lastIndexOf(".cmp"));
file.renameTo(newName);
}
}
for (Pair<String, String> rename : renames) {
SequentialFile fileTmp = fileFactory.createSequentialFile(rename.getA());
SequentialFile fileTo = fileFactory.createSequentialFile(rename.getB());
// delete a valid file depending on where the crash occurred during the control file delete
if (fileTmp.exists()) {
fileTo.delete();
fileTmp.renameTo(rename.getB());
}
}
controlFile.delete();
}
cleanupTmpFiles(".cmp");
cleanupTmpFiles(".tmp");
return;
}
use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.
the class ActiveMQServerImpl method loadJournals.
private JournalLoadInformation[] loadJournals() throws Exception {
JournalLoader journalLoader = activation.createJournalLoader(postOffice, pagingManager, storageManager, queueFactory, nodeManager, managementService, groupingHandler, configuration, parentServer);
JournalLoadInformation[] journalInfo = new JournalLoadInformation[2];
List<QueueBindingInfo> queueBindingInfos = new ArrayList<>();
List<GroupingInfo> groupingInfos = new ArrayList<>();
List<AddressBindingInfo> addressBindingInfos = new ArrayList<>();
journalInfo[0] = storageManager.loadBindingJournal(queueBindingInfos, groupingInfos, addressBindingInfos);
recoverStoredConfigs();
Map<Long, AddressBindingInfo> addressBindingInfosMap = new HashMap<>();
journalLoader.initAddresses(addressBindingInfosMap, addressBindingInfos);
Map<Long, QueueBindingInfo> queueBindingInfosMap = new HashMap<>();
journalLoader.initQueues(queueBindingInfosMap, queueBindingInfos);
journalLoader.handleGroupingBindings(groupingInfos);
Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap = new HashMap<>();
HashSet<Pair<Long, Long>> pendingLargeMessages = new HashSet<>();
List<PageCountPending> pendingNonTXPageCounter = new LinkedList<>();
journalInfo[1] = storageManager.loadMessageJournal(postOffice, pagingManager, resourceManager, queueBindingInfosMap, duplicateIDMap, pendingLargeMessages, pendingNonTXPageCounter, journalLoader);
journalLoader.handleDuplicateIds(duplicateIDMap);
for (Pair<Long, Long> msgToDelete : pendingLargeMessages) {
ActiveMQServerLogger.LOGGER.deletingPendingMessage(msgToDelete);
LargeServerMessage msg = storageManager.createLargeMessage();
msg.setMessageID(msgToDelete.getB());
msg.setPendingRecordID(msgToDelete.getA());
msg.setDurable(true);
msg.deleteFile();
}
if (pendingNonTXPageCounter.size() != 0) {
try {
journalLoader.recoverPendingPageCounters(pendingNonTXPageCounter);
} catch (Throwable e) {
ActiveMQServerLogger.LOGGER.errorRecoveringPageCounter(e);
}
}
journalLoader.cleanUp();
return journalInfo;
}
use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.
the class QueueImpl method locateTargetBinding.
private Pair<String, Binding> locateTargetBinding(SimpleString queueSuffix, Message copyMessage, long oldQueueID) {
String targetNodeID = null;
Binding targetBinding = null;
for (Map.Entry<SimpleString, Binding> entry : postOffice.getAllBindings().entrySet()) {
Binding binding = entry.getValue();
// we only care about the remote queue bindings
if (binding instanceof RemoteQueueBinding) {
RemoteQueueBinding remoteQueueBinding = (RemoteQueueBinding) binding;
// does this remote queue binding point to the same queue as the message?
if (oldQueueID == remoteQueueBinding.getRemoteQueueID()) {
// get the name of this queue so we can find the corresponding remote queue binding pointing to the scale down target node
SimpleString oldQueueName = remoteQueueBinding.getRoutingName();
// parse the queue name of the remote queue binding to determine the node ID
String temp = remoteQueueBinding.getQueue().getName().toString();
targetNodeID = temp.substring(temp.lastIndexOf(".") + 1);
logger.debug("Message formerly destined for " + oldQueueName + " with ID: " + oldQueueID + " on address " + copyMessage.getAddressSimpleString() + " on node " + targetNodeID);
// now that we have the name of the queue we need to look through all the bindings again to find the new remote queue binding
for (Map.Entry<SimpleString, Binding> entry2 : postOffice.getAllBindings().entrySet()) {
binding = entry2.getValue();
// again, we only care about the remote queue bindings
if (binding instanceof RemoteQueueBinding) {
remoteQueueBinding = (RemoteQueueBinding) binding;
temp = remoteQueueBinding.getQueue().getName().toString();
targetNodeID = temp.substring(temp.lastIndexOf(".") + 1);
if (oldQueueName.equals(remoteQueueBinding.getRoutingName()) && targetNodeID.equals(queueSuffix.toString())) {
targetBinding = remoteQueueBinding;
if (logger.isDebugEnabled()) {
logger.debug("Message now destined for " + remoteQueueBinding.getRoutingName() + " with ID: " + remoteQueueBinding.getRemoteQueueID() + " on address " + copyMessage.getAddress() + " on node " + targetNodeID);
}
break;
} else {
logger.debug("Failed to match: " + remoteQueueBinding);
}
}
}
}
}
}
return new Pair<>(targetNodeID, targetBinding);
}
use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.
the class ScaleDownHandler method scaleDownDuplicateIDs.
public void scaleDownDuplicateIDs(Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap, ClientSessionFactory sessionFactory, SimpleString managementAddress, String user, String password) throws Exception {
try (ClientSession session = sessionFactory.createSession(user, password, true, false, false, false, 0);
ClientProducer producer = session.createProducer(managementAddress)) {
// todo - https://issues.jboss.org/browse/HORNETQ-1336
for (Map.Entry<SimpleString, List<Pair<byte[], Long>>> entry : duplicateIDMap.entrySet()) {
ClientMessage message = session.createMessage(false);
List<Pair<byte[], Long>> list = entry.getValue();
String[] array = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
Pair<byte[], Long> pair = list.get(i);
array[i] = new String(pair.getA());
}
ManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, "updateDuplicateIdCache", entry.getKey().toString(), array);
producer.send(message);
}
}
}
use of org.apache.activemq.artemis.api.core.Pair in project activemq-artemis by apache.
the class ScaleDownHandler method scaleDownTransactions.
public void scaleDownTransactions(ClientSessionFactory sessionFactory, ResourceManager resourceManager, String user, String password) throws Exception {
ClientSession session = sessionFactory.createSession(user, password, true, false, false, false, 0);
ClientSession queueCreateSession = sessionFactory.createSession(user, password, false, true, true, false, 0);
List<Xid> preparedTransactions = resourceManager.getPreparedTransactions();
Map<String, Long> queueIDs = new HashMap<>();
for (Xid xid : preparedTransactions) {
logger.debug("Scaling down transaction: " + xid);
Transaction transaction = resourceManager.getTransaction(xid);
session.start(xid, XAResource.TMNOFLAGS);
List<TransactionOperation> allOperations = transaction.getAllOperations();
// Get the information of the Prepared TXs so it could replay the TXs
Map<Message, Pair<List<Long>, List<Long>>> queuesToSendTo = new HashMap<>();
for (TransactionOperation operation : allOperations) {
if (operation instanceof PostOfficeImpl.AddOperation) {
PostOfficeImpl.AddOperation addOperation = (PostOfficeImpl.AddOperation) operation;
List<MessageReference> refs = addOperation.getRelatedMessageReferences();
for (MessageReference ref : refs) {
Message message = ref.getMessage();
Queue queue = ref.getQueue();
long queueID;
String queueName = queue.getName().toString();
if (queueIDs.containsKey(queueName)) {
queueID = queueIDs.get(queueName);
} else {
queueID = createQueueIfNecessaryAndGetID(queueCreateSession, queue, message.getAddressSimpleString());
// store it so we don't have to look it up every time
queueIDs.put(queueName, queueID);
}
Pair<List<Long>, List<Long>> queueIds = queuesToSendTo.get(message);
if (queueIds == null) {
queueIds = new Pair<List<Long>, List<Long>>(new ArrayList<Long>(), new ArrayList<Long>());
queuesToSendTo.put(message, queueIds);
}
queueIds.getA().add(queueID);
}
} else if (operation instanceof RefsOperation) {
RefsOperation refsOperation = (RefsOperation) operation;
List<MessageReference> refs = refsOperation.getReferencesToAcknowledge();
for (MessageReference ref : refs) {
Message message = ref.getMessage();
Queue queue = ref.getQueue();
long queueID;
String queueName = queue.getName().toString();
if (queueIDs.containsKey(queueName)) {
queueID = queueIDs.get(queueName);
} else {
queueID = createQueueIfNecessaryAndGetID(queueCreateSession, queue, message.getAddressSimpleString());
// store it so we don't have to look it up every time
queueIDs.put(queueName, queueID);
}
Pair<List<Long>, List<Long>> queueIds = queuesToSendTo.get(message);
if (queueIds == null) {
queueIds = new Pair<List<Long>, List<Long>>(new ArrayList<Long>(), new ArrayList<Long>());
queuesToSendTo.put(message, queueIds);
}
queueIds.getA().add(queueID);
queueIds.getB().add(queueID);
}
}
}
ClientProducer producer = session.createProducer();
for (Map.Entry<Message, Pair<List<Long>, List<Long>>> entry : queuesToSendTo.entrySet()) {
List<Long> ids = entry.getValue().getA();
ByteBuffer buffer = ByteBuffer.allocate(ids.size() * 8);
for (Long id : ids) {
buffer.putLong(id);
}
Message message = entry.getKey();
message.putBytesProperty(Message.HDR_ROUTE_TO_IDS.toString(), buffer.array());
ids = entry.getValue().getB();
if (ids.size() > 0) {
buffer = ByteBuffer.allocate(ids.size() * 8);
for (Long id : ids) {
buffer.putLong(id);
}
message.putBytesProperty(Message.HDR_ROUTE_TO_ACK_IDS.toString(), buffer.array());
}
producer.send(message.getAddressSimpleString().toString(), message);
}
session.end(xid, XAResource.TMSUCCESS);
session.prepare(xid);
}
}
Aggregations