Package org.apache.sandesha.server.msgprocessors

Source Code of org.apache.sandesha.server.msgprocessors.AcknowledgementProcessor

/*
* Copyright  1999-2004 The Apache Software Foundation.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/
package org.apache.sandesha.server.msgprocessors;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.components.logger.LogFactory;
import org.apache.commons.logging.Log;
import org.apache.sandesha.Constants;
import org.apache.sandesha.EnvelopeCreator;
import org.apache.sandesha.IStorageManager;
import org.apache.sandesha.RMMessageContext;
import org.apache.sandesha.storage.dao.SandeshaQueueDAO;
import org.apache.sandesha.ws.rm.AcknowledgementRange;
import org.apache.sandesha.ws.rm.SequenceAcknowledgement;

import javax.xml.soap.SOAPEnvelope;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
* Processor for the acknowledgements. This will handle both processing of acknowledgements
* and sending acknowledgements. Sending part is required as the user wants synchronous
* acknowldgements to be sent from the server.
*
* @author Jaliya Eknayake
*/
public final class AcknowledgementProcessor implements IRMMessageProcessor {
    private IStorageManager storageManager = null;
    private static final Log log = LogFactory.getLog(SandeshaQueueDAO.class.getName());

    public AcknowledgementProcessor(IStorageManager storageManager) {
        this.storageManager = storageManager;
    }

    public final boolean processMessage(RMMessageContext rmMessageContext) throws AxisFault {
        SequenceAcknowledgement seqAcknowledgement = rmMessageContext.getRMHeaders()
                .getSequenceAcknowledgement();
        String seqID = seqAcknowledgement.getIdentifier().getIdentifier();
        List ackRanges = seqAcknowledgement.getAckRanges();
        Iterator ite = ackRanges.iterator();

        while (ite.hasNext()) {
            AcknowledgementRange ackRange = (AcknowledgementRange) ite.next();
            long msgNumber = ackRange.getMinValue();
            while (ackRange.getMaxValue() >= msgNumber) {
                if (!storageManager.isSentMsg(seqID, msgNumber)) {
                    throw new AxisFault(new javax.xml.namespace.QName(Constants.FaultCodes.WSRM_FAULT_INVALID_ACKNOWLEDGEMENT),
                            Constants.FaultMessages.INVALID_ACKNOWLEDGEMENT, null, null);
                }
                storageManager.setAckReceived(seqID, msgNumber);
                storageManager.setAcknowledged(seqID, msgNumber);
                msgNumber++;
            }
        }
        return false;
    }


    public boolean sendAcknowledgement(RMMessageContext rmMessageContext) throws AxisFault {
        String seqID = rmMessageContext.getSequenceID();

        long messageNumber = rmMessageContext.getRMHeaders().getSequence().getMessageNumber()
                .getMessageNumber();
        String seq = storageManager.getOutgoingSeqenceIdOfIncomingMsg(rmMessageContext);
        Map listOfMsgNumbers = storageManager.getListOfMessageNumbers(seq);

        ArrayList ackRangeList = null;
        if (listOfMsgNumbers != null) {
            ackRangeList = getAckRangesVector(listOfMsgNumbers);
        } else {
            ackRangeList = new ArrayList();
            AcknowledgementRange ackRange = new AcknowledgementRange();
            ackRange.setMaxValue(messageNumber);
            ackRange.setMinValue(messageNumber);
            ackRangeList.add(ackRange);
        }
        RMMessageContext rmMsgContext = getAckRMMsgCtx(rmMessageContext, ackRangeList);

        if (true ==
                (storageManager.getAcksTo(seqID).equals(Constants.WSA.NS_ADDRESSING_ANONYMOUS))) {
            try {
                String soapMsg = rmMsgContext.getMsgContext().getResponseMessage().getSOAPEnvelope()
                        .toString();
                rmMessageContext.getMsgContext().setResponseMessage(new Message(soapMsg));
            } catch (AxisFault af) {
                af.setFaultCodeAsString(Constants.FaultCodes.WSRM_SERVER_INTERNAL_ERROR);
                throw af;
            }
            return true;
        } else {
            //Store the asynchronize ack in the queue. The name for this queue is not yet fixed.
            storageManager.addAcknowledgement(rmMsgContext);
            return false;
        }
    }

    private RMMessageContext getAckRMMsgCtx(RMMessageContext rmMessageContext,
                                            List ackRangeList) {
        RMMessageContext rmMsgContext = new RMMessageContext();
        try {

            String to = storageManager.getAcksTo(rmMessageContext.getRMHeaders().getSequence().getIdentifier().getIdentifier());

            SOAPEnvelope ackEnvelope = EnvelopeCreator.createAcknowledgementEnvelope(rmMessageContext, to, ackRangeList);

            Message resMsg = new Message(ackEnvelope);
            MessageContext msgContext = new MessageContext(rmMessageContext.getMsgContext().getAxisEngine());
            rmMessageContext.copyContents(rmMsgContext);
            msgContext.setResponseMessage(resMsg);
            rmMsgContext.setMsgContext(msgContext);

            //Get the from address to send the Ack. Doesn't matter whether we have Sync or
            // ASync messages. If we have Sync them this property is not used.
            rmMsgContext.setOutGoingAddress(to);
            rmMsgContext.setMessageType(Constants.MSG_TYPE_ACKNOWLEDGEMENT);
        } catch (Exception e) {
            log.error(e);
        }
        return rmMsgContext;
    }

    /**
     * This method will split the input map with messages numbers to respectable
     * message ranges and will return a vector of AcknowledgementRange.
     *
     * @param listOfMsgNumbers
     * @return
     */
    private ArrayList getAckRangesVector(Map listOfMsgNumbers) {
        long min;
        long max;
        long size = listOfMsgNumbers.size();
        ArrayList list = new ArrayList();
        boolean found = false;

        min = ((Long) listOfMsgNumbers.get(new Long(1))).longValue();
        max = min;

        if (size > 1) {
            for (long i = 1; i <= size; i++) {

                if (i + 1 > size) {
                    found = true;
                    max = ((Long) listOfMsgNumbers.get(new Long(i))).longValue();
                } else {

                    if (1 == (((Long) listOfMsgNumbers.get(new Long(i + 1))).longValue() - ((Long) listOfMsgNumbers.get(new Long(i))).longValue())) {
                        max = ((Long) listOfMsgNumbers.get(new Long(i + 1))).longValue();
                        found = true;
                    } else {
                        found = false;
                        max = ((Long) listOfMsgNumbers.get(new Long(i))).longValue();
                        AcknowledgementRange ackRange = new AcknowledgementRange();
                        ackRange.setMaxValue(max);
                        ackRange.setMinValue(min);
                        list.add(ackRange);

                        min = ((Long) listOfMsgNumbers.get(new Long(i + 1))).longValue();
                    }

                }
            }
            if (found) {
                AcknowledgementRange ackRange = new AcknowledgementRange();
                ackRange.setMaxValue(max);
                ackRange.setMinValue(min);
                list.add(ackRange);
            }
        } else {
            AcknowledgementRange ackRange = new AcknowledgementRange();
            ackRange.setMaxValue(max);
            ackRange.setMinValue(min);
            list.add(ackRange);
        }
        return list;
    }
}
TOP

Related Classes of org.apache.sandesha.server.msgprocessors.AcknowledgementProcessor

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.