public class AcknowledgementProcessor implements MsgProcessor {
public void processMessage(RMMsgContext rmMsgCtx) throws SandeshaException {
SequenceAcknowledgement sequenceAck = (SequenceAcknowledgement) rmMsgCtx
.getMessagePart(Sandesha2Constants.MessageParts.SEQ_ACKNOWLEDGEMENT);
if (sequenceAck == null)
throw new SandeshaException("Sequence acknowledgement part is null");
AbstractContext context = rmMsgCtx.getContext();
if (context == null)
throw new SandeshaException("Context is null");
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))
throw new SandeshaException("OutSequenceId is null");
SequencePropertyBean internalSequenceBean = seqPropMgr.retrieve(
outSequenceId, Sandesha2Constants.SequenceProperties.INTERNAL_SEQUENCE_ID);
if (internalSequenceBean == null || internalSequenceBean.getValue() == null)
throw new SandeshaException("TempSequenceId is not set correctly");
String internalSequenceId = (String) internalSequenceBean.getValue();
//Following happens in the SandeshaGlobal handler
rmMsgCtx.getMessageContext()
.setProperty(Sandesha2Constants.ACK_PROCSSED, "true");
//Removing relatesTo - Some WSRM 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.setInternalSequenceId(internalSequenceId);
Collection retransmitterEntriesOfSequence = retransmitterMgr
.find(input);
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());
}
}
while (nackIterator.hasNext()) {
Nack nack = (Nack) nackIterator.next();
long msgNo = nack.getNackNumber();
//TODO - Process Nack
}
//following get called in the SandesaInHandler
//if (justSendTerminateIfNeeded) {
//If all messages up to last message have been acknowledged.
//Add terminate Sequence message.
SequencePropertyBean lastOutMsgBean = seqPropMgr.retrieve(
internalSequenceId, Sandesha2Constants.SequenceProperties.LAST_OUT_MESSAGE);
if (lastOutMsgBean != null) {
Long lastOutMsgNoLng = (Long) lastOutMsgBean.getValue();
if (lastOutMsgNoLng == null)
throw new SandeshaException(
"Invalid object set for the Last Out Message");
long lastOutMessageNo = lastOutMsgNoLng.longValue();
if (lastOutMessageNo <= 0)
throw new SandeshaException(
"Invalid value set for the last out message");
boolean complete = SandeshaUtil.verifySequenceCompletion(
sequenceAck.getAcknowledgementRanges().iterator(),
lastOutMessageNo);
if (complete) {
addTerminateSequenceMessage(rmMsgCtx, outSequenceId,
internalSequenceId);