Package org.apache.sandesha2.msgprocessors

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

/*
* 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 org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
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.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.client.SandeshaClientConstants;
import org.apache.sandesha2.client.SandeshaListener;
import org.apache.sandesha2.i18n.SandeshaMessageHelper;
import org.apache.sandesha2.i18n.SandeshaMessageKeys;
import org.apache.sandesha2.security.SecurityManager;
import org.apache.sandesha2.security.SecurityToken;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.Transaction;
import org.apache.sandesha2.storage.beanmanagers.RMDBeanMgr;
import org.apache.sandesha2.storage.beans.RMDBean;
import org.apache.sandesha2.storage.beans.RMSBean;
import org.apache.sandesha2.util.FaultManager;
import org.apache.sandesha2.util.MsgInitializer;
import org.apache.sandesha2.util.RMMsgCreator;
import org.apache.sandesha2.util.RangeString;
import org.apache.sandesha2.util.SandeshaUtil;
import org.apache.sandesha2.util.SequenceManager;
import org.apache.sandesha2.util.TerminateManager;
import org.apache.sandesha2.wsrm.Accept;
import org.apache.sandesha2.wsrm.CreateSequence;
import org.apache.sandesha2.wsrm.CreateSequenceResponse;
import org.apache.sandesha2.wsrm.Endpoint;
import org.apache.sandesha2.wsrm.SequenceOffer;

/**
* Responsible for processing an incoming Create Sequence message.
*/

public class CreateSeqMsgProcessor implements MsgProcessor {

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

  public boolean processInMessage(RMMsgContext createSeqRMMsg, Transaction transaction) throws AxisFault {
    if (log.isDebugEnabled())
      log.debug("Enter: CreateSeqMsgProcessor::processInMessage");

    try {
     
      CreateSequence createSeqPart = (CreateSequence) createSeqRMMsg
          .getMessagePart(Sandesha2Constants.MessageParts.CREATE_SEQ);
      if (createSeqPart == null) {
        if (log.isDebugEnabled())
          log.debug(SandeshaMessageHelper.getMessage(SandeshaMessageKeys.noCreateSeqParts));
        FaultManager.makeCreateSequenceRefusedFault(createSeqRMMsg,
                                                    SandeshaMessageHelper.getMessage(SandeshaMessageKeys.noCreateSeqParts),
                                                    new Exception());
        // Return false if an Exception hasn't been thrown.
        if (log.isDebugEnabled())
          log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.FALSE);       
        return false;

      }
 
      MessageContext createSeqMsg = createSeqRMMsg.getMessageContext();
      ConfigurationContext context = createSeqMsg.getConfigurationContext();
      StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(context, context.getAxisConfiguration());
     
      // If the inbound CreateSequence includes a SecurityTokenReference then
      // ask the security manager to resolve that to a token for us. We also
      // check that the Create was secured using the token.
      SecurityManager secManager = SandeshaUtil.getSecurityManager(context);
      OMElement theSTR = createSeqPart.getSecurityTokenReference();
      SecurityToken token = null;
      if(theSTR != null) {
        MessageContext msgcontext = createSeqRMMsg.getMessageContext();
        token = secManager.getSecurityToken(theSTR, msgcontext);
       
        // The create must be the body part of this message, so we check the
        // security of that element.
        OMElement body = msgcontext.getEnvelope().getBody();
        secManager.checkProofOfPossession(token, body, msgcontext);
      }
 
      //if toAddress is RMAnon we may need to terminate the request side sequence here.
      EndpointReference toEPR = createSeqMsg.getTo();
      if (toEPR.hasAnonymousAddress()) {
 
        RMSBean findBean = new RMSBean ();
        findBean.setReplyToEPR(toEPR.getAddress());
        findBean.setTerminationPauserForCS(true);
       
        //TODO recheck
        RMSBean rmsBean = storageManager.getRMSBeanMgr().findUnique(findBean);
        if (rmsBean!=null) {         
          //AckManager hs not done the termination. Do the termination here.
          MessageContext requestSideRefMessage = storageManager.retrieveMessageContext(rmsBean.getReferenceMessageStoreKey(),context);
          if (requestSideRefMessage==null) {
            FaultManager.makeCreateSequenceRefusedFault(createSeqRMMsg,
                SandeshaMessageHelper.getMessage(SandeshaMessageKeys.referencedMessageNotFound, rmsBean.getInternalSequenceID()),
                new Exception());           
            // Return false if an Exception hasn't been thrown.
            if (log.isDebugEnabled())
              log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.FALSE);       
            return false;
          }
         
          RMMsgContext requestSideRefRMMessage = MsgInitializer.initializeMessage(requestSideRefMessage);
          TerminateManager.addTerminateSequenceMessage(requestSideRefRMMessage, rmsBean.getInternalSequenceID(), rmsBean.getSequenceID(), storageManager);
        }
      }
       

      MessageContext outMessage = null;
 
      // Create the new sequence id, as well as establishing the beans that handle the
      // sequence state.
      RMDBean rmdBean = SequenceManager.setupNewSequence(createSeqRMMsg, storageManager, secManager, token);
       
      RMMsgContext createSeqResponse = RMMsgCreator.createCreateSeqResponseMsg(createSeqRMMsg, rmdBean);
      outMessage = createSeqResponse.getMessageContext();
      // Set a message ID for this Create Sequence Response message
      outMessage.setMessageID(SandeshaUtil.getUUID());
       
      createSeqResponse.setFlow(MessageContext.OUT_FLOW);
 
      // for making sure that this won't be processed again
      createSeqResponse.setProperty(Sandesha2Constants.APPLICATION_PROCESSING_DONE, "true");
     
      CreateSequenceResponse createSeqResPart = (CreateSequenceResponse) createSeqResponse
          .getMessagePart(Sandesha2Constants.MessageParts.CREATE_SEQ_RESPONSE);
 
        // OFFER PROCESSING
      SequenceOffer offer = createSeqPart.getSequenceOffer();
      if (offer != null) {
        Accept accept = createSeqResPart.getAccept();
        if (accept == null) {
          if (log.isDebugEnabled())
            log.debug(SandeshaMessageHelper.getMessage(SandeshaMessageKeys.noAcceptPart));
          FaultManager.makeCreateSequenceRefusedFault(createSeqRMMsg,
                                                      SandeshaMessageHelper.getMessage(SandeshaMessageKeys.noAcceptPart),
                                                      new Exception());
          // Return false if an Exception hasn't been thrown.
          if (log.isDebugEnabled())
            log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.FALSE);       
          return false;
        }
 
        // offered seq id
        String offeredSequenceID = offer.getIdentifer().getIdentifier();
       
        boolean offerEcepted = offerAccepted(offeredSequenceID, context, createSeqRMMsg, storageManager);
 
        if (offerEcepted) {
          // Setting the CreateSequence table entry for the outgoing
          // side.
          RMSBean rMSBean = new RMSBean();
          rMSBean.setSequenceID(offeredSequenceID);
          String outgoingSideInternalSequenceId = SandeshaUtil
              .getOutgoingSideInternalSequenceID(rmdBean.getSequenceID());
          rMSBean.setInternalSequenceID(outgoingSideInternalSequenceId);
          // this is a dummy value
          rMSBean.setCreateSeqMsgID(SandeshaUtil.getUUID());
           
          rMSBean.setToEPR(rmdBean.getToEPR());
          rMSBean.setAcksToEPR(rmdBean.getToEPR())// The acks need to flow back into this endpoint
          rMSBean.setReplyToEPR(rmdBean.getReplyToEPR());
          rMSBean.setLastActivatedTime(System.currentTimeMillis());
          rMSBean.setRMVersion(rmdBean.getRMVersion());
          rMSBean.setClientCompletedMessages(new RangeString());
 
          // Setting sequence properties for the outgoing sequence.
          // Only will be used by the server side response path. Will
          // be wasted properties for the client side.
           
          Endpoint endpoint = offer.getEndpoint();
          if (endpoint!=null) {
            // setting the OfferedEndpoint
            rMSBean.setOfferedEndPoint(endpoint.getEPR().getAddress());
          }
   
          rmdBean.setOutboundInternalSequence(outgoingSideInternalSequenceId);
          RMDBeanMgr rmdBeanMgr = storageManager.getRMDBeanMgr();
          rmdBeanMgr.update(rmdBean);
 
          // Store the inbound token (if any) with the new sequence
          rMSBean.setSecurityTokenData(rmdBean.getSecurityTokenData());
         
          // If this new sequence has anonymous acksTo, then we must poll for the acks
          // If the inbound sequence is targetted at the WSRM anonymous URI, we need to start
          // polling for this sequence.
          String acksTo = rMSBean.getAcksToEPR();
          EndpointReference reference = new EndpointReference(acksTo);
          if ((acksTo == null || reference.hasAnonymousAddress()) &&
            Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(createSeqRMMsg.getRMSpecVersion())) {
            rMSBean.setPollingMode(true);
          }
         
          // Set the SOAP Version for this sequence.
          rMSBean.setSoapVersion(SandeshaUtil.getSOAPVersion(createSeqRMMsg.getSOAPEnvelope()));
         
          if (isReplayModel(createSeqRMMsg)) {
            rMSBean.setReplayModel(true);
            rmdBean.setReplayModel(true);
          }
         
          storageManager.getRMSBeanMgr().insert(rMSBean);
         
          SandeshaUtil.startWorkersForSequence(context, rMSBean);
         
        } else {
          // removing the accept part.
          createSeqResPart.setAccept(null);
          createSeqResponse.addSOAPEnvelope();
        }
      }
             
      //TODO add createSequenceResponse message as the referenceMessage to the RMDBean.
 
      outMessage.setResponseWritten(true);
 
      rmdBean.setLastActivatedTime(System.currentTimeMillis());
     
      // If the inbound sequence is targetted at the anonymous URI, we need to start
      // polling for this sequence.
      if (toEPR.hasAnonymousAddress()) {
        if (Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(createSeqRMMsg.getRMSpecVersion())) {
          rmdBean.setPollingMode(true);
        }
      }
     
      storageManager.getRMDBeanMgr().update(rmdBean);
 
      SandeshaUtil.startWorkersForSequence(context, rmdBean);

     
      try{
        AxisEngine.send(outMessage);       
      }
      catch(AxisFault e){
        FaultManager.makeCreateSequenceRefusedFault(createSeqRMMsg,
            SandeshaMessageHelper.getMessage(SandeshaMessageKeys.couldNotSendCreateSeqResponse,
                                             SandeshaUtil.getStackTraceFromException(e)), e);
        // Return false if an Exception hasn't been thrown.
        if (log.isDebugEnabled())
          log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.FALSE);       
        return false;
      }

      // We have done all of our updates, so commit the transaction
      if(transaction != null && transaction.isActive()) {
        transaction.commit();
      }
     
      EndpointReference replyTo = createSeqMsg.getReplyTo();
      if(replyTo == null || replyTo.hasAnonymousAddress()) {
        TransportUtils.setResponseWritten(createSeqMsg, true);
      }
     
  //    SequencePropertyBean findBean = new SequencePropertyBean ();
  //    findBean.setName (Sandesha2Constants.SequenceProperties.TERMINATE_ON_CREATE_SEQUENCE);
  //    findBean.setValue(createSeqMsg.getTo().getAddress());
     
      createSeqRMMsg.pause();
    }
    catch (Exception e) {
      if (log.isDebugEnabled())
        log.debug("Caught an exception processing CreateSequence message", e);
      // Does the message context already contain a fault ?
      // If it doesn't then we can add the CreateSequenceRefusedFault.
      if (createSeqRMMsg.getMessageContext().getProperty(SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME) == null &&
          createSeqRMMsg.getMessageContext().getProperty(SOAP11Constants.SOAP_FAULT_CODE_LOCAL_NAME) == null) {
        // Add the fault details to the message
        FaultManager.makeCreateSequenceRefusedFault(createSeqRMMsg, SandeshaUtil.getStackTraceFromException(e), e);       
       
        // Return false if an Exception hasn't been thrown.
        if (log.isDebugEnabled())
          log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.FALSE);       
        return false;
      }
       
      // If we are SOAP12 and we have already processed the fault - rethrow the exception
      if (createSeqRMMsg.getMessageContext().getProperty(SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME) != null) {
          // throw the original exception
          if (e instanceof AxisFault)
            throw (AxisFault)e;
          
          throw new SandeshaException(e);
      }
    }

    if (log.isDebugEnabled())
      log.debug("Exit: CreateSeqMsgProcessor::processInMessage " + Boolean.TRUE);
    return true;
  }

  private boolean offerAccepted(String sequenceId, ConfigurationContext configCtx, RMMsgContext createSeqRMMsg,
      StorageManager storageManager) throws SandeshaException {
    if (log.isDebugEnabled())
      log.debug("Enter: CreateSeqMsgProcessor::offerAccepted, " + sequenceId);

    if ("".equals(sequenceId)) {
      if (log.isDebugEnabled())
        log.debug("Exit: CreateSeqMsgProcessor::offerAccepted, " + false);
      return false;
    }

    RMSBean createSeqFindBean = new RMSBean();
    createSeqFindBean.setSequenceID(sequenceId);
    Collection arr = storageManager.getRMSBeanMgr().find(createSeqFindBean);

    if (arr.size() > 0) {
      if (log.isDebugEnabled())
        log.debug("Exit: CreateSeqMsgProcessor::offerAccepted, " + false);
      return false;
    }
    if (sequenceId.length() <= 1) {
      if (log.isDebugEnabled())
        log.debug("Exit: CreateSeqMsgProcessor::offerAccepted, " + false);
      return false; // Single character offers are NOT accepted.
    }

    if (log.isDebugEnabled())
      log.debug("Exit: CreateSeqMsgProcessor::offerAccepted, " + true);
    return true;
  }

  public boolean processOutMessage(RMMsgContext rmMsgCtx) {
    if (log.isDebugEnabled())
      log.debug("Enter: CreateSeqMsgProcessor::processOutMessage");

    MessageContext msgCtx = rmMsgCtx.getMessageContext();

    // adding the SANDESHA_LISTENER
    SandeshaListener faultCallback = (SandeshaListener) msgCtx.getOptions().getProperty(
        SandeshaClientConstants.SANDESHA_LISTENER);
    if (faultCallback != null) {
      OperationContext operationContext = msgCtx.getOperationContext();
      if (operationContext != null) {
        operationContext.setProperty(SandeshaClientConstants.SANDESHA_LISTENER, faultCallback);
      }
    }
    if (log.isDebugEnabled())
      log.debug("Exit: CreateSeqMsgProcessor::processOutMessage " + Boolean.FALSE);
    return false;
  }
 
  /**
   * Checks weather the created sequence belong to the reply model. For this following conditions has to be fulfilled.
   *
   * 1. ReplyTo should be anonymous
   * 2. There must be an offer for the response sequence.
   * 3. RM Spec should be 1.0.
   *
   * @param createSequenceMessage
   * @return
   * @throws SandeshaException
   */
  private boolean isReplayModel (RMMsgContext createSequenceMessage) throws SandeshaException {
    boolean replayModel = false;
   
    CreateSequence createSequence = (CreateSequence) createSequenceMessage.getMessagePart(Sandesha2Constants.MessageParts.CREATE_SEQ);
    SequenceOffer offer = createSequence.getSequenceOffer();
   
    EndpointReference replyTo = createSequenceMessage.getReplyTo();
   
    String rmSpecVersion = createSequenceMessage.getRMSpecVersion();
   
    if (offer!=null &&
        replyTo!=null && replyTo.hasAnonymousAddress() &&
        rmSpecVersion!=null && rmSpecVersion.equals(Sandesha2Constants.SPEC_VERSIONS.v1_0))
      replayModel = true;
   
    return replayModel;
  }
 
}
TOP

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

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.