Package org.apache.sandesha2.msgprocessors

Source Code of org.apache.sandesha2.msgprocessors.AckRequestedProcessor

/*
* 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.sandesha2.msgprocessors;

import java.util.Collection;
import java.util.Iterator;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.OperationContextFactory;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.transport.TransportUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sandesha2.RMMsgContext;
import org.apache.sandesha2.Sandesha2Constants;
import org.apache.sandesha2.SandeshaException;
import org.apache.sandesha2.i18n.SandeshaMessageHelper;
import org.apache.sandesha2.i18n.SandeshaMessageKeys;
import org.apache.sandesha2.policy.SandeshaPolicyBean;
import org.apache.sandesha2.security.SecurityManager;
import org.apache.sandesha2.security.SecurityToken;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.beanmanagers.SenderBeanMgr;
import org.apache.sandesha2.storage.beans.RMDBean;
import org.apache.sandesha2.storage.beans.SenderBean;
import org.apache.sandesha2.util.FaultManager;
import org.apache.sandesha2.util.MsgInitializer;
import org.apache.sandesha2.util.RMMsgCreator;
import org.apache.sandesha2.util.SOAPAbstractFactory;
import org.apache.sandesha2.util.SandeshaUtil;
import org.apache.sandesha2.util.SpecSpecificConstants;
import org.apache.sandesha2.util.WSRMMessageSender;
import org.apache.sandesha2.wsrm.AckRequested;

/**
* Responsible for processing ack requested headers on incoming messages.
*/

public class AckRequestedProcessor extends WSRMMessageSender {

  private static final Log log = LogFactory.getLog(AckRequestedProcessor.class);

  public boolean processAckRequestedHeaders(RMMsgContext message) throws AxisFault {
    if (log.isDebugEnabled())
      log.debug("Enter: AckRequestedProcessor::processAckRequestHeaders");

    SOAPEnvelope envelope = message.getMessageContext().getEnvelope();
    SOAPHeader header = envelope.getHeader();
    boolean msgCtxPaused = false;
    if(header!=null)
    {
      for(int i = 0; i < Sandesha2Constants.SPEC_NS_URIS.length; i++) {
        QName headerName = new QName(Sandesha2Constants.SPEC_NS_URIS[i], Sandesha2Constants.WSRM_COMMON.ACK_REQUESTED);
       
        Iterator acks = header.getChildrenWithName(headerName);
        while(acks.hasNext()) {
          OMElement ack = (OMElement) acks.next();
          AckRequested ackReq = new AckRequested(headerName.getNamespaceURI());
          ackReq.fromOMElement(ack);
          boolean paused = processAckRequestedHeader(message, ack, ackReq);
          //if nto already paused we might be now
          if(!msgCtxPaused){
            msgCtxPaused = paused;
          }
        }
      }     
    }

    if (log.isDebugEnabled())
      log.debug("Exit: AckRequestedProcessor::processAckRequestHeaders " + msgCtxPaused);
    return msgCtxPaused;
  }

  /**
   *
   * @param msgContext
   * @param soapHeader
   * @param ackRequested
   * @return true if the msg context was paused
   * @throws AxisFault
   */
  public boolean processAckRequestedHeader(RMMsgContext rmMsgCtx, OMElement soapHeader, AckRequested ackRequested) throws AxisFault {
    if (log.isDebugEnabled())
      log.debug("Enter: AckRequestedProcessor::processAckRequestedHeader " + soapHeader);

    //checks weather the ack request was a piggybacked one.
    boolean piggybackedAckRequest = !(rmMsgCtx.getMessageType()==Sandesha2Constants.MessageTypes.ACK_REQUEST);
   
    String sequenceId = ackRequested.getIdentifier().getIdentifier();

    MessageContext msgContext = rmMsgCtx.getMessageContext();
    ConfigurationContext configurationContext = msgContext.getConfigurationContext();

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,
        configurationContext.getAxisConfiguration());
   
    // Check that the sender of this AckRequest holds the correct token
    RMDBean rmdBean = SandeshaUtil.getRMDBeanFromSequenceId(storageManager, sequenceId);

    if(rmdBean != null && rmdBean.getSecurityTokenData() != null) {
      SecurityManager secManager = SandeshaUtil.getSecurityManager(configurationContext);
      SecurityToken token = secManager.recoverSecurityToken(rmdBean.getSecurityTokenData());
     
      secManager.checkProofOfPossession(token, soapHeader, msgContext);
    }

    // Check that the sequence requested exists
    if (FaultManager.checkForUnknownSequence(rmMsgCtx, sequenceId, storageManager, piggybackedAckRequest)) {
      if (log.isDebugEnabled())
        log.debug("Exit: AckRequestedProcessor::processAckRequestedHeader, Unknown sequence ");
      return false;
    }

    // throwing a fault if the sequence is terminated
    if (FaultManager.checkForSequenceTerminated(rmMsgCtx, sequenceId, rmdBean, piggybackedAckRequest)) {
      if (log.isDebugEnabled())
        log.debug("Exit: AckRequestedProcessor::processAckRequestedHeader, Sequence terminated");
      return false;
    }

    // Setting the ack depending on AcksTo.
    EndpointReference acksTo = new EndpointReference(rmdBean.getAcksToEPR());
    String acksToStr = acksTo.getAddress();

    if (acksToStr == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(SandeshaMessageKeys.acksToStrNotSet));

    //Getting the operation for ack messages.
    AxisOperation ackOperation = SpecSpecificConstants.getWSRMOperation(
        Sandesha2Constants.MessageTypes.ACK,
        rmdBean.getRMVersion(),
        msgContext.getAxisService());
   
    MessageContext ackMsgCtx = SandeshaUtil.createNewRelatedMessageContext(rmMsgCtx, ackOperation);
   
    //setting up the RMMsgContext
    RMMsgContext ackRMMsgCtx = MsgInitializer.initializeMessage(ackMsgCtx);
    ackRMMsgCtx.setRMNamespaceValue(rmMsgCtx.getRMNamespaceValue());
       
    ackMsgCtx.setTo(acksTo);
       
    ackRMMsgCtx.setRMNamespaceValue(rmMsgCtx.getRMNamespaceValue());
   
    if (ackMsgCtx.getMessageID()==null)
      ackMsgCtx.setMessageID(SandeshaUtil.getUUID());
   
    //adding the SOAP Envelope
    SOAPFactory factory = SOAPAbstractFactory.getSOAPFactory(SandeshaUtil.getSOAPVersion(msgContext.getEnvelope()));
    SOAPEnvelope envelope = factory.getDefaultEnvelope();
    try {
      ackMsgCtx.setEnvelope(envelope);
    } catch (AxisFault e3) {
      throw new SandeshaException(e3.getMessage());
    }

    ackMsgCtx.setReplyTo(msgContext.getTo());
    RMMsgCreator.addAckMessage(ackRMMsgCtx, sequenceId, rmdBean);
   
    //this is not a client generated message. So set serverSide to true.
    ackMsgCtx.setServerSide(true);

    if (acksTo.hasAnonymousAddress()) {
      //If acksTo is anonymous we will be sending the ack here it self. Transport will use what ever mechanism to send the
      //message. (for e.g. HTTP will use the back channel)

      // setting "response written" since acksto is anonymous
     
      //adding an OperationContext if one is not available. (for e.g. If we are in the SandeshaGlobalInHandler)
      if (rmMsgCtx.getMessageContext().getOperationContext() == null) {
        // operation context will be null when doing in a GLOBAL
        // handler.
       
        ServiceContext serviceCtx = msgContext.getServiceContext();
        OperationContext opCtx =  OperationContextFactory.createOperationContext(ackOperation.getAxisSpecificMEPConstant(), ackOperation, serviceCtx);

        rmMsgCtx.getMessageContext().setOperationContext(opCtx);
      }
     
      try {
        AxisEngine.send(ackMsgCtx);
        TransportUtils.setResponseWritten(ackMsgCtx, true);
      } catch (AxisFault e1) {
        throw new SandeshaException(e1.getMessage());
      }

    } else {
      //If AcksTo is non-anonymous we will be adding a senderBean entry here. The sender is responsible
      //for sending it out.
     
      SenderBeanMgr senderBeanMgr = storageManager.getSenderBeanMgr();

      String key = SandeshaUtil.getUUID();

      // dumping to the storage will be done be Sandesha2 Transport Sender
      // storageManager.storeMessageContext(key,ackMsgCtx);

      SenderBean ackBean = new SenderBean();
      ackBean.setMessageContextRefKey(key);
      ackBean.setMessageID(ackMsgCtx.getMessageID());
     
      //acks are sent only once.
      ackBean.setReSend(false);
     
      ackBean.setSequenceID(sequenceId);
     
      EndpointReference to = ackMsgCtx.getTo();
      if (to!=null)
        ackBean.setToAddress(to.getAddress());

      // this will be set to true in the sender.
      ackBean.setSend(true);

      ackMsgCtx.setProperty(Sandesha2Constants.QUALIFIED_FOR_SENDING, Sandesha2Constants.VALUE_FALSE);
      ackBean.setMessageType(Sandesha2Constants.MessageTypes.ACK);
      SandeshaPolicyBean propertyBean = SandeshaUtil.getPropertyBean(msgContext.getAxisMessage());

      long ackInterval = propertyBean.getAcknowledgementInterval();

      // Ack will be sent as stand alone, only after the ackknowledgement interval
      long timeToSend = System.currentTimeMillis() + ackInterval;

      // removing old acks.
      SenderBean findBean = new SenderBean();
      findBean.setMessageType(Sandesha2Constants.MessageTypes.ACK);
      Collection coll = senderBeanMgr.find(findBean);
      Iterator it = coll.iterator();

      if (it.hasNext()) {
        SenderBean oldAckBean = (SenderBean) it.next();
        // If there is an old Ack. This Ack will be sent in the old timeToSend.
        timeToSend = oldAckBean.getTimeToSend();
        senderBeanMgr.delete(oldAckBean.getMessageID());
      }

      ackBean.setTimeToSend(timeToSend);

      msgContext.setProperty(Sandesha2Constants.QUALIFIED_FOR_SENDING, Sandesha2Constants.VALUE_FALSE);
     
      // passing the message through sandesha2sender
      SandeshaUtil.executeAndStore(ackRMMsgCtx, key);

      // inserting the new Ack.
      senderBeanMgr.insert(ackBean);

      msgContext.pause();

      if (log.isDebugEnabled())
        log.debug("Exit: AckRequestedProcessor::processAckRequestedHeader " + Boolean.TRUE);
     
    }
   
    //No need to suspend. Just proceed.
    return false;
  }
 
  /**
   * This is used to capture AckRequest messages send by the SandeshaClient.
   * This will send that message using the Sandesha2 Sender.
   *
   * @param rmMsgContext
   */
  public boolean processOutgoingAckRequestMessage (RMMsgContext ackRequestRMMsg) throws AxisFault {

    if (log.isDebugEnabled())
      log.debug("Enter: AckRequestedProcessor::processOutgoingAckRequestMessage");

    setupOutMessage(ackRequestRMMsg);

    AxisOperation ackOperation = SpecSpecificConstants.getWSRMOperation(
        Sandesha2Constants.MessageTypes.ACK,
        getRMVersion(),
        getMsgContext().getAxisService());
    getMsgContext().setAxisOperation(ackOperation);

    ServiceContext serviceCtx = getMsgContext().getServiceContext();
    OperationContext opcontext = OperationContextFactory.createOperationContext(ackOperation.getAxisSpecificMEPConstant(), ackOperation, serviceCtx);
    opcontext.setParent(getMsgContext().getServiceContext());

    getConfigurationContext().registerOperationContext(ackRequestRMMsg.getMessageId(), opcontext);
    getMsgContext().setOperationContext(opcontext);
   
    Iterator iterator = ackRequestRMMsg.getMessageParts(Sandesha2Constants.MessageParts.ACK_REQUEST);
   
    AckRequested ackRequested = null;
    while (iterator.hasNext()) {
      ackRequested = (AckRequested) iterator.next();
    }
   
    if (iterator.hasNext()) {
      throw new SandeshaException (SandeshaMessageHelper.getMessage(SandeshaMessageKeys.ackRequestMultipleParts));
    }
   
    if (ackRequested==null) {
      throw new SandeshaException (SandeshaMessageHelper.getMessage(SandeshaMessageKeys.noAckRequestPartFound));
    }
   
    ackRequestRMMsg.setWSAAction(SpecSpecificConstants.getAckRequestAction (getRMVersion()));
    ackRequestRMMsg.setSOAPAction(SpecSpecificConstants.getAckRequestSOAPAction (getRMVersion()));

    sendOutgoingMessage(ackRequestRMMsg, Sandesha2Constants.MessageTypes.ACK_REQUEST, 0);
   
    // Pause the message context
    ackRequestRMMsg.pause();

    if (log.isDebugEnabled())
      log.debug("Exit: AckRequestedProcessor::processOutgoingAckRequestMessage " + Boolean.TRUE);
   
    return true;

  }

}
TOP

Related Classes of org.apache.sandesha2.msgprocessors.AckRequestedProcessor

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.