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