// if (entries != null && entries.size() > 1)
// log.severe("the entries are '" + entries.size() + "' but we currently only can process one single entry at a time");
// check if already processed ... and at the same time do the versioning transformation (if needed)
for (int i=entries.size()-1; i > -1; i--) {
ReferenceEntry entry = (ReferenceEntry)entries.get(i);
MsgUnit msgUnit = entry.getMsgUnit();
ClientProperty alreadyProcessed = msgUnit.getQosData().getClientProperty(ReplicationConstants.ALREADY_PROCESSED_ATTR);
if (alreadyProcessed != null) {
log.warning("Received entry for client '" + this.slaveSessionId + "' which was already processed. Will remove it");
queue.removeRandom(entry);
entries.remove(i);
}
else
doTransform(msgUnit);
}
// check if one of the messages is the transition end tag, also check if the total size is exceeded
ArrayList remoteEntries = new ArrayList();
long totalSize = 0L;
for (int i=0; i < entries.size(); i++) {
ReferenceEntry entry = (ReferenceEntry)entries.get(i);
MsgUnit msgUnit = entry.getMsgUnit();
ClientProperty endMsg = msgUnit.getQosData().getClientProperty(ReplicationConstants.END_OF_TRANSITION);
// check if the message is the end of the data (only sent in case the initial data has to be stored on
// file in which case the dispatcher shall return in its waiting state.
ClientProperty endOfData = msgUnit.getQosData().getClientProperty(ReplicationConstants.INITIAL_DATA_END);
ClientProperty initialFilesLocation = msgUnit.getQosData().getClientProperty(ReplicationConstants.INITIAL_FILES_LOCATION);
ClientProperty subDirName = msgUnit.getQosData().getClientProperty(ReplicationConstants.INITIAL_DATA_ID);
if (endOfData != null) {
final boolean doPersist = true;
doPause(doPersist);
queue.removeRandom(entry);
// entries.remove(i); // endOfData will be kept locally, not sent to slave
String dirName = "unknown";
if (subDirName != null) {
if (initialFilesLocation != null) {
File base = new File(initialFilesLocation.getStringValue().trim());
File complete = new File(base, subDirName.getStringValue().trim());
dirName = complete.getAbsolutePath();
}
}
changeLastMessage("Manual Data transfer: WAITING (stored on '" + dirName + "')");
break; // we need to interrupt here: all subsequent entries will be processed later.
}
// check if the message has to be stored locally
ClientProperty endToRemote = msgUnit.getQosData().getClientProperty(ReplicationConstants.INITIAL_DATA_END_TO_REMOTE);
if (initialFilesLocation != null && (endToRemote == null || !endToRemote.getBooleanValue()) && (endMsg == null || !endMsg.getBooleanValue())) {
storeChunkLocally(entry, initialFilesLocation, subDirName);
queue.removeRandom(entry);
// entries.remove(i);
continue;
}
if (endMsg != null) {
log.info("Received msg marking the end of the initial for client '" + this.slaveSessionId + "' update: '" + this.name + "' going into NORMAL operations");
startCascadedAndChangeStatus();
}
byte[] content = msgUnit.getContent();
if (content != null)
totalSize += content.length;
if (totalSize <= this.maxChunkSize || i == 0)
remoteEntries.add(entry);
else
break;
}
entries = null; // we can free it here since not needed anymore
if (this.status == STATUS_NORMAL || this.status == STATUS_INCONSISTENT || this.status == STATUS_UNCONFIGURED)
return remoteEntries;
ArrayList ret = new ArrayList();
for (int i=0; i < remoteEntries.size(); i++) {
ReferenceEntry entry = (ReferenceEntry)remoteEntries.get(i);
MsgUnit msgUnit = entry.getMsgUnit();
long replKey = msgUnit.getQosData().getClientProperty(ReplicationConstants.REPL_KEY_ATTR, -1L);
/* this is done when acknowledge comes
if (replKey > -1L) {
setMaxReplKey(replKey, this.tmpTransSeq, this.tmpMsgSeq);
}
*/
log.info("check: processing '" + replKey + "' for client '" + this.slaveSessionId + "' ");
if (replKey < 0L) { // this does not come from the normal replication, so these are other messages which we just deliver
ClientProperty endMsg = msgUnit.getQosData().getClientProperty(ReplicationConstants.END_OF_TRANSITION);
if (endMsg == null) {
log.warning("the message unit with qos='" + msgUnit.getQosData().toXml() + "' and key '" + msgUnit.getKey() + "' for client '" + this.slaveSessionId + "' has no 'replKey' Attribute defined.");
ret.add(entry);
continue;
}
}
log.info("repl entry '" + replKey + "' for range [" + this.minReplKey + "," + this.maxReplKey + "] for client '" + this.slaveSessionId + "' ");
if (replKey >= this.minReplKey || this.forceSending) {
log.info("repl adding the entry for client '" + this.slaveSessionId + "' ");
doTransform(msgUnit);
ret.add(entry);
/* TODO TEMPORARLY REMOVED FOR TESTING: also test no initial dump and manual transfer
if (replKey > this.maxReplKey || this.forceSending) {
log.info("entry with replKey='" + replKey + "' is higher than maxReplKey)='" + this.maxReplKey + "' switching to normal operation again for client '" + this.slaveSessionId + "' ");
startCascadedAndChangeStatus();
}
*/
}
else { // such messages have been already from the initial update. (obsolete messages are removed)
log.info("removing entry with replKey='" + replKey + "' since older than minEntry='" + this.minReplKey + "' for client '" + this.slaveSessionId + "' ");
queue.removeRandom(entry);
}
}
// check if there are more than one entry the keep-transaction-flag has to be set:
if (ret.size() > 1) {
for (int i=0; i < ret.size()-1; i++) {
ReferenceEntry entry = (ReferenceEntry)entries.get(i);
MsgUnit msgUnit = entry.getMsgUnit();
msgUnit.getQosData().addClientProperty(KEEP_TRANSACTION_OPEN, true);
}
log.info("Sending '" + ret.size() + "' entries in one single message");
}
return ret;