private static final Log log = LogFactory.getLog(AcknowledgementProcessor.class);
public void processInMessage(RMMsgContext rmMsgCtx) throws SandeshaException {
SequenceAcknowledgement sequenceAck = (SequenceAcknowledgement) rmMsgCtx
.getMessagePart(Sandesha2Constants.MessageParts.SEQ_ACKNOWLEDGEMENT);
if (sequenceAck == null) {
String message = "Sequence acknowledgement part is null";
log.debug(message);
throw new SandeshaException(message);
}
MessageContext msgCtx = rmMsgCtx.getMessageContext();
ConfigurationContext configCtx = msgCtx.getConfigurationContext();
//setting mustUnderstand to false.
sequenceAck.setMustUnderstand(false);
rmMsgCtx.addSOAPEnvelope();
StorageManager storageManager = SandeshaUtil
.getSandeshaStorageManager(rmMsgCtx.getMessageContext()
.getConfigurationContext());
SenderBeanMgr retransmitterMgr = storageManager
.getRetransmitterBeanMgr();
SequencePropertyBeanMgr seqPropMgr = storageManager
.getSequencePropretyBeanMgr();
Iterator ackRangeIterator = sequenceAck.getAcknowledgementRanges()
.iterator();
Iterator nackIterator = sequenceAck.getNackList().iterator();
String outSequenceId = sequenceAck.getIdentifier().getIdentifier();
if (outSequenceId == null || "".equals(outSequenceId)) {
String message = "OutSequenceId is null";
log.debug(message);
throw new SandeshaException(message);
}
FaultManager faultManager = new FaultManager();
RMMsgContext faultMessageContext = faultManager.checkForUnknownSequence(rmMsgCtx,outSequenceId);
if (faultMessageContext != null) {
ConfigurationContext configurationContext = msgCtx.getConfigurationContext();
AxisEngine engine = new AxisEngine(configurationContext);
try {
engine.sendFault(faultMessageContext.getMessageContext());
} catch (AxisFault e) {
throw new SandeshaException ("Could not send the fault message",e);
}
return;
}
faultMessageContext = faultManager.checkForInvalidAcknowledgement(rmMsgCtx);
if (faultMessageContext != null) {
ConfigurationContext configurationContext = msgCtx.getConfigurationContext();
AxisEngine engine = new AxisEngine(configurationContext);
try {
engine.sendFault(faultMessageContext.getMessageContext());
} catch (AxisFault e) {
throw new SandeshaException ("Could not send the fault message",e);
}
return;
}
String internalSequenceID = SandeshaUtil.getSequenceProperty(outSequenceId,Sandesha2Constants.SequenceProperties.INTERNAL_SEQUENCE_ID,configCtx);
//updating the last activated time of the sequence.
Transaction lastUpdatedTimeTransaction = storageManager.getTransaction();
SequenceManager.updateLastActivatedTime(internalSequenceID,rmMsgCtx.getMessageContext().getConfigurationContext());
lastUpdatedTimeTransaction.commit();
//Starting transaction
Transaction ackTransaction = storageManager.getTransaction();
SequencePropertyBean internalSequenceBean = seqPropMgr.retrieve(
outSequenceId, Sandesha2Constants.SequenceProperties.INTERNAL_SEQUENCE_ID);
if (internalSequenceBean == null || internalSequenceBean.getValue() == null) {
String message = "TempSequenceId is not set correctly";
log.debug(message);
throw new SandeshaException(message);
}
String internalSequenceId = (String) internalSequenceBean.getValue();
//Following happens in the SandeshaGlobal handler
rmMsgCtx.getMessageContext()
.setProperty(Sandesha2Constants.ACK_PROCSSED, "true");
//Removing relatesTo - Some v1_0 endpoints tend to set relatesTo value for ack messages.
//Because of this dispatching may go wrong. So we set relatesTo value to null for ackMessages.
//(this happens in the SandeshaGlobal handler). Do this only if this is a standalone ACK.
// if (rmMsgCtx.getMessageType() == Sandesha2Constants.MessageTypes.ACK)
// rmMsgCtx.setRelatesTo(null);
SenderBean input = new SenderBean();
input.setSend(true);
input.setReSend(true);
Collection retransmitterEntriesOfSequence = retransmitterMgr
.find(input);
ArrayList ackedMessagesList = new ArrayList ();
while (ackRangeIterator.hasNext()) {
AcknowledgementRange ackRange = (AcknowledgementRange) ackRangeIterator
.next();
long lower = ackRange.getLowerValue();
long upper = ackRange.getUpperValue();
for (long messageNo = lower; messageNo <= upper; messageNo++) {
SenderBean retransmitterBean = getRetransmitterEntry(
retransmitterEntriesOfSequence, messageNo);
if (retransmitterBean != null)
retransmitterMgr.delete(retransmitterBean.getMessageID());
ackedMessagesList.add(new Long (messageNo));
}
}
while (nackIterator.hasNext()) {
Nack nack = (Nack) nackIterator.next();
long msgNo = nack.getNackNumber();
//TODO - Process Nack
}
//setting acked message date.
//TODO add details specific to each message.
long noOfMsgsAcked = getNoOfMessagesAcked(sequenceAck.getAcknowledgementRanges().iterator());
SequencePropertyBean noOfMsgsAckedBean = seqPropMgr.retrieve(outSequenceId,Sandesha2Constants.SequenceProperties.NO_OF_OUTGOING_MSGS_ACKED);
boolean added = false;
if (noOfMsgsAckedBean==null) {
added = true;
noOfMsgsAckedBean = new SequencePropertyBean ();
noOfMsgsAckedBean.setSequenceID(outSequenceId);
noOfMsgsAckedBean.setName(Sandesha2Constants.SequenceProperties.NO_OF_OUTGOING_MSGS_ACKED);
}
noOfMsgsAckedBean.setValue(Long.toString(noOfMsgsAcked));
if (added)
seqPropMgr.insert(noOfMsgsAckedBean);
else
seqPropMgr.update(noOfMsgsAckedBean);
//setting the completed_messages list. This gives all the messages of the sequence that were acked.
SequencePropertyBean allCompletedMsgsBean = seqPropMgr.retrieve(internalSequenceId,Sandesha2Constants.SequenceProperties.CLIENT_COMPLETED_MESSAGES);
if (allCompletedMsgsBean==null) {
allCompletedMsgsBean = new SequencePropertyBean ();
allCompletedMsgsBean.setSequenceID(internalSequenceId);
allCompletedMsgsBean.setName(Sandesha2Constants.SequenceProperties.CLIENT_COMPLETED_MESSAGES);
seqPropMgr.insert(allCompletedMsgsBean);
}
String str = ackedMessagesList.toString();
allCompletedMsgsBean.setValue(str);
seqPropMgr.update(allCompletedMsgsBean);
//commiting transaction
ackTransaction.commit();
String lastOutMsgNoStr = SandeshaUtil.getSequenceProperty(internalSequenceId,Sandesha2Constants.SequenceProperties.LAST_OUT_MESSAGE_NO,configCtx);
if (lastOutMsgNoStr!=null ) {
long highestOutMsgNo = 0;
if (lastOutMsgNoStr!=null) {
highestOutMsgNo = Long.parseLong(lastOutMsgNoStr);
}
if (highestOutMsgNo>0) {
boolean complete = AcknowledgementManager.verifySequenceCompletion (
sequenceAck.getAcknowledgementRanges().iterator(),highestOutMsgNo);
if (complete)
TerminateManager.addTerminateSequenceMessage(rmMsgCtx, outSequenceId,internalSequenceId);
}
}