Package org.servicemix.ws.rm.impl

Source Code of org.servicemix.ws.rm.impl.SimpleReliableMessagingDestination

package org.servicemix.ws.rm.impl;

import java.math.BigInteger;

import org.servicemix.ws.rm.ReliableMessagingDestination;
import org.servicemix.ws.xmlbeans.rm.AckRequestedDocument;
import org.servicemix.ws.xmlbeans.rm.AckRequestedType;
import org.servicemix.ws.xmlbeans.rm.CreateSequenceDocument;
import org.servicemix.ws.xmlbeans.rm.CreateSequenceResponseDocument;
import org.servicemix.ws.xmlbeans.rm.CreateSequenceResponseType;
import org.servicemix.ws.xmlbeans.rm.CreateSequenceType;
import org.servicemix.ws.xmlbeans.rm.SequenceAcknowledgementDocument;
import org.servicemix.ws.xmlbeans.rm.SequenceDocument;
import org.servicemix.ws.xmlbeans.rm.SequenceType;
import org.servicemix.ws.xmlbeans.rm.TerminateSequenceDocument;
import org.servicemix.ws.xmlbeans.rm.TerminateSequenceType;
import org.servicemix.ws.xmlbeans.rm.ExpiresDocument.Expires;
import org.servicemix.ws.xmlbeans.rm.IdentifierDocument.Identifier;
import org.servicemix.ws.xmlbeans.rm.SequenceAcknowledgementDocument.SequenceAcknowledgement;
import org.servicemix.ws.xmlbeans.rm.SequenceAcknowledgementDocument.SequenceAcknowledgement.AcknowledgementRange;

public class SimpleReliableMessagingDestination implements ReliableMessagingDestination {

    SequenceStore sequenceStore = new NonPersistentSequenceStore();
    private static final BigInteger MAX_INTEGER = new BigInteger(""+Integer.MAX_VALUE);
   
    public CreateSequenceResponseDocument createSequence(CreateSequenceDocument requestDoc) {
        CreateSequenceType createSequence = requestDoc.getCreateSequence();
        Sequence s = new Sequence();
        s.acksTo = createSequence.getAcksTo();
        if(createSequence.isSetExpires())
            s.expires = convertToLocalTime(createSequence.getExpires());
       
        sequenceStore.create(s);
       
        CreateSequenceResponseDocument responseDoc = CreateSequenceResponseDocument.Factory.newInstance();
        CreateSequenceResponseType response = responseDoc.addNewCreateSequenceResponse();
        Identifier identifier = response.addNewIdentifier();
        identifier.setStringValue(s.identifier);
        if(s.expires!=0)
            response.setExpires(convertToDuration(s.expires));
           
        return null;
    }

    /**
     * TODO: Need to implement these to support expiring subscriptions
     * @param expires
     * @return
     */
    private Expires convertToDuration(long expires) {
        return null;
    }

    /**
     * TODO: Need to implement these to support expiring subscriptions
     * @param expires
     * @return
     */
    private int convertToLocalTime(Expires expires) {
        return 0;
    }

    public void terminateSequence(TerminateSequenceDocument requestDoc) {
        TerminateSequenceType terminateSequence = requestDoc.getTerminateSequence();
        String identifier = terminateSequence.getIdentifier().getStringValue();
        sequenceStore.delete(identifier);
    }

    public SequenceAcknowledgementDocument assertValid(SequenceDocument doc) {
        SequenceType sequence = doc.getSequence();
        String identifier = sequence.getIdentifier().getStringValue();
        Sequence s = sequenceStore.retrieve(identifier);
       
        if( s == null ) {
            throw new SoapFault(
                    "The value of wsrm:Identifier is not a known Sequence identifier",
                    "Sender",
                    "wsrm:UnknownSequence",
                    sequence.getIdentifier().xmlText());
        }
       
        // Is the message number out of range?
        BigInteger value = sequence.getMessageNumber();
        if( value.compareTo(BigInteger.ZERO) <= 0 || value.compareTo(MAX_INTEGER)>0 ) {
           
            // We must terminate the sequence now.
            sequenceStore.delete(identifier);
           
            throw new SoapFault(
                    "The maximum value for wsrm:MessageNumber has been exceeded",
                    "Sender",
                    "wsrm:MessageNumberRollover",
                    sequence.getIdentifier().xmlText());
        }
       
        int intValue = value.intValue();
       
        // If we received the last message, then check to see if the message being
        // processed exceeds it's sequence.
        if( s.lastMessageNumber>0 && intValue > s.lastMessageNumber) {
            throw new SoapFault(
                    "The value for wsrm:MessageNumber exceeds the value of the MessageNumber  accompanying a LastMessage element in this Sequence.",
                    "Sender",
                    "wsrm:LastMessageNumberExceeded",
                    sequence.getIdentifier().xmlText());
        }
       
        // Is this message comming out of order??       
        if( intValue!=s.lastMessageAcked+1) {
            // This implementation is really simple and just drops out of order
            // messages.
           
            SequenceAcknowledgementDocument resultDoc = SequenceAcknowledgementDocument.Factory.newInstance();
            SequenceAcknowledgement acknowledgement = resultDoc.addNewSequenceAcknowledgement();
            acknowledgement.setIdentifier(sequence.getIdentifier());
            if( s.lastMessageAcked> 0 ) {
                AcknowledgementRange range = acknowledgement.addNewAcknowledgementRange();
                range.setLower(BigInteger.ONE);
                range.setUpper(new BigInteger(""+s.lastMessageAcked));
            }
            acknowledgement.addNack(value);
            return resultDoc;
        }
       
        return null;
    }

    public SequenceAcknowledgementDocument acknowledge(SequenceDocument doc) {
       
        SequenceType sequence = doc.getSequence();
        String identifier = sequence.getIdentifier().getStringValue();
       
        // We might need something like a retrieve for update so that
        // we can lock this record across a cluster
        Sequence s = sequenceStore.retrieve(identifier);
       
        int value = sequence.getMessageNumber().intValue();
        s.lastMessageAcked = value;
        if( sequence.isSetLastMessage() ) {
            s.lastMessageNumber = value;
        }
       
        sequenceStore.update(s);
       
        SequenceAcknowledgementDocument resultDoc = SequenceAcknowledgementDocument.Factory.newInstance();
        SequenceAcknowledgement acknowledgement = resultDoc.addNewSequenceAcknowledgement();
        acknowledgement.setIdentifier(sequence.getIdentifier());
        AcknowledgementRange range = acknowledgement.addNewAcknowledgementRange();
        range.setLower(BigInteger.ONE);
        range.setUpper(new BigInteger(""+s.lastMessageAcked));
       
        return resultDoc;
    }

    public SequenceAcknowledgementDocument acknowledgeRequested(AckRequestedDocument doc) {
        AckRequestedType sequence = doc.getAckRequested();
        String identifier = sequence.getIdentifier().getStringValue();
        Sequence s = sequenceStore.retrieve(identifier);
       
        if( s == null ) {
            throw new SoapFault(
                    "The value of wsrm:Identifier is not a known Sequence identifier",
                    "Sender",
                    "wsrm:UnknownSequence",
                    sequence.getIdentifier().xmlText());
        }
       
        SequenceAcknowledgementDocument resultDoc = SequenceAcknowledgementDocument.Factory.newInstance();
        SequenceAcknowledgement acknowledgement = resultDoc.addNewSequenceAcknowledgement();
        acknowledgement.setIdentifier(sequence.getIdentifier());
        if( s.lastMessageAcked> 0 ) {
            AcknowledgementRange range = acknowledgement.addNewAcknowledgementRange();
            range.setLower(BigInteger.ONE);
            range.setUpper(new BigInteger(""+s.lastMessageAcked));
        }
       
        return resultDoc;
    }

}
TOP

Related Classes of org.servicemix.ws.rm.impl.SimpleReliableMessagingDestination

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.