Package org.apache.sandesha2.client

Source Code of org.apache.sandesha2.client.SandeshaClient

/*
* Copyright 2004,2005 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.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;

import javax.xml.namespace.QName;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisOperationFactory;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.msgreceivers.RMMessageReceiver;
import org.apache.sandesha2.policy.SandeshaPolicyBean;
import org.apache.sandesha2.storage.SandeshaStorageException;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.Transaction;
import org.apache.sandesha2.storage.beanmanagers.RMSBeanMgr;
import org.apache.sandesha2.storage.beans.RMSBean;
import org.apache.sandesha2.storage.beans.RMDBean;
import org.apache.sandesha2.util.SandeshaUtil;
import org.apache.sandesha2.util.SpecSpecificConstants;
import org.apache.sandesha2.workers.Invoker;
import org.apache.sandesha2.wsrm.AckRequested;
import org.apache.sandesha2.wsrm.CloseSequence;
import org.apache.sandesha2.wsrm.Identifier;
import org.apache.sandesha2.wsrm.TerminateSequence;

/**
* Contains all the Sandesha2Constants of Sandesha2. Please see sub-interfaces
* to see grouped data.
*/

public class SandeshaClient {

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

  /**
   * Users can get a SequenceReport of the sequence defined by the information
   * given from the passed serviceClient object.
   *
   * @param serviceClient
   * @return
   * @throws SandeshaException
   */
  public static SequenceReport getOutgoingSequenceReport(ServiceClient serviceClient) throws SandeshaException {

    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configurationContext = serviceContext.getConfigurationContext();

    String internalSequenceID = getInternalSequenceIdFromServiceClient(serviceClient);

    return getOutgoingSequenceReport(internalSequenceID, configurationContext);
  }

  public static SequenceReport getOutgoingSequenceReport(String to, String sequenceKey,
      ConfigurationContext configurationContext) throws SandeshaException {

    String internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
    return getOutgoingSequenceReport(internalSequenceID, configurationContext);
  }

  public static SequenceReport getOutgoingSequenceReport(String internalSequenceID, 
      ConfigurationContext configurationContext) throws SandeshaException {
    return getOutgoingSequenceReport(internalSequenceID, configurationContext, true);
  }
 
  public static SequenceReport getOutgoingSequenceReport(String internalSequenceID,
      ConfigurationContext configurationContext, boolean createTransaction) throws SandeshaException {

    SequenceReport sequenceReport = new SequenceReport();
    sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_OUT);

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
    RMSBeanMgr createSeqMgr = storageManager.getRMSBeanMgr();

    Transaction reportTransaction = null;

    try {
      if (createTransaction)
        reportTransaction = storageManager.getTransaction();

      sequenceReport.setInternalSequenceID(internalSequenceID);

      RMSBean createSeqFindBean = new RMSBean();
      createSeqFindBean.setInternalSequenceID(internalSequenceID);

      RMSBean rMSBean = createSeqMgr.findUnique(createSeqFindBean);

      // if data not is available sequence has to be terminated or
      // timedOut.
      if (rMSBean != null && rMSBean.isTerminated()) {

        // check weather this is an terminated sequence.
        sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_TERMINATED);

        fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);

        return sequenceReport;

      } else if (rMSBean != null && rMSBean.isTimedOut()) {

        sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_TIMED_OUT);
       
        fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);

        return sequenceReport;
       
      } else if (rMSBean == null) {

        // sequence must hv been timed out before establishing. No other
        // posibility I can think of.
        // this does not get recorded since there is no key (which is
        // normally the sequenceID) to store it.

        // so, setting the sequence status to INITIAL
        sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_INITIAL);

        // returning the current sequence report.
        return sequenceReport;
      }

      String outSequenceID = rMSBean.getSequenceID();
      if (outSequenceID == null) {
        sequenceReport.setInternalSequenceID(internalSequenceID);
        sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_INITIAL);
        sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_OUT);
        if(rMSBean.getSecurityTokenData() != null) sequenceReport.setSecureSequence(true);

        return sequenceReport;
      }

      sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_ESTABLISHED);
      fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);
     
      if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
      reportTransaction = null;

    } catch (Exception e) {
      // Just log the exception
      if(log.isDebugEnabled()) log.debug("Exception", e);
    } finally {
      if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.rollback();
    }

    return sequenceReport;
  }

  private static void fillOutgoingSequenceInfo(SequenceReport report, RMSBean rmsBean,
      StorageManager storageManager) {
    report.setSequenceID(rmsBean.getSequenceID());

    List completedMessageList = rmsBean.getClientCompletedMessages().getContainedElementsAsNumbersList();

    Iterator iter = completedMessageList.iterator();
    while (iter.hasNext()) {
      report.addCompletedMessage((Long)iter.next());
    }
   
    if(rmsBean.getSecurityTokenData() != null) report.setSecureSequence(true);
  }

  /**
   * Users can get a list of sequenceReports each describing a incoming
   * sequence, which are the sequences the client work as a RMD.
   *
   * @param configCtx
   * @return
   * @throws SandeshaException
   */
  public static List getIncomingSequenceReports(ConfigurationContext configCtx) throws SandeshaException {

    SandeshaReport report = getSandeshaReport(configCtx);
    List incomingSequenceIDs = report.getIncomingSequenceList();
    Iterator incomingSequenceIDIter = incomingSequenceIDs.iterator();

    ArrayList incomingSequenceReports = new ArrayList();

    while (incomingSequenceIDIter.hasNext()) {
      String sequenceID = (String) incomingSequenceIDIter.next();
      SequenceReport incomingSequenceReport = getIncomingSequenceReport(sequenceID, configCtx);
      if (incomingSequenceReport == null) {
        throw new SandeshaException(SandeshaMessageHelper.getMessage(
            SandeshaMessageKeys.incommingSequenceReportNotFound, sequenceID));
      }
      incomingSequenceReports.add(incomingSequenceReport);
    }

    return incomingSequenceReports;
  }

  /**
   * SandeshaReport gives the details of all incoming and outgoing sequences.
   * The outgoing sequence have to pass the initial state (CS/CSR exchange) to
   * be included in a SandeshaReport
   *
   * @param configurationContext
   * @return
   * @throws SandeshaException
   */
  public static SandeshaReport getSandeshaReport(ConfigurationContext configurationContext) throws SandeshaException {

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
    SandeshaReport sandeshaReport = new SandeshaReport();

    Transaction reportTransaction = null;

    try {
      reportTransaction = storageManager.getTransaction();

      List rmsBeans = storageManager.getRMSBeanMgr().find(null);
      Iterator iterator = rmsBeans.iterator();
      while (iterator.hasNext()) {
        RMSBean bean = (RMSBean) iterator.next();
        String sequenceID = bean.getSequenceID();
        sandeshaReport.addToOutgoingSequenceList(sequenceID);
        sandeshaReport.addToOutgoingInternalSequenceMap(sequenceID, bean.getInternalSequenceID());

        SequenceReport report = getOutgoingSequenceReport(bean.getInternalSequenceID(), configurationContext);

        sandeshaReport.addToNoOfCompletedMessagesMap(sequenceID, report.getCompletedMessages().size());
        sandeshaReport.addToSequenceStatusMap(sequenceID, report.getSequenceStatus());
      }

      // incoming sequences
      Collection rmdBeans = storageManager.getRMDBeanMgr().find(null);

      Iterator iter = rmdBeans.iterator();
      while (iter.hasNext()) {
        RMDBean serverCompletedMsgsBean = (RMDBean) iter.next();
        String sequenceID = serverCompletedMsgsBean.getSequenceID();
        sandeshaReport.addToIncomingSequenceList(sequenceID);

        SequenceReport sequenceReport = getIncomingSequenceReport(sequenceID, configurationContext);

        sandeshaReport.addToNoOfCompletedMessagesMap(sequenceID, sequenceReport.getCompletedMessages().size());
        sandeshaReport.addToSequenceStatusMap(sequenceID, sequenceReport.getSequenceStatus());
      }
     
      if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
      reportTransaction = null;

    } catch (Exception e) {
      // just log the error
      if(log.isDebugEnabled()) log.debug("Exception", e);
    } finally {
      if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.rollback();
    }

    return sandeshaReport;
  }

  /**
   * This could be used to create sequences with a given sequence key.
   *
   * @param serviceClient - A configured ServiceClient to be used to invoke RM messages. This need to have Sandesha2 engaged.
   * @param offer - Weather a sequence should be offered for obtaining response messages.
   * @param sequenceKey The sequenceKey of the newly generated sequence.
   * @throws SandeshaException
   */
  public static void createSequence(ServiceClient serviceClient, boolean offer, String sequenceKey) throws SandeshaException {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaClient::createSequence , " + offer + ", " + sequenceKey);
   
    setUpServiceClientAnonymousOperations (serviceClient);
   
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    EndpointReference toEPR = serviceClient.getOptions().getTo();
    if (toEPR == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    String to = toEPR.getAddress();
    if (to == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    if (offer) {
      String offeredSequenceID = SandeshaUtil.getUUID();
      options.setProperty(SandeshaClientConstants.OFFERED_SEQUENCE_ID, offeredSequenceID);
    }

    // setting a new squenceKey if not already set.
    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);

    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);

    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    //When the message is marked as Dummy the application processor will not actually try to send it.
    //But still the create Sequence will be added.

    options.setProperty(SandeshaClientConstants.DUMMY_MESSAGE, Sandesha2Constants.VALUE_TRUE);

    String oldAction = options.getAction();
    options.setAction(SpecSpecificConstants.getCreateSequenceAction(rmSpecVersion));
   
    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configurationContext = serviceContext.getConfigurationContext();

    // cleanup previous sequence
    cleanupTerminatedSequence(to, oldSequenceKey, SandeshaUtil.getSandeshaStorageManager(configurationContext, configurationContext.getAxisConfiguration()));
   
    try {     
      //just to inform the sender.
      serviceClient.fireAndForget (null);
    } catch (AxisFault e) {
      throw new SandeshaException(e);
    }
    finally {
      options.setAction(oldAction);
     
      options.setProperty(SandeshaClientConstants.DUMMY_MESSAGE, Sandesha2Constants.VALUE_FALSE);
      options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
    }
   
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaClient::createSequence");
  }

  /**
   * If a user has requested to create a new sequence which was previously terminated, we need to clean up
   * any previous properties that might have been stored.
   * @param to
   * @param sequenceKey
   * @throws SandeshaStorageException
   */
  private static final void cleanupTerminatedSequence(String to, String sequenceKey, StorageManager storageManager) throws SandeshaException {
    String internalSequenceId = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
   
    if (log.isTraceEnabled())
      log.trace("Checking if sequence " + internalSequenceId + " previously terminated");
   
    Transaction tran = null;
   
    try {
      tran = storageManager.getTransaction();
     
      RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
      //see if the sequence is terminated
      boolean terminatedSequence = false;
      if (rmsBean != null && rmsBean.isTerminated())
        terminatedSequence = true;
 
      //see if the sequence is timed out
      if(rmsBean != null && rmsBean.isTimedOut()){
        terminatedSequence = true;
      }
 
      if (terminatedSequence) {   
        // Delete the rmsBean
        storageManager.getRMSBeanMgr().delete(rmsBean.getCreateSeqMsgID());
      }
     
      if(tran != null && tran.isActive()) tran.commit();
      tran = null;
   
    } finally {
      if(tran!=null && tran.isActive())
        tran.rollback();
    }
  }
 
  /**
   * Clients can use this to create a sequence sequence.
   *
   * @param serviceClient - A configured ServiceClient to be used to invoke RM messages. This need to have Sandesha2 engaged.
   * @param offer - Weather a sequence should be offered for obtaining response messages.
   * @return The sequenceKey of the newly generated sequence.
   * @throws SandeshaException
   */
  public static String createSequence(ServiceClient serviceClient, boolean offer)
      throws SandeshaException {

    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));
   
    String newSequenceKey = SandeshaUtil.getUUID();
    createSequence(serviceClient, offer, newSequenceKey);
   
    return newSequenceKey;
  }
 
  /**
   * User can terminate the sequence defined by the passed serviceClient.
   *
   * @deprecated
   */
  public static void createSequnce(ServiceClient serviceClient, boolean offer, String sequenceKey)
    throws SandeshaException {
    createSequence(serviceClient,offer,sequenceKey);
  }

  /**
   * User can terminate the sequence defined by the passed serviceClient.
   *
   * @param serviceClient
   * @throws SandeshaException
   */
  public static void terminateSequence(ServiceClient serviceClient) throws SandeshaException {
   
    setUpServiceClientAnonymousOperations (serviceClient);
   
    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);

    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);

    String oldAction = options.getAction();

    //in WSRM 1.0 we are adding another application msg with the LastMessage tag, instead of sending a terminate here.
    //Actual terminate will be sent once all the messages upto this get acked
   
    try {
      if (Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(rmSpecVersion)) {
        SOAPEnvelope terminateEnvelope = configureTerminateSequence(options, serviceContext
            .getConfigurationContext());
        OMElement terminateBody = terminateEnvelope.getBody().getFirstChildWithName(
            new QName(rmNamespaceValue,
                Sandesha2Constants.WSRM_COMMON.TERMINATE_SEQUENCE));

        // To inform the Sandesha2 out handler. The response to this call needs
        // be routed to the Sandesha Message receiver
        AxisCallback callback = new AxisCallback() {

          public void onMessage(MessageContext msg) {
            try {
              RMMessageReceiver rm = new RMMessageReceiver();
              rm.receive(msg);
            } catch(Exception e) {
              if(log.isErrorEnabled()) log.error("Exception on callback", e);
            }
          }

          public void onFault(MessageContext msg) {
            try {
              RMMessageReceiver rm = new RMMessageReceiver();
              rm.receive(msg);
            } catch(Exception e) {
              if(log.isErrorEnabled()) log.error("Exception on callback", e);
            }
          }

          public void onError(Exception e) {
            if(log.isErrorEnabled()) log.error("Exception on callback", e);
          }

          public void onComplete() {
            // Nothing to do here
          }
         
        };
        serviceClient.sendReceiveNonBlocking(terminateBody, callback);

      } else {
        options.setAction(Sandesha2Constants.SPEC_2005_02.Actions.ACTION_LAST_MESSAGE);
        options.setProperty(SandeshaClientConstants.LAST_MESSAGE, Constants.VALUE_TRUE);
        serviceClient.fireAndForget(null);
      }
     
    } catch (AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.couldNotSendTerminate,
          e.toString());
      throw new SandeshaException(message, e);
    } finally {
      options.setAction(oldAction);
    }
  }

  public static void terminateSequence(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
    terminateSequence(serviceClient);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
  }

  /**
   * User can close the sequence defined by the passed serviceClient.
   *
   * @param serviceClient
   * @throws SandeshaException
   */
  public static void closeSequence(ServiceClient serviceClient) throws SandeshaException {
   
    setUpServiceClientAnonymousOperations (serviceClient);
   
    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);

    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);

    SOAPEnvelope closeSequnceEnvelope = configureCloseSequence(options, serviceContext.getConfigurationContext());
    OMElement closeSequenceBody = closeSequnceEnvelope.getBody().getFirstChildWithName(
        new QName(rmNamespaceValue, Sandesha2Constants.WSRM_COMMON.CLOSE_SEQUENCE));

    String oldAction = options.getAction();
    options.setAction(SpecSpecificConstants.getCloseSequenceAction(rmSpecVersion));
    try {
      //to inform the sandesha2 out handler
      serviceClient.fireAndForget (closeSequenceBody);
    } catch (AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.couldNotSendClose,
          e.toString());
      throw new SandeshaException(message, e);
    } finally {
      options.setAction(oldAction);
    }
  }

  public static void closeSequence(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {

    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    String specVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
    if (!Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(specVersion)) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.closeSequenceSpecLevel,
          specVersion);
      throw new SandeshaException (message);
    }
   
    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
    closeSequence(serviceClient);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
  }

  /**
   * This blocks the system until the messages u have sent hv been completed.
   *
   * @param serviceClient
   */
  public static void waitUntilSequenceCompleted(ServiceClient serviceClient) throws SandeshaException {
    waitUntilSequenceCompleted(serviceClient, -1);
  }

  public static void waitUntilSequenceCompleted(ServiceClient serviceClient, String sequenceKey)
      throws SandeshaException {
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
    waitUntilSequenceCompleted(serviceClient);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
  }

  /**
   * This blocks the system until the messages u have sent hv been completed
   * or until the given time interval exceeds. (the time is taken in seconds)
   *
   * @param serviceClient
   * @param maxWaitingTime
   */
  public static void waitUntilSequenceCompleted(ServiceClient serviceClient, long maxWaitingTime)
      throws SandeshaException {

    long startTime = System.currentTimeMillis();

    SequenceReport sequenceReport = getOutgoingSequenceReport(serviceClient);
    if (sequenceReport == null) {
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotFindReportForGivenData,
          serviceClient.toString()));
    }

    boolean done = false;
    while (!done) {
      sequenceReport = getOutgoingSequenceReport(serviceClient);
      int status = sequenceReport.getSequenceStatus();
      if (status == SequenceReport.SEQUENCE_STATUS_TERMINATED)
        done = true;
      if (status == SequenceReport.SEQUENCE_STATUS_TIMED_OUT)
        done = true;

      if (!done) {
        long timeNow = System.currentTimeMillis();
        if ((timeNow > (startTime + maxWaitingTime)) && maxWaitingTime != -1)
          done = true;
        else
        {
          // Wait for half a second to stop 100 CPU
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            // Ignore the exception
          }
        }
      }
    }
  }

  public static void waitUntilSequenceCompleted(ServiceClient serviceClient, long maxWaitingTime, String sequenceKey)
      throws SandeshaException {
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
    waitUntilSequenceCompleted(serviceClient, maxWaitingTime);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
  }

  // gives the out sequenceID if CS/CSR exchange is done. Otherwise a
  // SandeshaException
  public static String getSequenceID(ServiceClient serviceClient) throws SandeshaException {

    String internalSequenceID = getInternalSequenceIdFromServiceClient(serviceClient);

    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configurationContext = serviceContext.getConfigurationContext();

    SequenceReport sequenceReport = SandeshaClient.getOutgoingSequenceReport(serviceClient);
    if (sequenceReport == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotFindReportForGivenData, serviceClient.toString()));

    if (sequenceReport.getSequenceStatus() != SequenceReport.SEQUENCE_STATUS_ESTABLISHED) {
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.noSequenceEstablished,
          internalSequenceID));
    }

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());

    // Get a transaction to retrieve the properties
    Transaction transaction = null;
    String sequenceID = null;
   
    try
    {
      transaction = storageManager.getTransaction();
      sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);   
    }
    finally
    {
      // Commit the transaction as it was only a retrieve
      if(transaction != null) transaction.commit();
    }
   
    if (sequenceID == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.sequenceIdBeanNotSet));

    return sequenceID;
  }
 
  private static SOAPEnvelope configureAckRequest(Options options, ConfigurationContext configurationContext)
 
  throws SandeshaException, MissingResourceException {
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    EndpointReference epr = options.getTo();
    if (epr == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    //first see if the cliet has told us which sequence to terminate
    String internalSequenceID =
      (String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
   
    if(internalSequenceID==null){
      //lookup the internal seq id based on to EPR and sequenceKey
      String to = epr.getAddress();
      String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
      internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
    }
   
    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());

    // Get a transaction to obtain sequence information
    Transaction transaction = null;
    String sequenceID = null;
   
    try
    {
      transaction = storageManager.getTransaction();
      sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
    }
    finally
    {
      // Commit the tran whatever happened
      if(transaction != null) transaction.commit();
    }
   
    if (sequenceID == null)
      sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID; 
   
    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    options.setAction(SpecSpecificConstants.getAckRequestAction(rmSpecVersion));
   
    String soapNamespaceURI = options.getSoapVersionURI();
    if (soapNamespaceURI == null)
      soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);
   
    SOAPFactory factory = null;
    SOAPEnvelope dummyEnvelope = null;
    if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
      factory = new SOAP12Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    } else {
      factory = new SOAP11Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    }

    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);

    AckRequested ackRequested = new AckRequested(rmNamespaceValue);
    Identifier identifier = new Identifier(rmNamespaceValue);
    identifier.setIndentifer(sequenceID);
    ackRequested.setIdentifier(identifier);

    ackRequested.toSOAPEnvelope(dummyEnvelope);

    return dummyEnvelope;
  }

  public static void sendAckRequest(ServiceClient serviceClient) throws SandeshaException {

    setUpServiceClientAnonymousOperations (serviceClient);
   
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configContext = serviceContext.getConfigurationContext();

    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
    if (rmSpecVersion == null)
      rmSpecVersion = Sandesha2Constants.SPEC_VERSIONS.v1_0;

    if (Sandesha2Constants.SPEC_VERSIONS.v1_0.equals(rmSpecVersion)) {
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.emptyAckRequestSpecLevel, rmSpecVersion));
    }
   
    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);

    SOAPEnvelope dummyEnvelope = configureAckRequest(options, configContext);
   
    OMElement ackRequestedHeaderBlock = dummyEnvelope.getHeader().getFirstChildWithName(
        new QName(rmNamespaceValue, Sandesha2Constants.WSRM_COMMON.ACK_REQUESTED));

    String oldAction = options.getAction();

    serviceClient.addHeader(ackRequestedHeaderBlock);

    try {
      //to inform the sandesha2 out handler
      serviceClient.sendReceiveNonBlocking (null,new AxisCallback () {

        public void onComplete() {}
        public void onError(Exception e) {}
        public void onFault(MessageContext msgContext) {}
        public void onMessage(MessageContext msgContext) {}
           
      });
    } catch (AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotSendAckRequestException, e.toString());
      throw new SandeshaException(message, e);
    }

    serviceClient.removeHeaders();
    options.setAction(oldAction);
  }

  public static void sendAckRequest(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
    sendAckRequest(serviceClient);

    options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
  }

  /**
   * Forces any inbound messages currently on the specified inOrder inbound sequence to be dispatched out of order.
   * @param configContext
   * @param sequenceID
   * @param allowLaterDeliveryOfMissingMessages if true, messages skipped over during this
   * action will be invoked if they arrive on the system at a later time.
   * Otherwise messages skipped over will be ignored
   * @throws SandeshaException
   */
  public static void forceDispatchOfInboundMessages(ConfigurationContext configContext,
      String sequenceID,
      boolean allowLaterDeliveryOfMissingMessages)throws SandeshaException{

    Transaction reportTransaction = null;

    try {
      StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configContext, configContext.getAxisConfiguration());
      reportTransaction = storageManager.getTransaction();

      //only do this if we are running inOrder
      if(SandeshaUtil.getPropertyBean(configContext.getAxisConfiguration()).isInOrder()){
        Invoker invoker = (Invoker)SandeshaUtil.getSandeshaStorageManager(configContext, configContext.getAxisConfiguration()).getInvoker();
        if (invoker==null){
          throw new SandeshaException(SandeshaMessageHelper.getMessage(
            SandeshaMessageKeys.invokerNotFound, sequenceID));
        }
       
        invoker.forceInvokeOfAllMessagesCurrentlyOnSequence(configContext, sequenceID, allowLaterDeliveryOfMissingMessages);     
      }
     
      if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
      reportTransaction = null;

    } catch (Exception e) {
      // Just log the exception
      if(log.isDebugEnabled()) log.debug("Exception", e);
    } finally {
      if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.rollback();
    }
  }

  private static SOAPEnvelope configureCloseSequence(Options options, ConfigurationContext configurationContext)
      throws SandeshaException {

    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    EndpointReference epr = options.getTo();
    if (epr == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    //first see if the cliet has told us which sequence to close
    String internalSequenceID =
      (String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
   
    if(internalSequenceID==null){
      //lookup the internal seq id based on to EPR and sequenceKey
      String to = epr.getAddress();
      String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
      internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
    }

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
   
    // Get a transaction for getting the sequence properties
    Transaction transaction = null;
    String sequenceID = null;
   
    try
    {
      transaction = storageManager.getTransaction();
      sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
    }
    finally
    {
      // Commit the tran whatever happened
      if(transaction != null) transaction.commit();
    }
   
    if (sequenceID == null)
      sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID; 

    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);

    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    if (!SpecSpecificConstants.isSequenceClosingAllowed(rmSpecVersion))
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.closeSequenceSpecLevel, rmSpecVersion));

    SOAPEnvelope dummyEnvelope = null;
    SOAPFactory factory = null;
    String soapNamespaceURI = options.getSoapVersionURI();
    if (soapNamespaceURI == null)
      soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);

    if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
      factory = new SOAP12Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    } else {
      factory = new SOAP11Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    }

    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);

    CloseSequence closeSequence = new CloseSequence(rmNamespaceValue);
    Identifier identifier = new Identifier(rmNamespaceValue);
    identifier.setIndentifer(sequenceID);
    closeSequence.setIdentifier(identifier);

    closeSequence.toSOAPEnvelope(dummyEnvelope);

    return dummyEnvelope;
  }

  private static byte getServerSequenceStatus(String sequenceID, StorageManager storageManager)
      throws SandeshaException {

    RMDBean rmdBean = SandeshaUtil.getRMDBeanFromSequenceId(storageManager, sequenceID);
    if (rmdBean != null && rmdBean.isTerminated()) {
      return SequenceReport.SEQUENCE_STATUS_TERMINATED;
    }

/*  Only outbound sequences time out 
    SequencePropertyBean timedOutBean = seqPropMgr.retrieve(sequenceID,
        Sandesha2Constants.SequenceProperties.SEQUENCE_TIMED_OUT);
    if (timedOutBean != null) {
      return SequenceReport.SEQUENCE_STATUS_TIMED_OUT;
    }
*/
    if (rmdBean != null) {
      return SequenceReport.SEQUENCE_STATUS_ESTABLISHED;
    }

    throw new SandeshaException(SandeshaMessageHelper.getMessage(
        SandeshaMessageKeys.cannotFindSequence, sequenceID
        ));
  }

  public static SequenceReport getIncomingSequenceReport(String sequenceID, ConfigurationContext configCtx)
      throws SandeshaException {

    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configCtx,configCtx.getAxisConfiguration());

    Transaction reportTransaction = null;

    try {
      reportTransaction = storageManager.getTransaction();

      SequenceReport sequenceReport = new SequenceReport();

      RMDBean rmdBean = SandeshaUtil.getRMDBeanFromSequenceId(storageManager, sequenceID);

      List completedMessageList = rmdBean.getServerCompletedMessages().getContainedElementsAsNumbersList();
     
      Iterator iter = completedMessageList.iterator();
      while (iter.hasNext()) {
        sequenceReport.addCompletedMessage((Long) iter.next());
      }

      sequenceReport.setSequenceID(sequenceID);
      sequenceReport.setInternalSequenceID(sequenceID); // for the
                                // incoming side
                                // internalSequenceID=sequenceID
      sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_IN);

      sequenceReport.setSequenceStatus(getServerSequenceStatus(sequenceID, storageManager));

      if(rmdBean.getSecurityTokenData() != null) sequenceReport.setSecureSequence(true);
     
      if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.commit();
      reportTransaction = null;

      return sequenceReport;

    } catch (Exception e) {
      // Just log the exception
      if(log.isDebugEnabled()) log.debug("Exception", e);
    } finally {
      if(reportTransaction != null && reportTransaction.isActive()) {
        reportTransaction.rollback();
      }
    }

    return null;
  }

  private static SOAPEnvelope configureTerminateSequence(Options options, ConfigurationContext configurationContext)
      throws SandeshaException {

    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    EndpointReference epr = options.getTo();
    if (epr == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    //first see if the cliet has told us which sequence to terminate
    String internalSequenceID =
      (String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
   
    if(internalSequenceID==null){
      //lookup the internal seq id based on to EPR and sequenceKey
      String to = epr.getAddress();
      String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
      internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
    }
   
    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());

    // Get a transaction to obtain sequence information
    Transaction transaction = null;
    String sequenceID = null;
   
    try
    {
      transaction = storageManager.getTransaction();
      sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
    }
    finally
    {
      // Commit the tran whatever happened
      if(transaction != null) transaction.commit();
    }
   
    if (sequenceID == null)
      sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID; 
   
    String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
    if (rmSpecVersion == null)
      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();

    options.setAction(SpecSpecificConstants.getTerminateSequenceAction(rmSpecVersion));
    SOAPEnvelope dummyEnvelope = null;
    SOAPFactory factory = null;
    String soapNamespaceURI = options.getSoapVersionURI();
    if (soapNamespaceURI == null)
      soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);
    if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
      factory = new SOAP12Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    } else {
      factory = new SOAP11Factory();
      dummyEnvelope = factory.getDefaultEnvelope();
    }

    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
    TerminateSequence terminateSequence = new TerminateSequence(rmNamespaceValue);
    Identifier identifier = new Identifier(rmNamespaceValue);
    identifier.setIndentifer(sequenceID);
    terminateSequence.setIdentifier(identifier);
    terminateSequence.toSOAPEnvelope(dummyEnvelope);

    return dummyEnvelope;
  }
 
 
//  private static SOAPEnvelope configureCreateSequence(Options options,
//      ConfigurationContext configurationContext) throws AxisFault {
//
//    if (options == null)
//      throw new SandeshaException(SandeshaMessageHelper
//          .getMessage(SandeshaMessageKeys.optionsObjectNotSet));
//
//    EndpointReference epr = options.getTo();
//    if (epr == null)
//      throw new SandeshaException(SandeshaMessageHelper.getMessage(
//          SandeshaMessageKeys.toEPRNotValid, null));
//
//
//    String rmSpecVersion = (String) options
//        .getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
//    if (rmSpecVersion == null)
//      rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
//
//    options.setAction(SpecSpecificConstants
//        .getCreateSequenceAction (rmSpecVersion));
//
//    SOAPEnvelope dummyEnvelope = null;
//    SOAPFactory factory = null;
//    String soapNamespaceURI = options.getSoapVersionURI();
//    if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI
//        .equals(soapNamespaceURI)) {
//      factory = new SOAP12Factory();
//      dummyEnvelope = factory.getDefaultEnvelope();
//    } else {
//      factory = new SOAP11Factory();
//      dummyEnvelope = factory.getDefaultEnvelope();
//    }
//
//    String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
//
//    String addressingNamespaceValue = (String) options.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
//    if (addressingNamespaceValue==null)
//      addressingNamespaceValue = SpecSpecificConstants.getDefaultAddressingNamespace ();
//   
//
//    CreateSequence createSequence = new CreateSequence (rmNamespaceValue,addressingNamespaceValue);
//    AcksTo acksTo = new AcksTo (rmNamespaceValue,addressingNamespaceValue);
//    createSequence.setAcksTo(acksTo);
//    EndpointReference endpointReference = new EndpointReference (null);
//    acksTo.setAddress(endpointReference);
//   
//    createSequence.toSOAPEnvelope(dummyEnvelope);
//
//    return dummyEnvelope;
//  }
 
 
  /**
   * Sandesha uses default 'fireAndForget' and 'sendReceive' methods to send control messages.
   * But these can only be called when Anonymous operations are present within the passed ServiceClient.
   * But these could be situations where these Anonymous operations are not present. In such cases Sandesha2
   * will try to add them into the serviceClient.
   */
  private static void setUpServiceClientAnonymousOperations (ServiceClient serviceClient) throws SandeshaException {
    try {
     
      AxisService service = serviceClient.getAxisService();

      AxisOperation anonOutOnlyOperation = service.getOperation(ServiceClient.ANON_OUT_ONLY_OP);
     
      if (anonOutOnlyOperation==null) {
        anonOutOnlyOperation = AxisOperationFactory.getAxisOperation(WSDLConstants.MEP_CONSTANT_OUT_ONLY);
        anonOutOnlyOperation.setName(ServiceClient.ANON_OUT_ONLY_OP);
       
        AxisOperation referenceOperation = service.getOperation(Sandesha2Constants.RM_IN_ONLY_OPERATION);
       
        if (referenceOperation!=null) {
          anonOutOnlyOperation.setPhasesOutFlow(referenceOperation.getPhasesOutFlow());
          anonOutOnlyOperation.setPhasesOutFaultFlow(referenceOperation.getPhasesOutFaultFlow());
          anonOutOnlyOperation.setPhasesInFaultFlow(referenceOperation.getPhasesInFaultFlow());
          anonOutOnlyOperation.setPhasesInFaultFlow(referenceOperation.getRemainingPhasesInFlow());

          service.addOperation(anonOutOnlyOperation);
        } else {
          String message = "Cant find RM Operations. Please engage the Sandesha2 module before doing the invocation.";
          throw new SandeshaException (message);
        }
      }

      AxisOperation anonOutInOperation = service.getOperation(ServiceClient.ANON_OUT_IN_OP);
     
      if (anonOutInOperation==null) {
        anonOutInOperation = AxisOperationFactory.getAxisOperation(WSDLConstants.MEP_CONSTANT_OUT_IN);
        anonOutInOperation.setName(ServiceClient.ANON_OUT_IN_OP);
       
        AxisOperation referenceOperation = service.getOperation(Sandesha2Constants.RM_IN_OUT_OPERATION);
       
        if (referenceOperation!=null) {
          anonOutInOperation.setPhasesOutFlow(referenceOperation.getPhasesOutFlow());
          anonOutInOperation.setPhasesOutFaultFlow(referenceOperation.getPhasesOutFaultFlow());
          anonOutInOperation.setPhasesInFaultFlow(referenceOperation.getPhasesInFaultFlow());
          anonOutInOperation.setPhasesInFaultFlow(referenceOperation.getRemainingPhasesInFlow());
         
          //operation will be added to the service only if a valid referenceOperation was found.
          service.addOperation(anonOutInOperation);
        }
      }
    } catch (AxisFault e) {
      throw new SandeshaException (e);
    }
  }

  /**
   * Gets the last error that occured on a send to an endpoint.
   *
   * The method will return null if no exception has been encountered.
   * Errors may be transient and maybe out of date.  To check the validity of the
   * error, check the timestamp from which the error was encountered
   * @see getLastSendTimestamp .
   *
   * @param serviceClient
   * @return
   * @throws SandeshaException
   */
  public static Exception getLastSendError(ServiceClient serviceClient)
 
  throws SandeshaException
  {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaClient::getLastSendError");

    // Get the internal sequence id for this client
    String internalSequenceId = getInternalSequenceIdFromServiceClient(serviceClient);
   
    if (log.isTraceEnabled())
      log.trace("Looking up sequence with identifier " + internalSequenceId);
   
    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configurationContext = serviceContext.getConfigurationContext();

    // Get the in use storage manager and the sequence property bean manager
    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
   
    Transaction transaction = null;
    Exception resultException = null;
   
    try
    {
      transaction = storageManager.getTransaction();
      RMSBean bean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
     
      if (bean != null) {           
        resultException = bean.getLastSendError();
      }
    }
    finally
    {
      // Commit the tran whatever happened
      if(transaction != null) transaction.commit();
    }
   
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaClient::getLastSendError, " + resultException);
   
    return resultException;
  }
 
  /**
   * Gets the timestamp from which the last error that occured on a send to an endpoint.
   *
   * The method will return -1 if no errors have been encountered.
   *
   * @param serviceClient
   * @return
   * @throws SandeshaException
   */
  public static long getLastSendErrorTimestamp(ServiceClient serviceClient)
 
  throws SandeshaException
  {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaClient::getLastSendErrorTimestamp");

    // Get the internal sequence id for this client
    String internalSequenceId = getInternalSequenceIdFromServiceClient(serviceClient);
   
    if (log.isTraceEnabled())
      log.trace("Looking up sequence with identifier " + internalSequenceId);
   
    ServiceContext serviceContext = serviceClient.getServiceContext();
    if (serviceContext == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.serviceContextNotSet));

    ConfigurationContext configurationContext = serviceContext.getConfigurationContext();

    // Get the in use storage manager and the sequence property bean manager
    StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
   
    // Create a transaction for the retrieve operation
    Transaction transaction = null;
    long resultTime = -1;

    try
    {
      transaction = storageManager.getTransaction();
     
      RMSBean bean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
     
      if (bean != null) {           
        resultTime = bean.getLastSendErrorTimestamp();
      }
    }
    finally
    {
      // commit the transaction as it was only a retrieve
      if(transaction != null) transaction.commit();
    }
   
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaClient::getLastSendErrorTimestamp, " + resultTime);
   
    return resultTime;

  }

  /**
   * Gets the internal sequence id from the service client instance.
   *
   * @param serviceClient
   * @return
   * @throws SandeshaException
   */
  private static String getInternalSequenceIdFromServiceClient(ServiceClient serviceClient) throws SandeshaException
  {
    Options options = serviceClient.getOptions();
    if (options == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.optionsObjectNotSet));

    EndpointReference toEPR = options.getTo();
    if (toEPR == null)
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.toEPRNotValid, null));

    String to = toEPR.getAddress();
    String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);

    String internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);

    return internalSequenceID;
  }

  private static final String getSOAPNamespaceURI(StorageManager storageManager, String internalSequenceID) throws SandeshaException {
    String soapNamespaceURI = null;
   
    // Get the RMSBean for this sequence.
    Transaction transaction = null;
   
    try {
      transaction = storageManager.getTransaction();
      RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceID);
      if (rmsBean.getSoapVersion() == Sandesha2Constants.SOAPVersion.v1_2)
        soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
    } finally {
      if(transaction != null) transaction.commit();
    }
   
    return soapNamespaceURI;
  }
 
  public static void setPolicyBean (ServiceClient serviceClient, SandeshaPolicyBean policyBean) throws SandeshaException {
    try {
      AxisService axisService = serviceClient.getAxisService();
      if (axisService!=null) {
        Parameter parameter = axisService.getParameter(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
        SandeshaPolicyBean parent = null;
        if (parameter==null) {
          parameter = new Parameter ();
          parameter.setName(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
        } else {
          parameter.setEditable(true); //if we don't do it here, Axis2 will not allow us to override the parameter value.
          parent = (SandeshaPolicyBean) parameter.getValue();
          policyBean.setParent(parent);
        }
       
        parameter.setValue(policyBean);
        axisService.addParameter(parameter);
      } else {
        String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotSetPolicyBeanServiceNull);
        throw new SandeshaException (message);
      }
    } catch (AxisFault e) {
      throw new SandeshaException (e);
    }
  }
 
}
TOP

Related Classes of org.apache.sandesha2.client.SandeshaClient

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.