You are viewing a plain text version of this content. The canonical link for it is here.
Posted to sandesha-dev@ws.apache.org by ch...@apache.org on 2007/04/23 11:55:16 UTC

svn commit: r531400 [2/18] - in /webservices/sandesha/trunk/java/modules: client/ core/ core/src/ core/src/main/ core/src/main/java/ core/src/main/java/org/ core/src/main/java/org/apache/ core/src/main/java/org/apache/sandesha2/ core/src/main/java/org/...

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClient.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClient.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClient.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClient.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,1407 @@
+/*
+ * 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.context.ConfigurationContext;
+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.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);
+
+		} catch (Exception e) {
+			if (reportTransaction!=null) {
+				reportTransaction.rollback();
+				reportTransaction = null;
+			}
+		} finally {
+			if (reportTransaction!=null) reportTransaction.commit();
+		}
+
+		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 ArrayList getIncomingSequenceReports(ConfigurationContext configCtx) throws SandeshaException {
+
+		SandeshaReport report = getSandeshaReport(configCtx);
+		ArrayList 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());
+			}
+
+		} catch (Exception e) {
+			if (reportTransaction!=null) {
+				reportTransaction.rollback();
+				reportTransaction = null;
+			}
+		} finally {
+			if (reportTransaction!=null) reportTransaction.commit();
+		}
+
+		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 = storageManager.getTransaction();
+		
+		try {
+			
+			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());
+			}
+		
+		} catch (SandeshaException e) {
+			if(tran!=null)
+				tran.rollback();
+			tran = null;
+			
+			throw e;
+		} 
+		if(tran!=null)
+			tran.commit();
+	}
+	
+	/**
+	 * 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.
+				serviceClient.fireAndForget(terminateBody);
+
+			} 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 = storageManager.getTransaction();
+		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.fireAndForget (null);
+		} 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);			
+			}
+			
+		} catch (Exception e) {
+			if (reportTransaction!=null) {
+				reportTransaction.rollback();
+				reportTransaction = null;
+			}
+		} finally {
+			if(reportTransaction != null) reportTransaction.commit();
+		}
+	}
+
+	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);
+			
+			return sequenceReport;
+
+		} catch (Exception e) {
+			if (reportTransaction!=null) {
+				reportTransaction.rollback();
+				reportTransaction = null;
+			}
+		} finally {
+			if (reportTransaction!=null) reportTransaction.commit();
+		}
+
+		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 = storageManager.getTransaction();
+		
+		try {				
+			RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceID);
+			if (rmsBean.getSoapVersion() == Sandesha2Constants.SOAPVersion.v1_2)
+				soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
+		} finally {
+			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 {
+					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);
+		}
+	}
+	
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClientConstants.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClientConstants.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClientConstants.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaClientConstants.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * Constants that are needed for the Sandesha2 Client API.
+ */
+public class SandeshaClientConstants {
+	public static String AcksTo = "Sandesha2AcksTo";
+	public static String LAST_MESSAGE = "Sandesha2LastMessage";
+	public static String OFFERED_SEQUENCE_ID = "Sandesha2OfferedSequenceId";
+	public static String INTERNAL_SEQUENCE_ID = "Sandesha2InternalSequenceId";
+	public static String SANDESHA_DEBUG_MODE = "Sandesha2DebugMode";
+	public static String SEQUENCE_KEY = "Sandesha2SequenceKey";
+	public static String MESSAGE_NUMBER = "Sandesha2MessageNumber";
+	public static String RM_SPEC_VERSION = "Sandesha2RMSpecVersion";
+	public static String DUMMY_MESSAGE = "Sandesha2DummyMessage"; //If this property is set, even though this message will invoke the RM handlers, this will not be sent as an actual application message
+	public static String UNRELIABLE_MESSAGE = "Sandesha2UnreliableMessage";
+	public static String SANDESHA_LISTENER = "Sandesha2Listener";
+	public static String USE_REPLY_TO_AS_ACKS_TO = "UseReplyToAsAcksTo";
+	public static String OFFERED_ENDPOINT = "OfferedEndpoint";
+	public static String AVOID_AUTO_TERMINATION = "AviodAutoTermination";
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaListener.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaListener.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaListener.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaListener.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,41 @@
+/*
+ * 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.client;
+
+import org.apache.axis2.AxisFault;
+
+/**
+ * By implementing this interface and registering an object with
+ * Sandesha2, users will be invoked in some events.
+ */
+
+public interface SandeshaListener {
+
+	/**
+	 * This sill be invoked when Sandesha2 receive a fault message
+	 * in response to a RM control message that was sent by it.
+	 */
+	public void onError(AxisFault fault);
+	
+	/**
+	 * This will be invoked when a specific sequence time out.
+	 * The timing out method depends on policies.
+	 */
+	public void onTimeOut(SequenceReport report);
+	
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaReport.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaReport.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaReport.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SandeshaReport.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,92 @@
+/*
+ * 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.HashMap;
+
+
+
+/**
+ * This gives a report explaining the current state of the Sandesha2 
+ * system.
+ */
+public class SandeshaReport {
+	
+	private ArrayList incomingSequenceList = null;
+	private ArrayList outgoingSequenceList = null;
+	private HashMap sequenceStatusMap = null;
+	private HashMap noOfCompletedMessagesMap = null;
+	private HashMap outgoingInternalSequenceIDMap = null;
+	
+	public SandeshaReport () {
+		incomingSequenceList = new ArrayList ();
+		outgoingSequenceList = new ArrayList ();
+		sequenceStatusMap = new HashMap ();
+		noOfCompletedMessagesMap = new HashMap ();
+		outgoingInternalSequenceIDMap = new HashMap ();
+	}
+
+	public long getCompletedMessagesCount(String sequenceID) {
+		Long lng = (Long) noOfCompletedMessagesMap.get(sequenceID);
+		if (lng==null)
+			return -1;
+		
+		return lng.longValue();
+	}
+
+	public ArrayList getIncomingSequenceList() {
+		return incomingSequenceList;
+	}
+
+	public ArrayList getOutgoingSequenceList() {
+		return outgoingSequenceList;
+	}
+
+	public byte getSequenceStatusMap(String sequenceID) {
+		Byte status = (Byte) sequenceStatusMap.get(sequenceID);
+		if (status==null)
+			return SequenceReport.SEQUENCE_STATUS_UNKNOWN;
+		
+		return status.byteValue();
+	}
+
+	public void addToIncomingSequenceList (String incomingSequenceID) {
+		incomingSequenceList.add(incomingSequenceID);
+	}
+	
+	public void addToOutgoingSequenceList (String outSequenceID) {
+		outgoingSequenceList.add(outSequenceID);
+	}
+	
+	public void addToNoOfCompletedMessagesMap (String id, long noOfMsgs) {
+		noOfCompletedMessagesMap.put(id, new Long (noOfMsgs));
+	}
+	
+	public void addToSequenceStatusMap (String id, byte status) {
+		sequenceStatusMap.put(id, new Byte (status));
+	}
+	
+	public String getInternalSequenceIdOfOutSequence (String outSequenceID) {
+		return (String) outgoingInternalSequenceIDMap.get(outSequenceID);
+	}
+	
+	public void addToOutgoingInternalSequenceMap (String outSequenceID, String internalSequenceID) {
+		outgoingInternalSequenceIDMap.put(outSequenceID,internalSequenceID);
+	}
+	
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SequenceReport.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SequenceReport.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SequenceReport.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/client/SequenceReport.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+/**
+ *This report will contain details of a specific sequence.
+ */
+
+public class SequenceReport {
+
+	public static final byte SEQUENCE_STATUS_UNKNOWN = 0;
+	public static final byte SEQUENCE_STATUS_INITIAL = 1;
+	public static final byte SEQUENCE_STATUS_ESTABLISHED = 2;
+	public static final byte SEQUENCE_STATUS_TERMINATED = 3;
+	public static final byte SEQUENCE_STATUS_TIMED_OUT = 4;
+	private static final byte MAX_SEQUENCE_STATUS = 4;
+	
+	public static final byte SEQUENCE_DIRECTION_UNKNOWN=0;
+	public static final byte SEQUENCE_DIRECTION_IN=1;
+	public static final byte SEQUENCE_DIRECTION_OUT=2;
+	private static final byte MAX_SEQUENCE_DIRECTION = 2;
+	
+	private byte sequenceStatus = SEQUENCE_STATUS_UNKNOWN;
+	private byte sequenceDirection = SEQUENCE_DIRECTION_UNKNOWN;
+	private String sequenceID = null;
+	private String internalSequenceID = null;   //only for outgoing sequences
+	private ArrayList completedMessages = null; //no of messages acked (both for incoming and outgoing)
+	private boolean secureSequence = false;
+	
+	public SequenceReport () {
+		completedMessages = new ArrayList ();
+	}
+	
+	public void setSequenceStatus (byte sequenceStatus) {
+		if (sequenceStatus>=SEQUENCE_STATUS_UNKNOWN && sequenceStatus<=MAX_SEQUENCE_STATUS) {
+			this.sequenceStatus = sequenceStatus;
+		}
+	}
+	
+	public void setSequenceDirection (byte sequenceDirection) {
+		if (sequenceDirection>=SEQUENCE_DIRECTION_UNKNOWN && sequenceDirection<=MAX_SEQUENCE_DIRECTION) {
+			this.sequenceDirection = sequenceDirection;
+		}
+	}
+	
+	public byte getSequenceStatus () {
+		return sequenceStatus;
+	}
+	
+	public byte getSequenceDirection () {
+		return sequenceDirection;
+	}
+
+	public String getSequenceID() {
+		return sequenceID;
+	}
+
+	public void setSequenceID(String sequenceID) {
+		this.sequenceID = sequenceID;
+	}
+	
+	public ArrayList getCompletedMessages () {
+		return completedMessages;
+	}
+
+	public void addCompletedMessage (Long messageNo) {
+		completedMessages.add(messageNo);
+	}
+	
+	public void setCompletedMessages (ArrayList completedMessages) {
+		this.completedMessages = completedMessages;
+	}
+
+	public String getInternalSequenceID() {
+		return internalSequenceID;
+	}
+
+	public void setInternalSequenceID(String internalSequenceID) {
+		this.internalSequenceID = internalSequenceID;
+	}
+
+	public boolean isSecureSequence() {
+		return secureSequence;
+	}
+
+	public void setSecureSequence(boolean secureSequence) {
+		this.secureSequence = secureSequence;
+	}
+	
+	
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaGlobalInHandler.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaGlobalInHandler.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaGlobalInHandler.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaGlobalInHandler.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,226 @@
+/*
+ * 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.handlers;
+
+import javax.xml.namespace.QName;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.soap.SOAPBody;
+import org.apache.axiom.soap.SOAPEnvelope;
+import org.apache.axiom.soap.SOAPHeader;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.handlers.AbstractHandler;
+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.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.util.FaultManager;
+import org.apache.sandesha2.util.MsgInitializer;
+import org.apache.sandesha2.util.Range;
+import org.apache.sandesha2.util.RangeString;
+import org.apache.sandesha2.util.SandeshaUtil;
+import org.apache.sandesha2.util.SpecSpecificConstants;
+import org.apache.sandesha2.wsrm.Sequence;
+
+/**
+ * The Global handler of Sandesha2. This is only used to check for WSRM 1.0 messages
+ * that have a particular way of signalling the last message in a sequence. These
+ * checks have to be done before dispatch.
+ */
+
+public class SandeshaGlobalInHandler extends AbstractHandler {
+
+	private static final long serialVersionUID = -7187928423123306156L;
+
+	private static final Log log = LogFactory.getLog(SandeshaGlobalInHandler.class);
+	
+	public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
+
+		if (log.isDebugEnabled())
+			log.debug("Enter: SandeshaGlobalInHandler::invoke, " + msgContext.getEnvelope().getHeader());
+
+		// The only work that this handler needs to do is identify messages which
+		// follow the WSRM 1.0 convention for sending 'LastMessage' when the sender
+		// doesn't have a reliable message to piggyback the last message marker onto.
+		// Normally they will identify this scenario with an action marker, but if
+		// there is no action at all then we have to check the soap body.
+		// Either way, all that this handler need do is set the action back onto
+		// the message, so that the dispatchers can allow it to continue. The real
+		// processing will be done in the SequenceProcessor.
+		String soapAction = msgContext.getSoapAction();
+		String wsaAction = msgContext.getWSAAction();
+		if(soapAction == null && wsaAction == null) {
+			// Look for a WSRM 1.0 sequence header with the lastMessage marker
+			SOAPEnvelope env = msgContext.getEnvelope();
+			if(env != null) {
+				boolean lastMessageHeader = false;
+				try {
+					SOAPHeader header = env.getHeader();
+					if(header != null) {
+						Sequence sequence = new Sequence(Sandesha2Constants.SPEC_2005_02.NS_URI);
+						sequence.fromOMElement(header);
+						if(sequence.getLastMessage() != null) {
+							lastMessageHeader = true;
+						}
+					}
+				} catch(Exception e) {
+					// Do nothing, we failed to find a Sequence header
+				}
+				if(lastMessageHeader) {
+					SOAPBody body = env.getBody();
+					if(body != null && body.getFirstElement() == null) {
+						// There is an empty body so we know this is the kind of message
+						// that we are looking for.
+						if(log.isDebugEnabled()) log.debug("Setting SOAP Action for a WSRM 1.0 last message");
+						msgContext.setSoapAction(Sandesha2Constants.SPEC_2005_02.Actions.SOAP_ACTION_LAST_MESSAGE);
+					}
+				}
+			}
+		}
+    
+    // Check if this is an application message and if it is a duplicate
+    RMMsgContext rmMsgCtx = MsgInitializer.initializeMessage(msgContext);
+
+    // Set the RMMMessageContext as a property on the message so we can retrieve it later
+    msgContext.setProperty(Sandesha2Constants.MessageContextProperties.RM_MESSAGE_CONTEXT, rmMsgCtx);
+
+    
+    StorageManager storageManager = 
+      SandeshaUtil.getSandeshaStorageManager(rmMsgCtx.getConfigurationContext(), 
+          rmMsgCtx.getConfigurationContext().getAxisConfiguration());
+    
+    Transaction transaction = storageManager.getTransaction();
+    try {    	    
+	    //processing any incoming faults.     
+			//This is responsible for Sandesha2 specific 
+			FaultManager.processMessagesForFaults(rmMsgCtx);
+    }
+		finally {
+			transaction.commit();
+		}
+
+    if (rmMsgCtx.getMessageType() == Sandesha2Constants.MessageTypes.APPLICATION) {
+      processApplicationMessage(rmMsgCtx);
+    }
+    
+		if (log.isDebugEnabled())
+			log.debug("Exit: SandeshaGlobalInHandler::invoke " + InvocationResponse.CONTINUE);
+		return InvocationResponse.CONTINUE;
+	}
+	
+  private static void processApplicationMessage(RMMsgContext rmMsgCtx) throws AxisFault {
+    if (log.isDebugEnabled())
+      log.debug("Enter: SandeshaGlobalInHandler::processApplicationMessage");
+    // Check if this is a duplicate message
+    Sequence sequence = (Sequence) rmMsgCtx.getMessagePart(Sandesha2Constants.MessageParts.SEQUENCE);
+    String sequenceId = sequence.getIdentifier().getIdentifier();
+    long msgNo = sequence.getMessageNumber().getMessageNumber();
+
+    StorageManager storageManager = 
+      SandeshaUtil.getSandeshaStorageManager(rmMsgCtx.getConfigurationContext(), 
+          rmMsgCtx.getConfigurationContext().getAxisConfiguration());
+    
+    Transaction transaction = storageManager.getTransaction();
+    
+    try {
+    
+      // Check that both the Sequence header and message body have been secured properly
+      RMDBeanMgr mgr = storageManager.getRMDBeanMgr();
+      RMDBean bean = mgr.retrieve(sequenceId);
+      
+      if(bean != null && bean.getSecurityTokenData() != null) {
+        SecurityManager secManager = SandeshaUtil.getSecurityManager(rmMsgCtx.getConfigurationContext());
+        
+        QName seqName = new QName(rmMsgCtx.getRMNamespaceValue(), Sandesha2Constants.WSRM_COMMON.SEQUENCE);
+        
+        SOAPEnvelope envelope = rmMsgCtx.getSOAPEnvelope();
+        OMElement body = envelope.getBody();
+        OMElement seqHeader = envelope.getHeader().getFirstChildWithName(seqName);
+        
+        SecurityToken token = secManager.recoverSecurityToken(bean.getSecurityTokenData());
+        
+        secManager.checkProofOfPossession(token, seqHeader, rmMsgCtx.getMessageContext());
+        secManager.checkProofOfPossession(token, body, rmMsgCtx.getMessageContext());
+      }
+    
+      if (bean != null) {
+        
+        if (msgNo == 0) {
+          String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.invalidMsgNumber, Long
+              .toString(msgNo));
+          log.debug(message);
+          throw new SandeshaException(message);
+        }
+    
+        // Get the server completed message ranges list
+        RangeString serverCompletedMessageRanges = bean.getServerCompletedMessages();
+    
+        // See if the message is in the list of completed ranges
+        boolean msgNoPresentInList = 
+          serverCompletedMessageRanges.isMessageNumberInRanges(msgNo);
+          
+        if (!msgNoPresentInList) {
+          serverCompletedMessageRanges.addRange(new Range(msgNo));
+          
+          storageManager.getRMDBeanMgr().update(bean);
+        }
+        else {
+          if (log.isDebugEnabled())
+            log.debug("Detected duplicate message " + msgNo);
+          rmMsgCtx.getMessageContext().setRelationships(null);
+          // Add the duplicate RM AxisOperation to the message
+          AxisOperation duplicateMessageOperation = SpecSpecificConstants.getWSRMOperation(
+              Sandesha2Constants.MessageTypes.DUPLICATE_MESSAGE,
+              Sandesha2Constants.SPEC_VERSIONS.v1_0,
+              rmMsgCtx.getMessageContext().getAxisService());
+          rmMsgCtx.getMessageContext().setAxisOperation(duplicateMessageOperation);
+        }
+              
+      } else {
+        if (log.isDebugEnabled())
+          log.debug("Detected message for no sequence " + msgNo);
+        rmMsgCtx.getMessageContext().setRelationships(null);
+        // Add the duplicate RM AxisOperation to the message
+        AxisOperation duplicateMessageOperation = SpecSpecificConstants.getWSRMOperation(
+            Sandesha2Constants.MessageTypes.DUPLICATE_MESSAGE,
+            Sandesha2Constants.SPEC_VERSIONS.v1_0,
+            rmMsgCtx.getMessageContext().getAxisService());
+        rmMsgCtx.getMessageContext().setAxisOperation(duplicateMessageOperation);
+      }
+      transaction.commit();
+      transaction = null;
+    }
+    finally {
+      if (transaction != null)
+        transaction.rollback();
+    }
+    if (log.isDebugEnabled())
+      log.debug("Exit: SandeshaGlobalInHandler::processApplicationMessage");
+  }
+}

Added: webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaInHandler.java
URL: http://svn.apache.org/viewvc/webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaInHandler.java?view=auto&rev=531400
==============================================================================
--- webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaInHandler.java (added)
+++ webservices/sandesha/trunk/java/modules/core/src/main/java/org/apache/sandesha2/handlers/SandeshaInHandler.java Mon Apr 23 02:54:53 2007
@@ -0,0 +1,183 @@
+/*
+ * 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.handlers;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.handlers.AbstractHandler;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.sandesha2.MessageValidator;
+import org.apache.sandesha2.RMMsgContext;
+import org.apache.sandesha2.Sandesha2Constants;
+import org.apache.sandesha2.client.SandeshaClientConstants;
+import org.apache.sandesha2.i18n.SandeshaMessageHelper;
+import org.apache.sandesha2.i18n.SandeshaMessageKeys;
+import org.apache.sandesha2.msgprocessors.AckRequestedProcessor;
+import org.apache.sandesha2.msgprocessors.AcknowledgementProcessor;
+import org.apache.sandesha2.msgprocessors.MessagePendingProcessor;
+import org.apache.sandesha2.msgprocessors.SequenceProcessor;
+import org.apache.sandesha2.storage.StorageManager;
+import org.apache.sandesha2.storage.Transaction;
+import org.apache.sandesha2.util.MsgInitializer;
+import org.apache.sandesha2.util.SandeshaUtil;
+
+/**
+ * This is invoked in the inFlow of an RM endpoint. This is responsible for
+ * selecting an suitable message processor and letting it process the message.
+ */
+
+public class SandeshaInHandler extends AbstractHandler {
+
+	private static final long serialVersionUID = 733210926016820857L;
+
+	private static final Log log = LogFactory.getLog(SandeshaInHandler.class.getName());
+
+	public String getName() {
+		return Sandesha2Constants.IN_HANDLER_NAME;
+	}
+	
+	public InvocationResponse invoke(MessageContext msgCtx) throws AxisFault {
+		
+		if (log.isDebugEnabled())
+			log.debug("Enter: SandeshaInHandler::invoke, " + msgCtx.getEnvelope().getHeader());
+
+		InvocationResponse returnValue = InvocationResponse.CONTINUE;
+		
+		ConfigurationContext context = msgCtx.getConfigurationContext();
+		if (context == null) {
+			String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.configContextNotSet);
+			log.debug(message);
+			throw new AxisFault(message);
+		}
+
+		String DONE = (String) msgCtx.getProperty(Sandesha2Constants.APPLICATION_PROCESSING_DONE);
+		if (null != DONE && Sandesha2Constants.VALUE_TRUE.equals(DONE)) {
+			if (log.isDebugEnabled())
+				log.debug("Exit: SandeshaInHandler::invoke, Application processing done " + returnValue);
+			return returnValue;
+		}
+		
+		// look at the service to see if RM is totally disabled. This allows the user to disable RM using
+		// a property on the service, even when Sandesha is engaged.
+		if (msgCtx.getAxisService() != null) {
+			Parameter unreliableParam = msgCtx.getAxisService().getParameter(SandeshaClientConstants.UNRELIABLE_MESSAGE);
+			if (null != unreliableParam && "true".equals(unreliableParam.getValue())) {
+				log.debug("Exit: SandeshaInHandler::invoke, Service has disabled RM " + returnValue);
+				return returnValue;
+			}
+		}
+		if (log.isDebugEnabled()) log.debug("SandeshaInHandler::invoke Continuing beyond basic checks");
+
+		Transaction transaction = null;
+
+		try {
+			StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(context, context.getAxisConfiguration());
+			transaction = storageManager.getTransaction();
+
+			AxisService axisService = msgCtx.getAxisService();
+			if (axisService == null) {
+				String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.axisServiceIsNull);
+				log.debug(message);
+				throw new AxisFault(message);
+			}
+
+			RMMsgContext rmMsgCtx = null;
+      
+      if (msgCtx.getProperty(Sandesha2Constants.MessageContextProperties.RM_MESSAGE_CONTEXT) != null)
+        rmMsgCtx = (RMMsgContext)msgCtx.getProperty(Sandesha2Constants.MessageContextProperties.RM_MESSAGE_CONTEXT);
+      else
+        rmMsgCtx = MsgInitializer.initializeMessage(msgCtx);
+
+			// validating the message
+			MessageValidator.validateMessage(rmMsgCtx, storageManager);
+			
+			// commit the current transaction
+			transaction.commit();
+			transaction = storageManager.getTransaction();
+
+			// Process Ack headers in the message
+			AcknowledgementProcessor ackProcessor = new AcknowledgementProcessor();
+			ackProcessor.processAckHeaders(rmMsgCtx);
+
+			// commit the current transaction
+			transaction.commit();
+			transaction = storageManager.getTransaction();
+
+			// Process Ack Request headers in the message
+			AckRequestedProcessor reqProcessor = new AckRequestedProcessor();
+			if(reqProcessor.processAckRequestedHeaders(rmMsgCtx)){
+				returnValue = InvocationResponse.SUSPEND;
+			}
+			
+			// Process MessagePending headers
+			MessagePendingProcessor pendingProcessor = new MessagePendingProcessor();
+			pendingProcessor.processMessagePendingHeaders(rmMsgCtx);
+
+			// commit the current transaction
+			transaction.commit();
+			transaction = storageManager.getTransaction();
+
+			// Process the Sequence header, if there is one
+			SequenceProcessor seqProcessor = new SequenceProcessor();
+			returnValue = seqProcessor.processSequenceHeader(rmMsgCtx);
+
+		} catch (Exception e) {
+			if (log.isDebugEnabled()) 
+				log.debug("SandeshaInHandler::invoke Exception caught during processInMessage", e);
+			// message should not be sent in a exception situation.
+			msgCtx.pause();
+			returnValue = InvocationResponse.SUSPEND;
+			
+			if (transaction != null) {
+				try {
+					transaction.rollback();
+					transaction = null;
+				} catch (Exception e1) {
+					String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.rollbackError, e1.toString());
+					log.debug(message, e);
+				}
+			}
+			
+			// Rethrow the original exception if it is an AxisFault
+			if (e instanceof AxisFault)
+				throw (AxisFault)e;
+			
+			String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.inMsgError, e.toString());
+			throw new AxisFault(message, e);
+		} 
+		finally {
+			if (log.isDebugEnabled()) log.debug("SandeshaInHandler::invoke Doing final processing");
+			if (transaction != null) {
+				try {
+					transaction.commit();
+				} catch (Exception e) {
+					String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.commitError, e.toString());
+					log.debug(message, e);
+				}
+			}
+		}
+		if (log.isDebugEnabled())
+			log.debug("Exit: SandeshaInHandler::invoke " + returnValue);
+		return returnValue;
+	}
+	
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: sandesha-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: sandesha-dev-help@ws.apache.org