Package org.apache.sandesha2.util

Source Code of org.apache.sandesha2.util.FaultManager

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

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
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.description.AxisOperation;
import org.apache.axis2.description.AxisOperationFactory;
import org.apache.axis2.om.OMElement;
import org.apache.axis2.soap.SOAP11Constants;
import org.apache.axis2.soap.SOAP12Constants;
import org.apache.axis2.soap.SOAPEnvelope;
import org.apache.axis2.soap.SOAPFactory;
import org.apache.axis2.soap.SOAPHeader;
import org.apache.axis2.util.Utils;
import org.apache.sandesha2.Sandesha2Constants;
import org.apache.sandesha2.FaultData;
import org.apache.sandesha2.RMMsgContext;
import org.apache.sandesha2.SOAPFaultEnvelopeCreator;
import org.apache.sandesha2.SandeshaException;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.beanmanagers.NextMsgBeanMgr;
import org.apache.sandesha2.storage.beanmanagers.SequencePropertyBeanMgr;
import org.apache.sandesha2.storage.beans.NextMsgBean;
import org.apache.sandesha2.storage.beans.SequencePropertyBean;
import org.apache.sandesha2.wsrm.AcknowledgementRange;
import org.apache.sandesha2.wsrm.CreateSequence;
import org.apache.sandesha2.wsrm.Identifier;
import org.apache.sandesha2.wsrm.Sequence;
import org.apache.sandesha2.wsrm.SequenceAcknowledgement;
import org.apache.sandesha2.wsrm.SequenceOffer;
import org.apache.sandesha2.wsrm.TerminateSequence;

/**
* Has logic to check for possible RM related faults and create it.
*
* @author Chamikara Jayalath <chamikaramj@gmail.com>
* @author Sanka Samaranayaka <ssanka@gmail.com>
*/

public class FaultManager {

  public FaultManager() {
  }

  public RMMsgContext checkForPossibleFaults(MessageContext msgCtx)
      throws SandeshaException {

    //Cannot initialize message before checking for MsgNoRoleover - since
    // initialization will give an exception
    //for rolled over messages.

    SOAPEnvelope envelope = msgCtx.getEnvelope();
    if (envelope == null)
      throw new SandeshaException("SOAP Envelope is null");

    RMMsgContext faultMessageContext = null;

    SOAPHeader header = envelope.getHeader();
    if (header != null) {
      OMElement sequenceHeaderBlock = header
          .getFirstChildWithName(new QName(Sandesha2Constants.WSRM.NS_URI_RM,
              Sandesha2Constants.WSRM.SEQUENCE));
      if (sequenceHeaderBlock != null) {
        faultMessageContext = checkForMessageNumberRoleover(msgCtx);
        if (faultMessageContext != null)
          return faultMessageContext;
      }
    }

    RMMsgContext rmMsgCtx = MsgInitializer.initializeMessage(msgCtx);
    int msgType = rmMsgCtx.getMessageType();

    if (msgType == Sandesha2Constants.MessageTypes.APPLICATION
        || msgType == Sandesha2Constants.MessageTypes.TERMINATE_SEQ) {
      faultMessageContext = checkForUnknownSequence(msgCtx);
      if (faultMessageContext != null)
        return faultMessageContext;

    }

    if (msgType == Sandesha2Constants.MessageTypes.CREATE_SEQ) {
      faultMessageContext = checkForCreateSequenceRefused(msgCtx);
      if (faultMessageContext != null)
        return faultMessageContext;
    }

    if (msgType == Sandesha2Constants.MessageTypes.ACK) {
      faultMessageContext = checkForInvalidAcknowledgement(msgCtx);
      if (faultMessageContext != null)
        return faultMessageContext;
    }

    if (msgType == Sandesha2Constants.MessageTypes.APPLICATION) {
      faultMessageContext = checkForLastMsgNumberExceeded(msgCtx);
      if (faultMessageContext != null)
        return faultMessageContext;
    }

    return faultMessageContext;

  }

  /**
   * Check weather the CreateSequence should be refused and generate the fault if it should.
   *
   * @param messageContext
   * @return
   * @throws SandeshaException
   */
  private RMMsgContext checkForCreateSequenceRefused(
      MessageContext messageContext) throws SandeshaException {

    RMMsgContext rmMsgCtx = MsgInitializer
        .initializeMessage(messageContext);

    CreateSequence createSequence = (CreateSequence) rmMsgCtx
        .getMessagePart(Sandesha2Constants.MessageParts.CREATE_SEQ);
    if (createSequence == null)
      throw new SandeshaException(
          "CreateSequence message does not have a CreateSequence part");

    ConfigurationContext context = messageContext.getConfigurationContext();
    StorageManager storageManager = (StorageManager) SandeshaUtil
        .getSandeshaStorageManager(context);
    if (storageManager == null)
      throw new SandeshaException("Storage Manager is null");

    boolean refuseSequence = false;
    String reason = "";

    SequenceOffer offer = createSequence.getSequenceOffer();
    if (offer != null) {
      String offeredSequenceId = offer.getIdentifer().getIdentifier();
      if (offeredSequenceId == null || "".equals(offeredSequenceId)) {
        refuseSequence = true;
        reason = "Offered sequenceId is invalid";
      } else {
        NextMsgBeanMgr nextMsgBeanMgr = storageManager
            .getNextMsgBeanMgr();
        Collection collection = nextMsgBeanMgr.retrieveAll();
        Iterator it = collection.iterator();
        while (it.hasNext()) {

          //checking weather a incoming sequence with the given id
          // exists.
          NextMsgBean nextMsgBean = (NextMsgBean) it.next();
          String sequenceId = nextMsgBean.getSequenceId();
          if (sequenceId.equals(offeredSequenceId)) {
            refuseSequence = true;
            reason = "A sequence with offered sequenceId, already axists";
          }

          //checking weather an outgoing sequence with the given id
          // exists.
          SequencePropertyBeanMgr sequencePropertyBeanMgr = storageManager
              .getSequencePropretyBeanMgr();
          SequencePropertyBean sequencePropertyBean = sequencePropertyBeanMgr
              .retrieve(
                  sequenceId,
                  Sandesha2Constants.SequenceProperties.OUT_SEQUENCE_ID);
          if (sequencePropertyBean != null) {
            String outSequenceId = (String) sequencePropertyBean
                .getValue();
            if (outSequenceId != null
                && outSequenceId.equals(offeredSequenceId)) {
              refuseSequence = true;
              reason = "A sequence with offered sequenceId, already axists";
            }

          }
        }
      }
    }

    //TODO - if (securityTokenReference is present RefuseCreateSequence)

    if (refuseSequence) {

      FaultData data = new FaultData();
      data
          .setType(Sandesha2Constants.SOAPFaults.FaultType.CREATE_SEQUENCE_REFUSED);

      int SOAPVersion = SandeshaUtil.getSOAPVersion(rmMsgCtx
          .getSOAPEnvelope());
      if (SOAPVersion == Sandesha2Constants.SOAPVersion.v1_1)
        data.setCode(SOAP11Constants.FAULT_CODE_SENDER);
      else
        data.setCode(SOAP12Constants.FAULT_CODE_SENDER);

      data
          .setSubcode(Sandesha2Constants.SOAPFaults.Subcodes.CREATE_SEQUENCE_REFUSED);
      data.setReason(reason);
      return getFault(rmMsgCtx, data);
    }

    return null;

  }

  /**
   * Check weather the LastMessage number has been exceeded and generate the fault if it is.
   *
   * @param msgCtx
   * @return
   */
  private RMMsgContext checkForLastMsgNumberExceeded(MessageContext msgCtx) {
    return null;
  }

  private RMMsgContext checkForMessageNumberRoleover(
      MessageContext messageContext) {
    return null;
  }

  /**
   * Check whether a Sequence message (a) belongs to a unknown sequence
   * (generates an UnknownSequence fault) (b) message number exceeds a
   * predifined limit ( genenrates a Message Number Rollover fault)
   *
   * @param msgCtx
   * @return @throws
   *         SandeshaException
   */
  public RMMsgContext checkForUnknownSequence(MessageContext messageContext)
      throws SandeshaException {

    RMMsgContext rmMsgCtx = MsgInitializer
        .initializeMessage(messageContext);
    String sequenceId = null;

    if (rmMsgCtx.getMessageType() == Sandesha2Constants.MessageTypes.APPLICATION) {
      Sequence sequence = (Sequence) rmMsgCtx
          .getMessagePart(Sandesha2Constants.MessageParts.SEQUENCE);
      if (sequence == null)
        throw new SandeshaException(
            "Sequence part not found in the application message");

      sequenceId = sequence.getIdentifier().getIdentifier();

    } else if (rmMsgCtx.getMessageType() == Sandesha2Constants.MessageTypes.ACK) {
      SequenceAcknowledgement sequenceAcknowledgement = (SequenceAcknowledgement) rmMsgCtx
          .getMessagePart(Sandesha2Constants.MessageParts.SEQ_ACKNOWLEDGEMENT);
      sequenceId = sequenceAcknowledgement.getIdentifier()
          .getIdentifier();
    } else if (rmMsgCtx.getMessageType() == Sandesha2Constants.MessageTypes.TERMINATE_SEQ) {
      TerminateSequence terminateSequence = (TerminateSequence) rmMsgCtx
          .getMessagePart(Sandesha2Constants.MessageParts.TERMINATE_SEQ);
      sequenceId = terminateSequence.getIdentifier().getIdentifier();
    } else {
      //sequenceId not found.
      return null;
    }

    StorageManager storageManager = SandeshaUtil
        .getSandeshaStorageManager(messageContext.getConfigurationContext());

    NextMsgBeanMgr mgr = storageManager.getNextMsgBeanMgr();
    SOAPEnvelope envelope = messageContext.getEnvelope();

    Collection coll = mgr.retrieveAll();
    Iterator it = coll.iterator();

    boolean validSequence = false;

    while (it.hasNext()) {
      NextMsgBean nextMsgBean = (NextMsgBean) it.next();
      String tempId = nextMsgBean.getSequenceId();
      if (tempId.equals(sequenceId)) {
        validSequence = true;
        break;
      }
    }

    if (!validSequence) {
      //Return an UnknownSequence error
      int SOAPVersion = SandeshaUtil.getSOAPVersion(envelope);

      FaultData data = new FaultData();
      if (SOAPVersion == Sandesha2Constants.SOAPVersion.v1_1)
        data.setCode(SOAP11Constants.FAULT_CODE_SENDER);
      else
        data.setCode(SOAP12Constants.FAULT_CODE_SENDER);

      data.setSubcode(Sandesha2Constants.SOAPFaults.Subcodes.UNKNOWN_SEQUENCE);

      SOAPFactory factory = SOAPAbstractFactory
          .getSOAPFactory(SOAPVersion);
      Identifier identifier = new Identifier(factory);
      identifier.setIndentifer(sequenceId);
      OMElement identifierOMElem = identifier.getOMElement();
      data.setDetail(identifierOMElem);
      data
          .setReason("The value of wsrm:Identifier is not a known Sequence identifier");

      return getFault(rmMsgCtx, data);

    }

    return null;
  }

  /**
   * Check weather the Acknowledgement is invalid and generate a fault if it is.
   *
   * @param msgCtx
   * @return @throws
   *         SandeshaException
   */
  public RMMsgContext checkForInvalidAcknowledgement(MessageContext msgCtx)
      throws SandeshaException {

    //check lower<=upper
    //TODO acked for not-send message
    RMMsgContext rmMsgContext = new RMMsgContext();
    if (rmMsgContext.getMessageType() != Sandesha2Constants.MessageTypes.ACK)
      return null;

    SequenceAcknowledgement sequenceAcknowledgement = (SequenceAcknowledgement) rmMsgContext
        .getMessagePart(Sandesha2Constants.MessageParts.SEQ_ACKNOWLEDGEMENT);
    List sequenceAckList = sequenceAcknowledgement
        .getAcknowledgementRanges();
    Iterator it = sequenceAckList.iterator();

    while (it.hasNext()) {
      AcknowledgementRange acknowledgementRange = (AcknowledgementRange) it
          .next();
      long upper = acknowledgementRange.getUpperValue();
      long lower = acknowledgementRange.getLowerValue();

      if (lower > upper) {
        //Invalid ack
        FaultData data = new FaultData();
        int SOAPVersion = SandeshaUtil.getSOAPVersion(msgCtx
            .getEnvelope());
        if (SOAPVersion == Sandesha2Constants.SOAPVersion.v1_1)
          data.setCode(SOAP11Constants.FAULT_CODE_SENDER);
        else
          data.setCode(SOAP12Constants.FAULT_CODE_SENDER);

        data.setSubcode(Sandesha2Constants.SOAPFaults.Subcodes.INVALID_ACKNOWLEDGEMENT);
        data.setSubcode("The SequenceAcknowledgement is invalid. Lower value is larger than upper value");
        data.setDetail(sequenceAcknowledgement.getOMElement());

        return getFault(rmMsgContext, data);
      }
    }

    return null;
  }


  /**
   * Returns a RMMessageContext for the fault message. Data for generating the fault is given in the data parameter.
   *
   * @param referenceRMMsgContext
   * @param data
   * @return
   * @throws SandeshaException
   */
  public RMMsgContext getFault(RMMsgContext referenceRMMsgContext,
      FaultData data) throws SandeshaException {

    try {

      MessageContext referenceMessage = referenceRMMsgContext
          .getMessageContext();
      MessageContext faultMsgContext = Utils
          .createOutMessageContext(referenceMessage);

      StorageManager storageManager = SandeshaUtil
          .getSandeshaStorageManager(referenceMessage
              .getConfigurationContext());

      //setting contexts.
      faultMsgContext.setAxisServiceGroup(referenceMessage
          .getAxisServiceGroup());
      faultMsgContext.setAxisService(referenceMessage.getAxisService());
      faultMsgContext.setAxisServiceGroup(referenceMessage
          .getAxisServiceGroup());
      faultMsgContext.setServiceGroupContext(referenceMessage
          .getServiceGroupContext());
      faultMsgContext.setServiceGroupContextId(referenceMessage
          .getServiceGroupContextId());
      faultMsgContext.setServiceContext(referenceMessage
          .getServiceContext());
      faultMsgContext.setServiceContextID(referenceMessage
          .getServiceContextID());

      AxisOperation operation = AxisOperationFactory
          .getAxisOperation(AxisOperationFactory.MEP_CONSTANT_OUT_ONLY);

      OperationContext operationContext = new OperationContext(operation);

      faultMsgContext.setAxisOperation(operation);
      faultMsgContext.setOperationContext(operationContext);

      String acksToStr = null;
      if (referenceRMMsgContext.getMessageType() == Sandesha2Constants.MessageTypes.CREATE_SEQ) {
        CreateSequence createSequence = (CreateSequence) referenceRMMsgContext
            .getMessagePart(Sandesha2Constants.MessageParts.CREATE_SEQ);
        acksToStr = createSequence.getAcksTo().getAddress().getEpr()
            .getAddress();
      } else {
        SequencePropertyBeanMgr seqPropMgr = storageManager
            .getSequencePropretyBeanMgr();
        String sequenceId = data.getSequenceId();
        SequencePropertyBean acksToBean = seqPropMgr.retrieve(
            sequenceId, Sandesha2Constants.SequenceProperties.ACKS_TO_EPR);
        if (acksToBean != null) {
          EndpointReference epr = (EndpointReference) acksToBean
              .getValue();
          if (epr != null)
            acksToStr = epr.getAddress();
        }
      }

      if (acksToStr != null
          && !acksToStr.equals(Sandesha2Constants.WSA.NS_URI_ANONYMOUS)) {
        faultMsgContext.setTo(new EndpointReference(acksToStr));
      }

      int SOAPVersion = SandeshaUtil.getSOAPVersion(referenceMessage
          .getEnvelope());

      SOAPFaultEnvelopeCreator.addSOAPFaultEnvelope(faultMsgContext,
          SOAPVersion, data);

      RMMsgContext faultRMMsgCtx = MsgInitializer
          .initializeMessage(faultMsgContext);

      return faultRMMsgCtx;

    } catch (AxisFault e) {
      throw new SandeshaException(e.getMessage());
    }

  }
}
TOP

Related Classes of org.apache.sandesha2.util.FaultManager

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.