/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.sandesha2.client;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.MissingResourceException;
import javax.xml.namespace.QName;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.impl.llom.soap11.SOAP11Factory;
import org.apache.axiom.soap.impl.llom.soap12.SOAP12Factory;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.client.async.AxisCallback;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisOperationFactory;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sandesha2.Sandesha2Constants;
import org.apache.sandesha2.SandeshaException;
import org.apache.sandesha2.i18n.SandeshaMessageHelper;
import org.apache.sandesha2.i18n.SandeshaMessageKeys;
import org.apache.sandesha2.msgreceivers.RMMessageReceiver;
import org.apache.sandesha2.policy.SandeshaPolicyBean;
import org.apache.sandesha2.storage.SandeshaStorageException;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.Transaction;
import org.apache.sandesha2.storage.beanmanagers.RMSBeanMgr;
import org.apache.sandesha2.storage.beans.RMSBean;
import org.apache.sandesha2.storage.beans.RMDBean;
import org.apache.sandesha2.util.SandeshaUtil;
import org.apache.sandesha2.util.SpecSpecificConstants;
import org.apache.sandesha2.workers.Invoker;
import org.apache.sandesha2.wsrm.AckRequested;
import org.apache.sandesha2.wsrm.CloseSequence;
import org.apache.sandesha2.wsrm.Identifier;
import org.apache.sandesha2.wsrm.TerminateSequence;
/**
* Contains all the Sandesha2Constants of Sandesha2. Please see sub-interfaces
* to see grouped data.
*/
public class SandeshaClient {
private static final Log log = LogFactory.getLog(SandeshaClient.class);
/**
* Users can get a SequenceReport of the sequence defined by the information
* given from the passed serviceClient object.
*
* @param serviceClient
* @return
* @throws SandeshaException
*/
public static SequenceReport getOutgoingSequenceReport(ServiceClient serviceClient) throws SandeshaException {
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configurationContext = serviceContext.getConfigurationContext();
String internalSequenceID = getInternalSequenceIdFromServiceClient(serviceClient);
return getOutgoingSequenceReport(internalSequenceID, configurationContext);
}
public static SequenceReport getOutgoingSequenceReport(String to, String sequenceKey,
ConfigurationContext configurationContext) throws SandeshaException {
String internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
return getOutgoingSequenceReport(internalSequenceID, configurationContext);
}
public static SequenceReport getOutgoingSequenceReport(String internalSequenceID,
ConfigurationContext configurationContext) throws SandeshaException {
return getOutgoingSequenceReport(internalSequenceID, configurationContext, true);
}
public static SequenceReport getOutgoingSequenceReport(String internalSequenceID,
ConfigurationContext configurationContext, boolean createTransaction) throws SandeshaException {
SequenceReport sequenceReport = new SequenceReport();
sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_OUT);
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
RMSBeanMgr createSeqMgr = storageManager.getRMSBeanMgr();
Transaction reportTransaction = null;
try {
if (createTransaction)
reportTransaction = storageManager.getTransaction();
sequenceReport.setInternalSequenceID(internalSequenceID);
RMSBean createSeqFindBean = new RMSBean();
createSeqFindBean.setInternalSequenceID(internalSequenceID);
RMSBean rMSBean = createSeqMgr.findUnique(createSeqFindBean);
// if data not is available sequence has to be terminated or
// timedOut.
if (rMSBean != null && rMSBean.isTerminated()) {
// check weather this is an terminated sequence.
sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_TERMINATED);
fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);
return sequenceReport;
} else if (rMSBean != null && rMSBean.isTimedOut()) {
sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_TIMED_OUT);
fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);
return sequenceReport;
} else if (rMSBean == null) {
// sequence must hv been timed out before establishing. No other
// posibility I can think of.
// this does not get recorded since there is no key (which is
// normally the sequenceID) to store it.
// so, setting the sequence status to INITIAL
sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_INITIAL);
// returning the current sequence report.
return sequenceReport;
}
String outSequenceID = rMSBean.getSequenceID();
if (outSequenceID == null) {
sequenceReport.setInternalSequenceID(internalSequenceID);
sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_INITIAL);
sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_OUT);
if(rMSBean.getSecurityTokenData() != null) sequenceReport.setSecureSequence(true);
return sequenceReport;
}
sequenceReport.setSequenceStatus(SequenceReport.SEQUENCE_STATUS_ESTABLISHED);
fillOutgoingSequenceInfo(sequenceReport, rMSBean, storageManager);
if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
reportTransaction = null;
} catch (Exception e) {
// Just log the exception
if(log.isDebugEnabled()) log.debug("Exception", e);
} finally {
if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.rollback();
}
return sequenceReport;
}
private static void fillOutgoingSequenceInfo(SequenceReport report, RMSBean rmsBean,
StorageManager storageManager) {
report.setSequenceID(rmsBean.getSequenceID());
List completedMessageList = rmsBean.getClientCompletedMessages().getContainedElementsAsNumbersList();
Iterator iter = completedMessageList.iterator();
while (iter.hasNext()) {
report.addCompletedMessage((Long)iter.next());
}
if(rmsBean.getSecurityTokenData() != null) report.setSecureSequence(true);
}
/**
* Users can get a list of sequenceReports each describing a incoming
* sequence, which are the sequences the client work as a RMD.
*
* @param configCtx
* @return
* @throws SandeshaException
*/
public static List getIncomingSequenceReports(ConfigurationContext configCtx) throws SandeshaException {
SandeshaReport report = getSandeshaReport(configCtx);
List incomingSequenceIDs = report.getIncomingSequenceList();
Iterator incomingSequenceIDIter = incomingSequenceIDs.iterator();
ArrayList incomingSequenceReports = new ArrayList();
while (incomingSequenceIDIter.hasNext()) {
String sequenceID = (String) incomingSequenceIDIter.next();
SequenceReport incomingSequenceReport = getIncomingSequenceReport(sequenceID, configCtx);
if (incomingSequenceReport == null) {
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.incommingSequenceReportNotFound, sequenceID));
}
incomingSequenceReports.add(incomingSequenceReport);
}
return incomingSequenceReports;
}
/**
* SandeshaReport gives the details of all incoming and outgoing sequences.
* The outgoing sequence have to pass the initial state (CS/CSR exchange) to
* be included in a SandeshaReport
*
* @param configurationContext
* @return
* @throws SandeshaException
*/
public static SandeshaReport getSandeshaReport(ConfigurationContext configurationContext) throws SandeshaException {
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
SandeshaReport sandeshaReport = new SandeshaReport();
Transaction reportTransaction = null;
try {
reportTransaction = storageManager.getTransaction();
List rmsBeans = storageManager.getRMSBeanMgr().find(null);
Iterator iterator = rmsBeans.iterator();
while (iterator.hasNext()) {
RMSBean bean = (RMSBean) iterator.next();
String sequenceID = bean.getSequenceID();
sandeshaReport.addToOutgoingSequenceList(sequenceID);
sandeshaReport.addToOutgoingInternalSequenceMap(sequenceID, bean.getInternalSequenceID());
SequenceReport report = getOutgoingSequenceReport(bean.getInternalSequenceID(), configurationContext);
sandeshaReport.addToNoOfCompletedMessagesMap(sequenceID, report.getCompletedMessages().size());
sandeshaReport.addToSequenceStatusMap(sequenceID, report.getSequenceStatus());
}
// incoming sequences
Collection rmdBeans = storageManager.getRMDBeanMgr().find(null);
Iterator iter = rmdBeans.iterator();
while (iter.hasNext()) {
RMDBean serverCompletedMsgsBean = (RMDBean) iter.next();
String sequenceID = serverCompletedMsgsBean.getSequenceID();
sandeshaReport.addToIncomingSequenceList(sequenceID);
SequenceReport sequenceReport = getIncomingSequenceReport(sequenceID, configurationContext);
sandeshaReport.addToNoOfCompletedMessagesMap(sequenceID, sequenceReport.getCompletedMessages().size());
sandeshaReport.addToSequenceStatusMap(sequenceID, sequenceReport.getSequenceStatus());
}
if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
reportTransaction = null;
} catch (Exception e) {
// just log the error
if(log.isDebugEnabled()) log.debug("Exception", e);
} finally {
if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.rollback();
}
return sandeshaReport;
}
/**
* This could be used to create sequences with a given sequence key.
*
* @param serviceClient - A configured ServiceClient to be used to invoke RM messages. This need to have Sandesha2 engaged.
* @param offer - Weather a sequence should be offered for obtaining response messages.
* @param sequenceKey The sequenceKey of the newly generated sequence.
* @throws SandeshaException
*/
public static void createSequence(ServiceClient serviceClient, boolean offer, String sequenceKey) throws SandeshaException {
if (log.isDebugEnabled())
log.debug("Enter: SandeshaClient::createSequence , " + offer + ", " + sequenceKey);
setUpServiceClientAnonymousOperations (serviceClient);
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
EndpointReference toEPR = serviceClient.getOptions().getTo();
if (toEPR == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
String to = toEPR.getAddress();
if (to == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
if (offer) {
String offeredSequenceID = SandeshaUtil.getUUID();
options.setProperty(SandeshaClientConstants.OFFERED_SEQUENCE_ID, offeredSequenceID);
}
// setting a new squenceKey if not already set.
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
//When the message is marked as Dummy the application processor will not actually try to send it.
//But still the create Sequence will be added.
options.setProperty(SandeshaClientConstants.DUMMY_MESSAGE, Sandesha2Constants.VALUE_TRUE);
String oldAction = options.getAction();
options.setAction(SpecSpecificConstants.getCreateSequenceAction(rmSpecVersion));
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configurationContext = serviceContext.getConfigurationContext();
// cleanup previous sequence
cleanupTerminatedSequence(to, oldSequenceKey, SandeshaUtil.getSandeshaStorageManager(configurationContext, configurationContext.getAxisConfiguration()));
try {
//just to inform the sender.
serviceClient.fireAndForget (null);
} catch (AxisFault e) {
throw new SandeshaException(e);
}
finally {
options.setAction(oldAction);
options.setProperty(SandeshaClientConstants.DUMMY_MESSAGE, Sandesha2Constants.VALUE_FALSE);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
if (log.isDebugEnabled())
log.debug("Exit: SandeshaClient::createSequence");
}
/**
* If a user has requested to create a new sequence which was previously terminated, we need to clean up
* any previous properties that might have been stored.
* @param to
* @param sequenceKey
* @throws SandeshaStorageException
*/
private static final void cleanupTerminatedSequence(String to, String sequenceKey, StorageManager storageManager) throws SandeshaException {
String internalSequenceId = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
if (log.isTraceEnabled())
log.trace("Checking if sequence " + internalSequenceId + " previously terminated");
Transaction tran = null;
try {
tran = storageManager.getTransaction();
RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
//see if the sequence is terminated
boolean terminatedSequence = false;
if (rmsBean != null && rmsBean.isTerminated())
terminatedSequence = true;
//see if the sequence is timed out
if(rmsBean != null && rmsBean.isTimedOut()){
terminatedSequence = true;
}
if (terminatedSequence) {
// Delete the rmsBean
storageManager.getRMSBeanMgr().delete(rmsBean.getCreateSeqMsgID());
}
if(tran != null && tran.isActive()) tran.commit();
tran = null;
} finally {
if(tran!=null && tran.isActive())
tran.rollback();
}
}
/**
* Clients can use this to create a sequence sequence.
*
* @param serviceClient - A configured ServiceClient to be used to invoke RM messages. This need to have Sandesha2 engaged.
* @param offer - Weather a sequence should be offered for obtaining response messages.
* @return The sequenceKey of the newly generated sequence.
* @throws SandeshaException
*/
public static String createSequence(ServiceClient serviceClient, boolean offer)
throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String newSequenceKey = SandeshaUtil.getUUID();
createSequence(serviceClient, offer, newSequenceKey);
return newSequenceKey;
}
/**
* User can terminate the sequence defined by the passed serviceClient.
*
* @deprecated
*/
public static void createSequnce(ServiceClient serviceClient, boolean offer, String sequenceKey)
throws SandeshaException {
createSequence(serviceClient,offer,sequenceKey);
}
/**
* User can terminate the sequence defined by the passed serviceClient.
*
* @param serviceClient
* @throws SandeshaException
*/
public static void terminateSequence(ServiceClient serviceClient) throws SandeshaException {
setUpServiceClientAnonymousOperations (serviceClient);
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
String oldAction = options.getAction();
//in WSRM 1.0 we are adding another application msg with the LastMessage tag, instead of sending a terminate here.
//Actual terminate will be sent once all the messages upto this get acked
try {
if (Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(rmSpecVersion)) {
SOAPEnvelope terminateEnvelope = configureTerminateSequence(options, serviceContext
.getConfigurationContext());
OMElement terminateBody = terminateEnvelope.getBody().getFirstChildWithName(
new QName(rmNamespaceValue,
Sandesha2Constants.WSRM_COMMON.TERMINATE_SEQUENCE));
// To inform the Sandesha2 out handler. The response to this call needs
// be routed to the Sandesha Message receiver
AxisCallback callback = new AxisCallback() {
public void onMessage(MessageContext msg) {
try {
RMMessageReceiver rm = new RMMessageReceiver();
rm.receive(msg);
} catch(Exception e) {
if(log.isErrorEnabled()) log.error("Exception on callback", e);
}
}
public void onFault(MessageContext msg) {
try {
RMMessageReceiver rm = new RMMessageReceiver();
rm.receive(msg);
} catch(Exception e) {
if(log.isErrorEnabled()) log.error("Exception on callback", e);
}
}
public void onError(Exception e) {
if(log.isErrorEnabled()) log.error("Exception on callback", e);
}
public void onComplete() {
// Nothing to do here
}
};
serviceClient.sendReceiveNonBlocking(terminateBody, callback);
} else {
options.setAction(Sandesha2Constants.SPEC_2005_02.Actions.ACTION_LAST_MESSAGE);
options.setProperty(SandeshaClientConstants.LAST_MESSAGE, Constants.VALUE_TRUE);
serviceClient.fireAndForget(null);
}
} catch (AxisFault e) {
String message = SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.couldNotSendTerminate,
e.toString());
throw new SandeshaException(message, e);
} finally {
options.setAction(oldAction);
}
}
public static void terminateSequence(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
terminateSequence(serviceClient);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
/**
* User can close the sequence defined by the passed serviceClient.
*
* @param serviceClient
* @throws SandeshaException
*/
public static void closeSequence(ServiceClient serviceClient) throws SandeshaException {
setUpServiceClientAnonymousOperations (serviceClient);
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
SOAPEnvelope closeSequnceEnvelope = configureCloseSequence(options, serviceContext.getConfigurationContext());
OMElement closeSequenceBody = closeSequnceEnvelope.getBody().getFirstChildWithName(
new QName(rmNamespaceValue, Sandesha2Constants.WSRM_COMMON.CLOSE_SEQUENCE));
String oldAction = options.getAction();
options.setAction(SpecSpecificConstants.getCloseSequenceAction(rmSpecVersion));
try {
//to inform the sandesha2 out handler
serviceClient.fireAndForget (closeSequenceBody);
} catch (AxisFault e) {
String message = SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.couldNotSendClose,
e.toString());
throw new SandeshaException(message, e);
} finally {
options.setAction(oldAction);
}
}
public static void closeSequence(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
String specVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (!Sandesha2Constants.SPEC_VERSIONS.v1_1.equals(specVersion)) {
String message = SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.closeSequenceSpecLevel,
specVersion);
throw new SandeshaException (message);
}
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
closeSequence(serviceClient);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
/**
* This blocks the system until the messages u have sent hv been completed.
*
* @param serviceClient
*/
public static void waitUntilSequenceCompleted(ServiceClient serviceClient) throws SandeshaException {
waitUntilSequenceCompleted(serviceClient, -1);
}
public static void waitUntilSequenceCompleted(ServiceClient serviceClient, String sequenceKey)
throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
waitUntilSequenceCompleted(serviceClient);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
/**
* This blocks the system until the messages u have sent hv been completed
* or until the given time interval exceeds. (the time is taken in seconds)
*
* @param serviceClient
* @param maxWaitingTime
*/
public static void waitUntilSequenceCompleted(ServiceClient serviceClient, long maxWaitingTime)
throws SandeshaException {
long startTime = System.currentTimeMillis();
SequenceReport sequenceReport = getOutgoingSequenceReport(serviceClient);
if (sequenceReport == null) {
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.cannotFindReportForGivenData,
serviceClient.toString()));
}
boolean done = false;
while (!done) {
sequenceReport = getOutgoingSequenceReport(serviceClient);
int status = sequenceReport.getSequenceStatus();
if (status == SequenceReport.SEQUENCE_STATUS_TERMINATED)
done = true;
if (status == SequenceReport.SEQUENCE_STATUS_TIMED_OUT)
done = true;
if (!done) {
long timeNow = System.currentTimeMillis();
if ((timeNow > (startTime + maxWaitingTime)) && maxWaitingTime != -1)
done = true;
else
{
// Wait for half a second to stop 100 CPU
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// Ignore the exception
}
}
}
}
}
public static void waitUntilSequenceCompleted(ServiceClient serviceClient, long maxWaitingTime, String sequenceKey)
throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
waitUntilSequenceCompleted(serviceClient, maxWaitingTime);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
// gives the out sequenceID if CS/CSR exchange is done. Otherwise a
// SandeshaException
public static String getSequenceID(ServiceClient serviceClient) throws SandeshaException {
String internalSequenceID = getInternalSequenceIdFromServiceClient(serviceClient);
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configurationContext = serviceContext.getConfigurationContext();
SequenceReport sequenceReport = SandeshaClient.getOutgoingSequenceReport(serviceClient);
if (sequenceReport == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.cannotFindReportForGivenData, serviceClient.toString()));
if (sequenceReport.getSequenceStatus() != SequenceReport.SEQUENCE_STATUS_ESTABLISHED) {
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.noSequenceEstablished,
internalSequenceID));
}
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
// Get a transaction to retrieve the properties
Transaction transaction = null;
String sequenceID = null;
try
{
transaction = storageManager.getTransaction();
sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
}
finally
{
// Commit the transaction as it was only a retrieve
if(transaction != null) transaction.commit();
}
if (sequenceID == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.sequenceIdBeanNotSet));
return sequenceID;
}
private static SOAPEnvelope configureAckRequest(Options options, ConfigurationContext configurationContext)
throws SandeshaException, MissingResourceException {
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
EndpointReference epr = options.getTo();
if (epr == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
//first see if the cliet has told us which sequence to terminate
String internalSequenceID =
(String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
if(internalSequenceID==null){
//lookup the internal seq id based on to EPR and sequenceKey
String to = epr.getAddress();
String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
}
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
// Get a transaction to obtain sequence information
Transaction transaction = null;
String sequenceID = null;
try
{
transaction = storageManager.getTransaction();
sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
}
finally
{
// Commit the tran whatever happened
if(transaction != null) transaction.commit();
}
if (sequenceID == null)
sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID;
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
options.setAction(SpecSpecificConstants.getAckRequestAction(rmSpecVersion));
String soapNamespaceURI = options.getSoapVersionURI();
if (soapNamespaceURI == null)
soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);
SOAPFactory factory = null;
SOAPEnvelope dummyEnvelope = null;
if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
factory = new SOAP12Factory();
dummyEnvelope = factory.getDefaultEnvelope();
} else {
factory = new SOAP11Factory();
dummyEnvelope = factory.getDefaultEnvelope();
}
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
AckRequested ackRequested = new AckRequested(rmNamespaceValue);
Identifier identifier = new Identifier(rmNamespaceValue);
identifier.setIndentifer(sequenceID);
ackRequested.setIdentifier(identifier);
ackRequested.toSOAPEnvelope(dummyEnvelope);
return dummyEnvelope;
}
public static void sendAckRequest(ServiceClient serviceClient) throws SandeshaException {
setUpServiceClientAnonymousOperations (serviceClient);
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configContext = serviceContext.getConfigurationContext();
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = Sandesha2Constants.SPEC_VERSIONS.v1_0;
if (Sandesha2Constants.SPEC_VERSIONS.v1_0.equals(rmSpecVersion)) {
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.emptyAckRequestSpecLevel, rmSpecVersion));
}
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
SOAPEnvelope dummyEnvelope = configureAckRequest(options, configContext);
OMElement ackRequestedHeaderBlock = dummyEnvelope.getHeader().getFirstChildWithName(
new QName(rmNamespaceValue, Sandesha2Constants.WSRM_COMMON.ACK_REQUESTED));
String oldAction = options.getAction();
serviceClient.addHeader(ackRequestedHeaderBlock);
try {
//to inform the sandesha2 out handler
serviceClient.sendReceiveNonBlocking (null,new AxisCallback () {
public void onComplete() {}
public void onError(Exception e) {}
public void onFault(MessageContext msgContext) {}
public void onMessage(MessageContext msgContext) {}
});
} catch (AxisFault e) {
String message = SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.cannotSendAckRequestException, e.toString());
throw new SandeshaException(message, e);
}
serviceClient.removeHeaders();
options.setAction(oldAction);
}
public static void sendAckRequest(ServiceClient serviceClient, String sequenceKey) throws SandeshaException {
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
String oldSequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, sequenceKey);
sendAckRequest(serviceClient);
options.setProperty(SandeshaClientConstants.SEQUENCE_KEY, oldSequenceKey);
}
/**
* Forces any inbound messages currently on the specified inOrder inbound sequence to be dispatched out of order.
* @param configContext
* @param sequenceID
* @param allowLaterDeliveryOfMissingMessages if true, messages skipped over during this
* action will be invoked if they arrive on the system at a later time.
* Otherwise messages skipped over will be ignored
* @throws SandeshaException
*/
public static void forceDispatchOfInboundMessages(ConfigurationContext configContext,
String sequenceID,
boolean allowLaterDeliveryOfMissingMessages)throws SandeshaException{
Transaction reportTransaction = null;
try {
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configContext, configContext.getAxisConfiguration());
reportTransaction = storageManager.getTransaction();
//only do this if we are running inOrder
if(SandeshaUtil.getPropertyBean(configContext.getAxisConfiguration()).isInOrder()){
Invoker invoker = (Invoker)SandeshaUtil.getSandeshaStorageManager(configContext, configContext.getAxisConfiguration()).getInvoker();
if (invoker==null){
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.invokerNotFound, sequenceID));
}
invoker.forceInvokeOfAllMessagesCurrentlyOnSequence(configContext, sequenceID, allowLaterDeliveryOfMissingMessages);
}
if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.commit();
reportTransaction = null;
} catch (Exception e) {
// Just log the exception
if(log.isDebugEnabled()) log.debug("Exception", e);
} finally {
if(reportTransaction != null && reportTransaction.isActive()) reportTransaction.rollback();
}
}
private static SOAPEnvelope configureCloseSequence(Options options, ConfigurationContext configurationContext)
throws SandeshaException {
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
EndpointReference epr = options.getTo();
if (epr == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
//first see if the cliet has told us which sequence to close
String internalSequenceID =
(String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
if(internalSequenceID==null){
//lookup the internal seq id based on to EPR and sequenceKey
String to = epr.getAddress();
String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
}
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
// Get a transaction for getting the sequence properties
Transaction transaction = null;
String sequenceID = null;
try
{
transaction = storageManager.getTransaction();
sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
}
finally
{
// Commit the tran whatever happened
if(transaction != null) transaction.commit();
}
if (sequenceID == null)
sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID;
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
if (!SpecSpecificConstants.isSequenceClosingAllowed(rmSpecVersion))
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.closeSequenceSpecLevel, rmSpecVersion));
SOAPEnvelope dummyEnvelope = null;
SOAPFactory factory = null;
String soapNamespaceURI = options.getSoapVersionURI();
if (soapNamespaceURI == null)
soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);
if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
factory = new SOAP12Factory();
dummyEnvelope = factory.getDefaultEnvelope();
} else {
factory = new SOAP11Factory();
dummyEnvelope = factory.getDefaultEnvelope();
}
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
CloseSequence closeSequence = new CloseSequence(rmNamespaceValue);
Identifier identifier = new Identifier(rmNamespaceValue);
identifier.setIndentifer(sequenceID);
closeSequence.setIdentifier(identifier);
closeSequence.toSOAPEnvelope(dummyEnvelope);
return dummyEnvelope;
}
private static byte getServerSequenceStatus(String sequenceID, StorageManager storageManager)
throws SandeshaException {
RMDBean rmdBean = SandeshaUtil.getRMDBeanFromSequenceId(storageManager, sequenceID);
if (rmdBean != null && rmdBean.isTerminated()) {
return SequenceReport.SEQUENCE_STATUS_TERMINATED;
}
/* Only outbound sequences time out
SequencePropertyBean timedOutBean = seqPropMgr.retrieve(sequenceID,
Sandesha2Constants.SequenceProperties.SEQUENCE_TIMED_OUT);
if (timedOutBean != null) {
return SequenceReport.SEQUENCE_STATUS_TIMED_OUT;
}
*/
if (rmdBean != null) {
return SequenceReport.SEQUENCE_STATUS_ESTABLISHED;
}
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.cannotFindSequence, sequenceID
));
}
public static SequenceReport getIncomingSequenceReport(String sequenceID, ConfigurationContext configCtx)
throws SandeshaException {
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configCtx,configCtx.getAxisConfiguration());
Transaction reportTransaction = null;
try {
reportTransaction = storageManager.getTransaction();
SequenceReport sequenceReport = new SequenceReport();
RMDBean rmdBean = SandeshaUtil.getRMDBeanFromSequenceId(storageManager, sequenceID);
List completedMessageList = rmdBean.getServerCompletedMessages().getContainedElementsAsNumbersList();
Iterator iter = completedMessageList.iterator();
while (iter.hasNext()) {
sequenceReport.addCompletedMessage((Long) iter.next());
}
sequenceReport.setSequenceID(sequenceID);
sequenceReport.setInternalSequenceID(sequenceID); // for the
// incoming side
// internalSequenceID=sequenceID
sequenceReport.setSequenceDirection(SequenceReport.SEQUENCE_DIRECTION_IN);
sequenceReport.setSequenceStatus(getServerSequenceStatus(sequenceID, storageManager));
if(rmdBean.getSecurityTokenData() != null) sequenceReport.setSecureSequence(true);
if (reportTransaction!=null && reportTransaction.isActive()) reportTransaction.commit();
reportTransaction = null;
return sequenceReport;
} catch (Exception e) {
// Just log the exception
if(log.isDebugEnabled()) log.debug("Exception", e);
} finally {
if(reportTransaction != null && reportTransaction.isActive()) {
reportTransaction.rollback();
}
}
return null;
}
private static SOAPEnvelope configureTerminateSequence(Options options, ConfigurationContext configurationContext)
throws SandeshaException {
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
EndpointReference epr = options.getTo();
if (epr == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
//first see if the cliet has told us which sequence to terminate
String internalSequenceID =
(String)options.getProperty(SandeshaClientConstants.INTERNAL_SEQUENCE_ID);
if(internalSequenceID==null){
//lookup the internal seq id based on to EPR and sequenceKey
String to = epr.getAddress();
String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
}
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
// Get a transaction to obtain sequence information
Transaction transaction = null;
String sequenceID = null;
try
{
transaction = storageManager.getTransaction();
sequenceID = SandeshaUtil.getSequenceIDFromInternalSequenceID(internalSequenceID, storageManager);
}
finally
{
// Commit the tran whatever happened
if(transaction != null) transaction.commit();
}
if (sequenceID == null)
sequenceID = Sandesha2Constants.TEMP_SEQUENCE_ID;
String rmSpecVersion = (String) options.getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
if (rmSpecVersion == null)
rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
options.setAction(SpecSpecificConstants.getTerminateSequenceAction(rmSpecVersion));
SOAPEnvelope dummyEnvelope = null;
SOAPFactory factory = null;
String soapNamespaceURI = options.getSoapVersionURI();
if (soapNamespaceURI == null)
soapNamespaceURI = getSOAPNamespaceURI(storageManager, internalSequenceID);
if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI.equals(soapNamespaceURI)) {
factory = new SOAP12Factory();
dummyEnvelope = factory.getDefaultEnvelope();
} else {
factory = new SOAP11Factory();
dummyEnvelope = factory.getDefaultEnvelope();
}
String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
TerminateSequence terminateSequence = new TerminateSequence(rmNamespaceValue);
Identifier identifier = new Identifier(rmNamespaceValue);
identifier.setIndentifer(sequenceID);
terminateSequence.setIdentifier(identifier);
terminateSequence.toSOAPEnvelope(dummyEnvelope);
return dummyEnvelope;
}
// private static SOAPEnvelope configureCreateSequence(Options options,
// ConfigurationContext configurationContext) throws AxisFault {
//
// if (options == null)
// throw new SandeshaException(SandeshaMessageHelper
// .getMessage(SandeshaMessageKeys.optionsObjectNotSet));
//
// EndpointReference epr = options.getTo();
// if (epr == null)
// throw new SandeshaException(SandeshaMessageHelper.getMessage(
// SandeshaMessageKeys.toEPRNotValid, null));
//
//
// String rmSpecVersion = (String) options
// .getProperty(SandeshaClientConstants.RM_SPEC_VERSION);
// if (rmSpecVersion == null)
// rmSpecVersion = SpecSpecificConstants.getDefaultSpecVersion();
//
// options.setAction(SpecSpecificConstants
// .getCreateSequenceAction (rmSpecVersion));
//
// SOAPEnvelope dummyEnvelope = null;
// SOAPFactory factory = null;
// String soapNamespaceURI = options.getSoapVersionURI();
// if (SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI
// .equals(soapNamespaceURI)) {
// factory = new SOAP12Factory();
// dummyEnvelope = factory.getDefaultEnvelope();
// } else {
// factory = new SOAP11Factory();
// dummyEnvelope = factory.getDefaultEnvelope();
// }
//
// String rmNamespaceValue = SpecSpecificConstants.getRMNamespaceValue(rmSpecVersion);
//
// String addressingNamespaceValue = (String) options.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
// if (addressingNamespaceValue==null)
// addressingNamespaceValue = SpecSpecificConstants.getDefaultAddressingNamespace ();
//
//
// CreateSequence createSequence = new CreateSequence (rmNamespaceValue,addressingNamespaceValue);
// AcksTo acksTo = new AcksTo (rmNamespaceValue,addressingNamespaceValue);
// createSequence.setAcksTo(acksTo);
// EndpointReference endpointReference = new EndpointReference (null);
// acksTo.setAddress(endpointReference);
//
// createSequence.toSOAPEnvelope(dummyEnvelope);
//
// return dummyEnvelope;
// }
/**
* Sandesha uses default 'fireAndForget' and 'sendReceive' methods to send control messages.
* But these can only be called when Anonymous operations are present within the passed ServiceClient.
* But these could be situations where these Anonymous operations are not present. In such cases Sandesha2
* will try to add them into the serviceClient.
*/
private static void setUpServiceClientAnonymousOperations (ServiceClient serviceClient) throws SandeshaException {
try {
AxisService service = serviceClient.getAxisService();
AxisOperation anonOutOnlyOperation = service.getOperation(ServiceClient.ANON_OUT_ONLY_OP);
if (anonOutOnlyOperation==null) {
anonOutOnlyOperation = AxisOperationFactory.getAxisOperation(WSDLConstants.MEP_CONSTANT_OUT_ONLY);
anonOutOnlyOperation.setName(ServiceClient.ANON_OUT_ONLY_OP);
AxisOperation referenceOperation = service.getOperation(Sandesha2Constants.RM_IN_ONLY_OPERATION);
if (referenceOperation!=null) {
anonOutOnlyOperation.setPhasesOutFlow(referenceOperation.getPhasesOutFlow());
anonOutOnlyOperation.setPhasesOutFaultFlow(referenceOperation.getPhasesOutFaultFlow());
anonOutOnlyOperation.setPhasesInFaultFlow(referenceOperation.getPhasesInFaultFlow());
anonOutOnlyOperation.setPhasesInFaultFlow(referenceOperation.getRemainingPhasesInFlow());
service.addOperation(anonOutOnlyOperation);
} else {
String message = "Cant find RM Operations. Please engage the Sandesha2 module before doing the invocation.";
throw new SandeshaException (message);
}
}
AxisOperation anonOutInOperation = service.getOperation(ServiceClient.ANON_OUT_IN_OP);
if (anonOutInOperation==null) {
anonOutInOperation = AxisOperationFactory.getAxisOperation(WSDLConstants.MEP_CONSTANT_OUT_IN);
anonOutInOperation.setName(ServiceClient.ANON_OUT_IN_OP);
AxisOperation referenceOperation = service.getOperation(Sandesha2Constants.RM_IN_OUT_OPERATION);
if (referenceOperation!=null) {
anonOutInOperation.setPhasesOutFlow(referenceOperation.getPhasesOutFlow());
anonOutInOperation.setPhasesOutFaultFlow(referenceOperation.getPhasesOutFaultFlow());
anonOutInOperation.setPhasesInFaultFlow(referenceOperation.getPhasesInFaultFlow());
anonOutInOperation.setPhasesInFaultFlow(referenceOperation.getRemainingPhasesInFlow());
//operation will be added to the service only if a valid referenceOperation was found.
service.addOperation(anonOutInOperation);
}
}
} catch (AxisFault e) {
throw new SandeshaException (e);
}
}
/**
* Gets the last error that occured on a send to an endpoint.
*
* The method will return null if no exception has been encountered.
* Errors may be transient and maybe out of date. To check the validity of the
* error, check the timestamp from which the error was encountered
* @see getLastSendTimestamp .
*
* @param serviceClient
* @return
* @throws SandeshaException
*/
public static Exception getLastSendError(ServiceClient serviceClient)
throws SandeshaException
{
if (log.isDebugEnabled())
log.debug("Enter: SandeshaClient::getLastSendError");
// Get the internal sequence id for this client
String internalSequenceId = getInternalSequenceIdFromServiceClient(serviceClient);
if (log.isTraceEnabled())
log.trace("Looking up sequence with identifier " + internalSequenceId);
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configurationContext = serviceContext.getConfigurationContext();
// Get the in use storage manager and the sequence property bean manager
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
Transaction transaction = null;
Exception resultException = null;
try
{
transaction = storageManager.getTransaction();
RMSBean bean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
if (bean != null) {
resultException = bean.getLastSendError();
}
}
finally
{
// Commit the tran whatever happened
if(transaction != null) transaction.commit();
}
if (log.isDebugEnabled())
log.debug("Exit: SandeshaClient::getLastSendError, " + resultException);
return resultException;
}
/**
* Gets the timestamp from which the last error that occured on a send to an endpoint.
*
* The method will return -1 if no errors have been encountered.
*
* @param serviceClient
* @return
* @throws SandeshaException
*/
public static long getLastSendErrorTimestamp(ServiceClient serviceClient)
throws SandeshaException
{
if (log.isDebugEnabled())
log.debug("Enter: SandeshaClient::getLastSendErrorTimestamp");
// Get the internal sequence id for this client
String internalSequenceId = getInternalSequenceIdFromServiceClient(serviceClient);
if (log.isTraceEnabled())
log.trace("Looking up sequence with identifier " + internalSequenceId);
ServiceContext serviceContext = serviceClient.getServiceContext();
if (serviceContext == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.serviceContextNotSet));
ConfigurationContext configurationContext = serviceContext.getConfigurationContext();
// Get the in use storage manager and the sequence property bean manager
StorageManager storageManager = SandeshaUtil.getSandeshaStorageManager(configurationContext,configurationContext.getAxisConfiguration());
// Create a transaction for the retrieve operation
Transaction transaction = null;
long resultTime = -1;
try
{
transaction = storageManager.getTransaction();
RMSBean bean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
if (bean != null) {
resultTime = bean.getLastSendErrorTimestamp();
}
}
finally
{
// commit the transaction as it was only a retrieve
if(transaction != null) transaction.commit();
}
if (log.isDebugEnabled())
log.debug("Exit: SandeshaClient::getLastSendErrorTimestamp, " + resultTime);
return resultTime;
}
/**
* Gets the internal sequence id from the service client instance.
*
* @param serviceClient
* @return
* @throws SandeshaException
*/
private static String getInternalSequenceIdFromServiceClient(ServiceClient serviceClient) throws SandeshaException
{
Options options = serviceClient.getOptions();
if (options == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.optionsObjectNotSet));
EndpointReference toEPR = options.getTo();
if (toEPR == null)
throw new SandeshaException(SandeshaMessageHelper.getMessage(
SandeshaMessageKeys.toEPRNotValid, null));
String to = toEPR.getAddress();
String sequenceKey = (String) options.getProperty(SandeshaClientConstants.SEQUENCE_KEY);
String internalSequenceID = SandeshaUtil.getInternalSequenceID(to, sequenceKey);
return internalSequenceID;
}
private static final String getSOAPNamespaceURI(StorageManager storageManager, String internalSequenceID) throws SandeshaException {
String soapNamespaceURI = null;
// Get the RMSBean for this sequence.
Transaction transaction = null;
try {
transaction = storageManager.getTransaction();
RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceID);
if (rmsBean.getSoapVersion() == Sandesha2Constants.SOAPVersion.v1_2)
soapNamespaceURI = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
} finally {
if(transaction != null) transaction.commit();
}
return soapNamespaceURI;
}
public static void setPolicyBean (ServiceClient serviceClient, SandeshaPolicyBean policyBean) throws SandeshaException {
try {
AxisService axisService = serviceClient.getAxisService();
if (axisService!=null) {
Parameter parameter = axisService.getParameter(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
SandeshaPolicyBean parent = null;
if (parameter==null) {
parameter = new Parameter ();
parameter.setName(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
} else {
parameter.setEditable(true); //if we don't do it here, Axis2 will not allow us to override the parameter value.
parent = (SandeshaPolicyBean) parameter.getValue();
policyBean.setParent(parent);
}
parameter.setValue(policyBean);
axisService.addParameter(parameter);
} else {
String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotSetPolicyBeanServiceNull);
throw new SandeshaException (message);
}
} catch (AxisFault e) {
throw new SandeshaException (e);
}
}
}