Package org.apache.sandesha2.util

Source Code of org.apache.sandesha2.util.SandeshaUtil

/*
* 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.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axiom.soap.SOAP12Constants;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axiom.soap.impl.builder.StAXSOAPModelBuilder;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.OperationContextFactory;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.context.ServiceGroupContext;
import org.apache.axis2.description.AxisDescription;
import org.apache.axis2.description.AxisModule;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisServiceGroup;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.TransportOutDescription;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sandesha2.RMMsgContext;
import org.apache.sandesha2.Sandesha2Constants;
import org.apache.sandesha2.SandeshaException;
import org.apache.sandesha2.client.SandeshaClientConstants;
import org.apache.sandesha2.context.ContextManager;
import org.apache.sandesha2.i18n.SandeshaMessageHelper;
import org.apache.sandesha2.i18n.SandeshaMessageKeys;
import org.apache.sandesha2.policy.SandeshaPolicyBean;
import org.apache.sandesha2.security.SecurityManager;
import org.apache.sandesha2.storage.StorageManager;
import org.apache.sandesha2.storage.beanmanagers.RMDBeanMgr;
import org.apache.sandesha2.storage.beanmanagers.RMSBeanMgr;
import org.apache.sandesha2.storage.beans.RMDBean;
import org.apache.sandesha2.storage.beans.RMSBean;
import org.apache.sandesha2.storage.beans.RMSequenceBean;
import org.apache.sandesha2.transport.Sandesha2TransportOutDesc;
import org.apache.sandesha2.workers.SandeshaThread;
import org.apache.sandesha2.wsrm.AckRequested;
import org.apache.sandesha2.wsrm.AcknowledgementRange;
import org.apache.sandesha2.wsrm.CloseSequence;
import org.apache.sandesha2.wsrm.CloseSequenceResponse;
import org.apache.sandesha2.wsrm.Sequence;
import org.apache.sandesha2.wsrm.SequenceAcknowledgement;

/**
* Contains utility methods that are used in many plases of Sandesha2.
*/

public class SandeshaUtil {

  // private static Hashtable storedMsgContexts = new Hashtable();

  private static Log log = LogFactory.getLog(SandeshaUtil.class);
 
  private static AxisModule axisModule = null;

  public static AxisModule getAxisModule() {
    return axisModule;
  }

  public static void setAxisModule(AxisModule module) {
    axisModule = module;
  }

  /**
   * Create a new UUID.
   *
   * @return
   */
  public static String getUUID() {
    // String uuid = "uuid:" + UUIDGenerator.getUUID();
    String uuid = org.apache.axiom.om.util.UUIDGenerator.getUUID();

    return uuid;
  }

  /**
   * Used to convert a RangeString into a set of AcknowledgementRanges.
   *
   * @param msgNoStr
   * @param factory
   * @return
   * @throws SandeshaException
   */
  public static ArrayList getAckRangeArrayList(RangeString completedMessageRanges, String rmNamespaceValue)
      throws SandeshaException {

    ArrayList ackRanges = new ArrayList(); //the final ack ranges that we will build up

    Range[] ranges = completedMessageRanges.getRanges();
    for(int i=0; i<ranges.length; i++){
      AcknowledgementRange ackRange = new AcknowledgementRange(rmNamespaceValue);
      ackRange.setLowerValue(ranges[i].lowerValue);
      ackRange.setUpperValue(ranges[i].upperValue);
      ackRanges.add(ackRange);     
    }
   
    return ackRanges;
  }

  public static void startWorkersForSequence(ConfigurationContext context, RMSequenceBean sequence)
  throws SandeshaException {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaUtil::startWorkersForSequence, sequence " + sequence);
   
    StorageManager mgr = getSandeshaStorageManager(context, context.getAxisConfiguration());
    boolean polling = sequence.isPollingMode();
   
    SandeshaThread sender = mgr.getSender();
    SandeshaThread invoker = mgr.getInvoker();
    SandeshaThread pollMgr = mgr.getPollingManager();
   
    // Only start the polling manager if we are configured to use MakeConnection
    if(polling && pollMgr == null) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.makeConnectionDisabled);
      throw new SandeshaException(message);
    }

    if(sequence instanceof RMSBean) {
      // We pass in the internal sequence id for internal sequences.
      String sequenceId = ((RMSBean)sequence).getInternalSequenceID();
      sender.runThreadForSequence(context, sequenceId, true);
      if(polling) pollMgr.runThreadForSequence(context, sequenceId, true);
    } else {
      String sequenceId = sequence.getSequenceID();
      sender.runThreadForSequence(context, sequenceId, false);
      if(invoker != null) invoker.runThreadForSequence(context, sequenceId, false);
      if(polling) pollMgr.runThreadForSequence(context, sequenceId, false);
    }
   
    if (log.isDebugEnabled()) log.debug("Exit: SandeshaUtil::startWorkersForSequence");
  }

  public static String getMessageTypeString(int messageType) {
    switch (messageType) {
    case Sandesha2Constants.MessageTypes.CREATE_SEQ:
      return "CreateSequence";
    case Sandesha2Constants.MessageTypes.CREATE_SEQ_RESPONSE:
      return "CreateSequenceResponse";
    case Sandesha2Constants.MessageTypes.ACK:
      return "Acknowledgement";
    case Sandesha2Constants.MessageTypes.APPLICATION:
      return "Application";
    case Sandesha2Constants.MessageTypes.TERMINATE_SEQ:
      return "TerminateSequence";
    case Sandesha2Constants.MessageTypes.ACK_REQUEST:
      return "AckRequest";
    case Sandesha2Constants.MessageTypes.CLOSE_SEQUENCE:
      return "CloseSequence";
    case Sandesha2Constants.MessageTypes.CLOSE_SEQUENCE_RESPONSE:
      return "CloseSequenceResponse";
    case Sandesha2Constants.MessageTypes.TERMINATE_SEQ_RESPONSE:
      return "TerminateSequenceResponse";
    case Sandesha2Constants.MessageTypes.FAULT_MSG:
      return "Fault";
    case Sandesha2Constants.MessageTypes.MAKE_CONNECTION_MSG:
      return "MakeConnection";
    case Sandesha2Constants.MessageTypes.UNKNOWN:
      return "Unknown";
    default:
      return "Error";
    }
  }

  public static String getServerSideIncomingSeqIdFromInternalSeqId(String internalSequenceId)
      throws SandeshaException {

    String startStr = Sandesha2Constants.INTERNAL_SEQUENCE_PREFIX + ":";
    if (!internalSequenceId.startsWith(startStr)) {
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.invalidInternalSequenceID,
          internalSequenceId));
    }

    String incomingSequenceId = internalSequenceId.substring(startStr.length());
    return incomingSequenceId;
  }

  /**
   * Used to obtain the storage Manager Implementation.
   *
   * @param context
   * @return
   * @throws SandeshaException
   */
  public static StorageManager getSandeshaStorageManager(ConfigurationContext context,AxisDescription description) throws SandeshaException {

    Parameter parameter = description.getParameter(Sandesha2Constants.STORAGE_MANAGER_PARAMETER);
    if (parameter==null) {
      parameter = new Parameter (Sandesha2Constants.STORAGE_MANAGER_PARAMETER,Sandesha2Constants.DEFAULT_STORAGE_MANAGER);
    }
   
    String value = (String) parameter.getValue();
   
    if (Sandesha2Constants.INMEMORY_STORAGE_MANAGER.equals(value))
      return getInMemoryStorageManager(context);
    else if (Sandesha2Constants.PERMANENT_STORAGE_MANAGER.equals(value))
      return getPermanentStorageManager(context);
    else
      throw new SandeshaException (SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotGetStorageManager));
  }
 
  public static StorageManager getInMemoryStorageManager(ConfigurationContext context) throws SandeshaException {

    StorageManager inMemoryStorageManager = null;
   
    AxisConfiguration config = context.getAxisConfiguration();
    Parameter parameter = config.getParameter(Sandesha2Constants.INMEMORY_STORAGE_MANAGER);
    if(parameter != null) inMemoryStorageManager = (StorageManager) parameter.getValue();
    if (inMemoryStorageManager != nullreturn inMemoryStorageManager;

    try {
      //Currently module policies (default) are used to find the storage manager. These cant be overriden
      //TODO change this so that different services can hv different storage managers.
      String storageManagerClassStr = getDefaultPropertyBean(context.getAxisConfiguration()).getInMemoryStorageManagerClass();
      inMemoryStorageManager = getStorageManagerInstance(storageManagerClassStr,context);
      parameter = new Parameter(Sandesha2Constants.INMEMORY_STORAGE_MANAGER, inMemoryStorageManager);
      config.addParameter(parameter);
    } catch(AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotInitInMemoryStorageManager,
          e.toString());
      throw new SandeshaException(message, e);
    }
   
    return inMemoryStorageManager;
  }
 
  public static StorageManager getPermanentStorageManager(ConfigurationContext context) throws SandeshaException {

    StorageManager permanentStorageManager = null;
   
    AxisConfiguration config = context.getAxisConfiguration();
    Parameter parameter = config.getParameter(Sandesha2Constants.PERMANENT_STORAGE_MANAGER);
    if(parameter != null) permanentStorageManager = (StorageManager) parameter.getValue();
    if (permanentStorageManager != nullreturn permanentStorageManager;

    try {
      //Currently module policies (default) are used to find the storage manager. These cant be overriden
      //TODO change this so that different services can hv different storage managers.
      String storageManagerClassStr = getDefaultPropertyBean(context.getAxisConfiguration()).getPermanentStorageManagerClass();
      permanentStorageManager = getStorageManagerInstance(storageManagerClassStr,context);
      parameter = new Parameter(Sandesha2Constants.PERMANENT_STORAGE_MANAGER, permanentStorageManager);
      config.addParameter(parameter);
    } catch(AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotInitPersistentStorageManager,
          e.toString());
      throw new SandeshaException(message, e);
    }
   
    return permanentStorageManager;
  }
 
  private static StorageManager getStorageManagerInstance (String className,ConfigurationContext context) throws SandeshaException {
   
    StorageManager storageManager = null;
    try {
      ClassLoader classLoader = null;
      AxisConfiguration config = context.getAxisConfiguration();
      Parameter classLoaderParam = config.getParameter(Sandesha2Constants.MODULE_CLASS_LOADER);
      if(classLoaderParam != null) classLoader = (ClassLoader) classLoaderParam.getValue();

        if (classLoader==null)
          throw new SandeshaException (SandeshaMessageHelper.getMessage(
              SandeshaMessageKeys.classLoaderNotFound));
       
        Class c = classLoader.loadClass(className);
      Class configContextClass = context.getClass();
     
      Constructor constructor = c.getConstructor(new Class[] { configContextClass });
      Object obj = constructor.newInstance(new Object[] {context});

      if (obj == null || !(obj instanceof StorageManager))
        throw new SandeshaException(SandeshaMessageHelper.getMessage(
            SandeshaMessageKeys.storageManagerMustImplement));

      StorageManager mgr = (StorageManager) obj;
      storageManager = mgr;
      return storageManager;
     
    } catch (Exception e) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.cannotGetStorageManager);
      if (log.isErrorEnabled())
        log.error(message, e);
      throw new SandeshaException(message,e);
    }
  }

  public static int getSOAPVersion(SOAPEnvelope envelope) throws SandeshaException {
    String namespaceName = envelope.getNamespace().getNamespaceURI();
    if (namespaceName.equals(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI))
      return Sandesha2Constants.SOAPVersion.v1_1;
    else if (namespaceName.equals(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI))
      return Sandesha2Constants.SOAPVersion.v1_2;
    else
      throw new SandeshaException(SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.unknownSoapVersion,
          namespaceName));
  }


  public static MessageContext createNewRelatedMessageContext(RMMsgContext referenceRMMessage, AxisOperation operation)
      throws SandeshaException {
    try {
      MessageContext referenceMessage = referenceRMMessage.getMessageContext();
      ConfigurationContext configContext = referenceMessage.getConfigurationContext();
      AxisConfiguration axisConfiguration = configContext.getAxisConfiguration();

      MessageContext newMessageContext = new MessageContext();
      newMessageContext.setConfigurationContext(configContext);
     
      Options oldOptions = referenceMessage.getOptions();
            Options newOptions = new Options ();
            newOptions.setProperties(oldOptions.getProperties());
     
      newMessageContext.setOptions(newOptions);
     
      if (referenceMessage.getAxisServiceGroup() != null) {
        newMessageContext.setAxisServiceGroup(referenceMessage.getAxisServiceGroup());
       
        if (referenceMessage.getServiceGroupContext()!=null) {
          newMessageContext.setServiceGroupContext(referenceMessage.getServiceGroupContext());
          newMessageContext.setServiceGroupContextId(referenceMessage.getServiceGroupContextId());
        } else {
          ServiceGroupContext serviceGroupContext = new ServiceGroupContext (
              configContext,referenceMessage.getAxisServiceGroup());
          newMessageContext.setServiceGroupContext(serviceGroupContext);
        }
      } else {
        AxisServiceGroup axisServiceGroup = new AxisServiceGroup(axisConfiguration);
        ServiceGroupContext serviceGroupContext = new ServiceGroupContext(configContext, axisServiceGroup);

        newMessageContext.setAxisServiceGroup(axisServiceGroup);
        newMessageContext.setServiceGroupContext(serviceGroupContext);
      }

      if (referenceMessage.getAxisService() != null) {
        newMessageContext.setAxisService(referenceMessage.getAxisService());
       
        if (referenceMessage.getServiceContext()!=null) {
          newMessageContext.setServiceContext(referenceMessage.getServiceContext());
          newMessageContext.setServiceContextID(referenceMessage.getServiceContextID());
        } else {
          ServiceGroupContext sgc = newMessageContext.getServiceGroupContext();
          ServiceContext serviceContext = sgc.getServiceContext(referenceMessage.getAxisService());
          newMessageContext.setServiceContext(serviceContext);
        }
      }

      newMessageContext.setAxisOperation(operation);

      //The message created will basically be used as a outMessage, so setting the AxisMessage accordingly
      newMessageContext.setAxisMessage(operation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE));
     
      OperationContext operationContext = OperationContextFactory.createOperationContext(operation.getAxisSpecificMEPConstant(), operation, newMessageContext.getServiceContext());
      newMessageContext.setOperationContext(operationContext);
      operationContext.addMessageContext(newMessageContext);

      // adding a blank envelope
      SOAPFactory factory = SOAPAbstractFactory.getSOAPFactory(SandeshaUtil.getSOAPVersion(referenceMessage
          .getEnvelope()));
      newMessageContext.setEnvelope(factory.getDefaultEnvelope());

      newMessageContext.setTransportIn(referenceMessage.getTransportIn());
      newMessageContext.setTransportOut(referenceMessage.getTransportOut());

      // copying transport info.
      newMessageContext.setProperty(MessageContext.TRANSPORT_OUT, referenceMessage
          .getProperty(MessageContext.TRANSPORT_OUT));

      newMessageContext.setProperty(Constants.OUT_TRANSPORT_INFO, referenceMessage
          .getProperty(Constants.OUT_TRANSPORT_INFO));
      newMessageContext.setProperty(MessageContext.TRANSPORT_HEADERS, referenceMessage
          .getProperty(MessageContext.TRANSPORT_HEADERS));
      newMessageContext.setProperty(MessageContext.TRANSPORT_IN, referenceMessage
          .getProperty(MessageContext.TRANSPORT_IN));
      newMessageContext.setProperty(MessageContext.TRANSPORT_OUT, referenceMessage
          .getProperty(MessageContext.TRANSPORT_OUT));
     
      newMessageContext.setProperty(AddressingConstants.WS_ADDRESSING_VERSION,
          referenceMessage.getProperty(AddressingConstants.WS_ADDRESSING_VERSION));
      newMessageContext.setProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES,
          referenceMessage.getProperty(AddressingConstants.DISABLE_ADDRESSING_FOR_OUT_MESSAGES));
     
      copyConfiguredProperties (referenceMessage,newMessageContext);

      //copying the serverSide property
      newMessageContext.setServerSide(referenceMessage.isServerSide());
     
      //this had to be set here to avoid a double invocation.
      if (oldOptions!=null)
        newOptions.setUseSeparateListener(oldOptions.isUseSeparateListener());
     
      return newMessageContext;

    } catch (AxisFault e) {
      log.debug(e.getMessage());
      throw new SandeshaException(e.getMessage());
    }

  }
 

  private static void copyConfiguredProperties (MessageContext fromMessage, MessageContext toMessage) throws AxisFault {

//    copying properties as configured in the module.xml properties. Module xml has several
    //properties which gives comma seperated lists of property names that have to be copited
    //from various places when creating related messages.
   
    if (axisModule==null) {
      String message = SandeshaMessageKeys.moduleNotSet;
      throw new SandeshaException (message);
    }
   
    Parameter propertiesFromRefMsg = axisModule.getParameter(Sandesha2Constants.propertiesToCopyFromReferenceMessage);
    if (propertiesFromRefMsg!=null) {
      String value = (String) propertiesFromRefMsg.getValue();
      if (value!=null) {
        value = value.trim();
        String[] propertyNames = value.split(",");
        for (int i=0;i<propertyNames.length;i++) {
          String tmp = propertyNames[i];
          String propertyName = null;
          String targetPropertyName = null;
          if (tmp.indexOf (":")>=0) {
            //if the property name is given as two values seperated by a colon, this gives the key of the from msg
            //and the key for the To Msg respsctively.
            String[] vals = tmp.split(":");
            propertyName = vals[0].trim();
            targetPropertyName = vals[1].trim();
          } else {
            propertyName = targetPropertyName = tmp;
          }
         
          Object val = fromMessage.getProperty(propertyName);
          if (val!=null) {
            toMessage.setProperty(targetPropertyName,val);
          }
        }
      }
    }
   
    Parameter propertiesFromRefReqMsg = axisModule.getParameter(Sandesha2Constants.propertiesToCopyFromReferenceRequestMessage);
    OperationContext referenceOpCtx = fromMessage.getOperationContext();
    MessageContext referenceRequestMessage = null;
    if (referenceOpCtx!=null)
      referenceRequestMessage=referenceOpCtx.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
   
    if (propertiesFromRefReqMsg!=null && referenceRequestMessage!=null) {
      String value = (String) propertiesFromRefReqMsg.getValue();
      if (value!=null) {
        value = value.trim();
        String[] propertyNames = value.split(",");
        for (int i=0;i<propertyNames.length;i++) {
          String propertyName = propertyNames[i];
          Object val = referenceRequestMessage.getProperty(propertyName);
          if (val!=null) {
            toMessage.setProperty(propertyName,val);
          }
        }
      }
    }

   
  }
 
  public static SandeshaPolicyBean getDefaultPropertyBean (AxisConfiguration axisConfiguration) throws SandeshaException {
    Parameter parameter = axisConfiguration.getParameter(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
    if (parameter==null)
      throw new SandeshaException (SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.defaultPropertyBeanNotSet));
   
    SandeshaPolicyBean sandeshaPropertyBean = (SandeshaPolicyBean) parameter.getValue();
    return sandeshaPropertyBean;
  }

  //TODO change this method.
  public static ArrayList getArrayListFromString(String str) {

    if (str == null || "".equals(str))
      return new ArrayList();

    if (str.length() < 2) {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.invalidStringArray,
          str);
      log.debug(message);
      throw new IllegalArgumentException (message);
    }

    int length = str.length();

    if (str.charAt(0) != '[' || str.charAt(length - 1) != ']') {
      String message = SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.invalidStringArray, str);
      log.debug(message);
      throw new IllegalArgumentException(message);
    }

    ArrayList retArr = new ArrayList();

    String subStr = str.substring(1, length - 1);

    String[] parts = subStr.split(",");

    for (int i = 0; i < parts.length; i++) {
      if (!"".equals(parts[i]))
        retArr.add(parts[i].trim());
    }

    return retArr;
  }

  public static String getInternalSequenceID(String to, String sequenceKey) {
    if (to == null && sequenceKey == null)
      return null;
    else if (to == null)
      return sequenceKey;
    else if (sequenceKey == null)
      return to;
    else
      return Sandesha2Constants.INTERNAL_SEQUENCE_PREFIX + ":" + to + ":" + sequenceKey;
  }

  public static String getOutgoingSideInternalSequenceID(String sequenceID) {
    return Sandesha2Constants.INTERNAL_SEQUENCE_PREFIX + ":" + sequenceID;
  }

  public static final RMSBean getRMSBeanFromInternalSequenceId(StorageManager storageManager, String internalSequenceID)
 
  throws SandeshaException {
    RMSBeanMgr rmsBeanMgr = storageManager.getRMSBeanMgr();
    RMSBean bean = new RMSBean();
    bean.setInternalSequenceID(internalSequenceID);
   
    bean = rmsBeanMgr.findUnique(bean);

    return bean;
  }
 
  public static final RMSBean getRMSBeanFromSequenceId(StorageManager storageManager, String sequenceID)
 
  throws SandeshaException {
    RMSBeanMgr rmsBeanMgr = storageManager.getRMSBeanMgr();
    RMSBean bean = new RMSBean();
    bean.setSequenceID(sequenceID);
   
    bean = rmsBeanMgr.findUnique(bean);

    return bean;
  }

  public static RMDBean getRMDBeanFromSequenceId(StorageManager storageManager, String sequenceID)
 
  throws SandeshaException {
    RMDBeanMgr rmdBeanMgr = storageManager.getRMDBeanMgr();
    RMDBean bean = new RMDBean();
    bean.setSequenceID(sequenceID);
   
    bean = rmdBeanMgr.findUnique(bean);

    return bean;
  }

  public static String getSequenceIDFromInternalSequenceID(String internalSequenceID,
      StorageManager storageManager) throws SandeshaException {

    RMSBean rMSBean = getRMSBeanFromInternalSequenceId(storageManager, internalSequenceID);

    String sequeunceID = null;
    if (rMSBean != null &&
        rMSBean.getSequenceID() != null &&
        !rMSBean.getSequenceID().equals(Sandesha2Constants.TEMP_SEQUENCE_ID))
      sequeunceID = rMSBean.getSequenceID();

    return sequeunceID;
  }

  public static String getExecutionChainString(ArrayList executionChain) {
    Iterator iter = executionChain.iterator();

    String executionChainStr = "";
    while (iter.hasNext()) {
      Handler handler = (Handler) iter.next();
      String name = handler.getName();
      executionChainStr = executionChainStr + Sandesha2Constants.EXECUTIN_CHAIN_SEPERATOR + name;
    }

    return executionChainStr;
  }

  public static boolean isAllMsgsAckedUpto(long highestInMsgNo, String internalSequenceId,
      StorageManager storageManager) throws SandeshaException {

    RMSBean rmsBean = SandeshaUtil.getRMSBeanFromInternalSequenceId(storageManager, internalSequenceId);
   
    RangeString ackedMsgRanges = rmsBean.getClientCompletedMessages();
    long smallestMsgNo = 1;
    Range interestedRange = new Range(smallestMsgNo, highestInMsgNo);
    boolean allComplete = false;
    if(ackedMsgRanges!=null && ackedMsgRanges.isRangeCompleted(interestedRange)){
      allComplete = true;
    }
    return allComplete;
 
  }
 
  public static SandeshaPolicyBean getPropertyBean (AxisDescription axisDescription) throws SandeshaException {
    Parameter parameter = axisDescription.getParameter(Sandesha2Constants.SANDESHA_PROPERTY_BEAN);
    if (parameter==null)
      throw new SandeshaException (SandeshaMessageHelper.getMessage(
          SandeshaMessageKeys.propertyBeanNotSet));
   
    SandeshaPolicyBean propertyBean = (SandeshaPolicyBean) parameter.getValue();
    if (propertyBean==null) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.policyBeanNotFound);
      throw new SandeshaException (message);
    }

    return propertyBean;
  }

  public static String getSequenceIDFromRMMessage(RMMsgContext rmMessageContext) throws SandeshaException {
    int messageType = rmMessageContext.getMessageType();

    String sequenceID = null;
    if (messageType == Sandesha2Constants.MessageTypes.APPLICATION) {
      Sequence sequence = (Sequence) rmMessageContext.getMessagePart(Sandesha2Constants.MessageParts.SEQUENCE);
      sequenceID = sequence.getIdentifier().getIdentifier();
    } else if (messageType == Sandesha2Constants.MessageTypes.ACK) {
      Iterator sequenceAckIter = rmMessageContext
          .getMessageParts(Sandesha2Constants.MessageParts.SEQ_ACKNOWLEDGEMENT);
     
      //In case of ack messages sequenceId is decided based on the sequenceId of the first
      //sequence Ack. In other words Sandesha2 does not expect to receive two SequenceAcknowledgements
      //of different RM specifications in the same incoming message.
     
      SequenceAcknowledgement sequenceAcknowledgement = (SequenceAcknowledgement) sequenceAckIter.next();
      sequenceID = sequenceAcknowledgement.getIdentifier().getIdentifier();
    } else if (messageType == Sandesha2Constants.MessageTypes.ACK_REQUEST) {
      Iterator ackRequestIter = rmMessageContext
          .getMessageParts(Sandesha2Constants.MessageParts.ACK_REQUEST);
 
      //In case of ack request messages sequenceId is decided based on the sequenceId of the first
      //AckRequested.
     
      AckRequested ackReq = (AckRequested) ackRequestIter.next();
      sequenceID = ackReq.getIdentifier().getIdentifier();
    } else if (messageType == Sandesha2Constants.MessageTypes.CLOSE_SEQUENCE) {
      CloseSequence closeSequence = (CloseSequence) rmMessageContext
          .getMessagePart(Sandesha2Constants.MessageParts.CLOSE_SEQUENCE);
      sequenceID = closeSequence.getIdentifier().getIdentifier();
    } else if (messageType == Sandesha2Constants.MessageTypes.CLOSE_SEQUENCE_RESPONSE) {
      CloseSequenceResponse closeSequenceResponse = (CloseSequenceResponse) rmMessageContext
          .getMessagePart(Sandesha2Constants.MessageParts.CLOSE_SEQUENCE_RESPONSE);
      sequenceID = closeSequenceResponse.getIdentifier().getIdentifier();
    }

    // TODO complete for other message types

    return sequenceID;
  }
 
  public static String getSequenceKeyFromInternalSequenceID(String internalSequenceID, String to){
    if(to==null){
      //sequenceKey is just the internalSequenceID
      return internalSequenceID;
    }
    else{
      //remove the prefix
      int postPrefixStringIndex = internalSequenceID.indexOf(Sandesha2Constants.INTERNAL_SEQUENCE_PREFIX);
      if(postPrefixStringIndex>=0){
        String postPrefixString = internalSequenceID.substring(postPrefixStringIndex + Sandesha2Constants.INTERNAL_SEQUENCE_PREFIX.length());
        //strip of the to epr and trailing and trailing ":"
        String toEPRString = ":" + to + ":";
        int indexOfToEPR = postPrefixString.indexOf(toEPRString);
        if(indexOfToEPR>=0){
          return postPrefixString.substring(indexOfToEPR + toEPRString.length());
        }
      }
    }
    return null; //could not find the sequenceKey
  }
 

  public static SecurityManager getSecurityManager(ConfigurationContext context) throws SandeshaException {
    SecurityManager util = null;
    AxisConfiguration config = context.getAxisConfiguration();
    Parameter p = config.getParameter(Sandesha2Constants.SECURITY_MANAGER);
    if(p != null) util = (SecurityManager) p.getValue();
    if (util != null) return util;

    try {
      //Currently module policies are used to find the security impl. These cant be overriden
      String securityManagerClassStr = getDefaultPropertyBean(context.getAxisConfiguration()).getSecurityManagerClass();
      util = getSecurityManagerInstance(securityManagerClassStr,context);
      p = new Parameter(Sandesha2Constants.SECURITY_MANAGER,util);
      config.addParameter(p);
    } catch(AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotInitSecurityManager, e.toString());
      throw new SandeshaException(message,e);
    }
    return util;
  }

  private static SecurityManager getSecurityManagerInstance (String className,ConfigurationContext context) throws SandeshaException {
    try {
      ClassLoader classLoader = null;
      AxisConfiguration config = context.getAxisConfiguration();
      Parameter classLoaderParam = config.getParameter(Sandesha2Constants.MODULE_CLASS_LOADER);
      if(classLoaderParam != null) classLoader = (ClassLoader) classLoaderParam.getValue();

      if (classLoader==null)
        throw new SandeshaException (SandeshaMessageHelper.getMessage(SandeshaMessageKeys.classLoaderNotFound));
       
      Class c = classLoader.loadClass(className);
      Class configContextClass = context.getClass();
     
      Constructor constructor = c.getConstructor(new Class[] { configContextClass });
      Object obj = constructor.newInstance(new Object[] {context});

      if (!(obj instanceof SecurityManager)) {
        String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.securityManagerMustImplement, className);
        throw new SandeshaException(message);
      }
      return (SecurityManager) obj;
     
    } catch (Exception e) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotInitSecurityManager, e.toString());
      throw new SandeshaException(message,e);
    }
  }
 
  public static ContextManager getContextManager(ConfigurationContext context) throws SandeshaException {
    ContextManager mgr = null;
    AxisConfiguration config = context.getAxisConfiguration();
    Parameter p = config.getParameter(Sandesha2Constants.CONTEXT_MANAGER);
    if(p != null) mgr = (ContextManager) p.getValue();
    if (mgr != null) return mgr;

    try {
      //Currently module policies are used to find the context impl. These cant be overriden
      String securityManagerClassStr = getDefaultPropertyBean(context.getAxisConfiguration()).getContextManagerClass();
      mgr = getContextManagerInstance(securityManagerClassStr,context);
      p = new Parameter(Sandesha2Constants.CONTEXT_MANAGER,mgr);
      config.addParameter(p);
    } catch(AxisFault e) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotInitContextManager, e.toString());
      throw new SandeshaException(message,e);
    }
    return mgr;
  }

  private static ContextManager getContextManagerInstance(String className,ConfigurationContext context) throws SandeshaException {
    try {
      ClassLoader classLoader = null;
      AxisConfiguration config = context.getAxisConfiguration();
      Parameter classLoaderParam = config.getParameter(Sandesha2Constants.MODULE_CLASS_LOADER);
      if(classLoaderParam != null) classLoader = (ClassLoader) classLoaderParam.getValue();

      if (classLoader==null)
        throw new SandeshaException (SandeshaMessageHelper.getMessage(SandeshaMessageKeys.classLoaderNotFound));
       
      Class c = classLoader.loadClass(className);
      Class configContextClass = context.getClass();
     
      Constructor constructor = c.getConstructor(new Class[] { configContextClass });
      Object obj = constructor.newInstance(new Object[] {context});

      if (!(obj instanceof ContextManager)) {
        String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.contextManagerMustImplement, className);
        throw new SandeshaException(message);
      }
      return (ContextManager) obj;
     
    } catch (Exception e) {
      String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cannotInitContextManager, e.toString());
      throw new SandeshaException(message,e);
    }
  }

  public static boolean isWSRMAnonymous(String address) {
    if (address!=null && address.startsWith(Sandesha2Constants.SPEC_2007_02.ANONYMOUS_URI_PREFIX))
      return true;
    else
      return false;
  }
  public static void executeAndStore (RMMsgContext rmMsgContext, String storageKey) throws AxisFault {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaUtil::executeAndStore, " + storageKey);
   
    MessageContext msgContext = rmMsgContext.getMessageContext();
    ConfigurationContext configurationContext = msgContext.getConfigurationContext();

    SandeshaPolicyBean policy = getPropertyBean(msgContext.getAxisOperation());
    if(policy.isUseMessageSerialization()) {
      msgContext.setProperty(Sandesha2Constants.QUALIFIED_FOR_SENDING, Sandesha2Constants.VALUE_TRUE);

      StorageManager store = getSandeshaStorageManager(configurationContext, configurationContext.getAxisConfiguration());
      store.storeMessageContext(storageKey, msgContext);
     
    } else {
      // message will be stored in the Sandesha2TransportSender
      msgContext.setProperty(Sandesha2Constants.MESSAGE_STORE_KEY, storageKey);
 
      TransportOutDescription transportOut = msgContext.getTransportOut();
 
      msgContext.setProperty(Sandesha2Constants.ORIGINAL_TRANSPORT_OUT_DESC, transportOut);
      msgContext.setProperty(Sandesha2Constants.SET_SEND_TO_TRUE, Sandesha2Constants.VALUE_TRUE);
 
      Sandesha2TransportOutDesc sandesha2TransportOutDesc = new Sandesha2TransportOutDesc();
      msgContext.setTransportOut(sandesha2TransportOutDesc);
 
       // sending the message once through Sandesha2TransportSender.
      if (msgContext.isPaused())
        AxisEngine.resumeSend(msgContext);
      else {
        //this invocation has to be a blocking one.
       
        Boolean isTransportNonBlocking = (Boolean) msgContext.getProperty(MessageContext.TRANSPORT_NON_BLOCKING);
        if (isTransportNonBlocking!=null && isTransportNonBlocking.booleanValue())
          msgContext.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, Boolean.FALSE);
       
        AxisEngine.send(msgContext);
       
        msgContext.setProperty(MessageContext.TRANSPORT_NON_BLOCKING, isTransportNonBlocking);
      }
    }
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaUtil::executeAndStore");
  }
 
  public static void modifyExecutionChainForStoring (MessageContext message)
  throws SandeshaException
  {
   
    Object property = message.getProperty(Sandesha2Constants.RETRANSMITTABLE_PHASES);
    if (property!=null)
      return; //Phases are already set. Dont hv to redo.
   
    SandeshaPolicyBean policy = getPropertyBean(message.getAxisOperation());
    if(policy.isUseMessageSerialization())
      return; // No need to mess with the transport when we use message serialization
   
    TransportOutDescription transportOutDescription = message.getTransportOut();
    if (!(transportOutDescription instanceof Sandesha2TransportOutDesc))
      return; //This message is aimed to be stored only if, Sandesha2TransportOutDescription is set.
   
    ArrayList executionChain = message.getExecutionChain();
    ArrayList retransmittablePhaseNames = getRetransmittablePhaseNameList();
    ArrayList retransmittablePhases = new ArrayList ();
   
    for (Iterator it=executionChain.iterator();it.hasNext();) {
      Handler handler = (Handler) it.next();
     
      if (retransmittablePhaseNames.contains(handler.getName())) {
        retransmittablePhases.add(handler);
       
        it.remove();
      }
    }
   
    message.setProperty(Sandesha2Constants.RETRANSMITTABLE_PHASES, retransmittablePhases);
  }
 
  private static ArrayList getRetransmittablePhaseNameList () {
   
    //TODO get this phase list from a property
   
    String security = "Security";
   
    ArrayList phases = new ArrayList ();
    phases.add(security);
   
    return phases;
  }
 
  public static MessageContext cloneMessageContext (MessageContext oldMsg) throws AxisFault {
    MessageContext newMsg = new MessageContext ();
    newMsg.setOptions(new Options (oldMsg.getOptions()));
   
   
    //TODO hd to use following hack since a 'clone' method was not available for SOAPEnvelopes.
    //Do it the correct way when that becomes available.
    OMElement newElement = oldMsg.getEnvelope().cloneOMElement();
    String elementString = newElement.toString();
   
    try {
      ByteArrayInputStream stream = new ByteArrayInputStream(
          elementString.getBytes("UTF8"));
      StAXSOAPModelBuilder builder = new StAXSOAPModelBuilder(
          XMLInputFactory.newInstance().createXMLStreamReader(stream),
          null);
      SOAPEnvelope envelope = builder.getSOAPEnvelope();

      newMsg.setEnvelope(envelope);
    } catch (XMLStreamException e) {
      throw AxisFault.makeFault(e);
    } catch (UnsupportedEncodingException e) {
      throw AxisFault.makeFault(e);
    }
   
    newMsg.setConfigurationContext(oldMsg.getConfigurationContext());
    newMsg.setAxisService(oldMsg.getAxisService());
    newMsg.setTransportOut(oldMsg.getTransportOut());
    newMsg.setTransportIn(oldMsg.getTransportIn());
   
    //Copy property objects from oldMsg to newMsg
    copyConfiguredProperties(oldMsg,newMsg);
   
    return newMsg;
   
  }

  /**
   * Remove the MustUnderstand header blocks.
   * @param envelope
   */
  public static SOAPEnvelope removeMustUnderstand(SOAPEnvelope envelope) {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaUtil::removeMustUnderstand");
    // you have to explicitely set the 'processed' attribute for header
    // blocks, since it get lost in the above read from the stream.

    SOAPHeader header = envelope.getHeader();
    if (header != null) {
      Iterator childrenOfOldEnv = header.getChildElements();
      while (childrenOfOldEnv.hasNext()) {
       
        SOAPHeaderBlock oldEnvHeaderBlock = (SOAPHeaderBlock) childrenOfOldEnv.next();

        QName oldEnvHeaderBlockQName = oldEnvHeaderBlock.getQName();
        if (oldEnvHeaderBlockQName != null) {
          // If we've processed the part and it has a must understand, set it as processed
          if (oldEnvHeaderBlock.isProcessed() && oldEnvHeaderBlock.getMustUnderstand()) {
            // Remove the MustUnderstand part
            oldEnvHeaderBlock.setMustUnderstand(false);
          }
        }
      }
    }
   
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaUtil::removeMustUnderstand");
    return envelope;
  }

  public static EndpointReference cloneEPR (EndpointReference epr) {
    EndpointReference newEPR = new EndpointReference (epr.getAddress());
    Map referenceParams = epr.getAllReferenceParameters();
   
    if (referenceParams != null) {
      for (Iterator keys = referenceParams.keySet().iterator(); keys
          .hasNext();) {
        Object key = keys.next();
        Object referenceParam = referenceParams.get(key);

        if (referenceParam instanceof OMElement) {
          OMElement clonedElement = ((OMElement) referenceParam)
              .cloneOMElement();
          clonedElement.setText("false");
          newEPR.addReferenceParameter(clonedElement);
        }
      }
    }
   
    return newEPR;
 
 
  public static boolean isMessageUnreliable(MessageContext mc) {
    if(log.isDebugEnabled()) log.debug("Entry: SandeshaUtil::isMessageUnreliable");
    boolean result = false;

    //look at the msg ctx first
    String unreliable = (String) mc.getProperty(SandeshaClientConstants.UNRELIABLE_MESSAGE);
    if ("true".equals(unreliable)) {
      if (log.isDebugEnabled()) log.debug("Unreliable message context");
      result = true;
    }     
   
    if(!result) {
      //look at the operation
      if (mc.getAxisOperation() != null) {
        Parameter unreliableParam = mc.getAxisOperation().getParameter(SandeshaClientConstants.UNRELIABLE_MESSAGE);
        if (null != unreliableParam && "true".equals(unreliableParam.getValue())) {
          if (log.isDebugEnabled()) log.debug("Unreliable operation");
          result = true;
        }
      }
    }
   
    if(log.isDebugEnabled()) log.debug("Exit: SandeshaUtil::isMessageUnreliable, " + result);
    return result;
  }
 
 
  public static boolean isDuplicateInOnlyMessage(MessageContext msgContext)
  {
    AxisOperation operation = msgContext.getAxisOperation();
    String localName = operation.getName().getLocalPart();
    if(localName.equals(Sandesha2Constants.RM_DUPLICATE_IN_ONLY_OPERATION.getLocalPart())){
      return true;
    }
    else return false;
  }
 
  public static boolean isDuplicateInOutMessage(MessageContext msgContext)
  {
    AxisOperation operation = msgContext.getAxisOperation();
    String localName = operation.getName().getLocalPart();
    if(localName.equals(Sandesha2Constants.RM_DUPLICATE_IN_OUT_OPERATION.getLocalPart())){
      return true;
    }
    else return false;
 
 
 
  public static SOAPEnvelope cloneEnvelope(SOAPEnvelope envelope) throws SandeshaException {
   
    // Now clone the env and set it in the message context
    XMLStreamReader streamReader = envelope.cloneOMElement().getXMLStreamReader();
    SOAPEnvelope clonedEnvelope = new StAXSOAPModelBuilder(streamReader, null).getSOAPEnvelope();

    // you have to explicitely set the 'processed' attribute for header
    // blocks, since it get lost in the above read from the stream.

    SOAPHeader header = envelope.getHeader();
    if (header != null) {
      Iterator childrenOfOldEnv = header.getChildElements();
      Iterator childrenOfNewEnv = clonedEnvelope.getHeader().getChildElements();
      while (childrenOfOldEnv.hasNext()) {
       
        SOAPHeaderBlock oldEnvHeaderBlock = (SOAPHeaderBlock) childrenOfOldEnv.next();
        SOAPHeaderBlock newEnvHeaderBlock = (SOAPHeaderBlock) childrenOfNewEnv.next();

        QName oldEnvHeaderBlockQName = oldEnvHeaderBlock.getQName();
        if (oldEnvHeaderBlockQName != null) {
          if (oldEnvHeaderBlockQName.equals(newEnvHeaderBlock.getQName())) {
            if (oldEnvHeaderBlock.isProcessed())
              newEnvHeaderBlock.setProcessed();
          } else {
            String message = SandeshaMessageHelper.getMessage(SandeshaMessageKeys.cloneDoesNotMatchToOriginal);
            throw new SandeshaException(message);
          }
        }
      }
    }
   
    return clonedEnvelope;
  }
 
  public static final String getStackTraceFromException(Exception e) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintWriter pw = new PrintWriter(baos);
    e.printStackTrace(pw);
    pw.flush();
    String stackTrace = baos.toString();
    return stackTrace;
  }

  public static EndpointReference rewriteEPR(RMSBean sourceBean, EndpointReference epr, ConfigurationContext configContext)
  throws SandeshaException
  {
    if (log.isDebugEnabled())
      log.debug("Enter: SandeshaUtil::rewriteEPR " + epr);

    SandeshaPolicyBean policy = SandeshaUtil.getPropertyBean(configContext.getAxisConfiguration());
    if(!policy.isEnableRMAnonURI()) {
      if (log.isDebugEnabled())
        log.debug("Exit: SandeshaUtil::rewriteEPR, anon uri is disabled");
      return epr;
    }

    // Handle EPRs that have not yet been set. These are effectively WS-A anon, and therefore
    // we can rewrite them.
    if(epr == null) epr = new EndpointReference(null);
   
    String address = epr.getAddress();
    if(address == null ||
       AddressingConstants.Final.WSA_ANONYMOUS_URL.equals(address) ||
       AddressingConstants.Submission.WSA_ANONYMOUS_URL.equals(address)) {
      // We use the sequence to hold the anonymous uuid, so that messages assigned to the
      // sequence will use the same UUID to identify themselves
      String uuid = sourceBean.getAnonymousUUID();
      if(uuid == null) {
        uuid = Sandesha2Constants.SPEC_2007_02.ANONYMOUS_URI_PREFIX + SandeshaUtil.getUUID();
        sourceBean.setAnonymousUUID(uuid);
      }
     
      if(log.isDebugEnabled()) log.debug("Rewriting EPR with anon URI " + uuid);
      epr.setAddress(uuid);
    }
   
    if (log.isDebugEnabled())
      log.debug("Exit: SandeshaUtil::rewriteEPR " + epr);
    return epr;
  }


}
TOP

Related Classes of org.apache.sandesha2.util.SandeshaUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.