Package com.eviware.soapui.impl.wsdl.support.wsa

Source Code of com.eviware.soapui.impl.wsdl.support.wsa.WsaValidator

/*
*  soapUI, copyright (C) 2004-2011 eviware.com
*
*  soapUI is free software; you can redistribute it and/or modify it under the
*  terms of version 2.1 of the GNU Lesser General Public License as published by
*  the Free Software Foundation.
*
*  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
*  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*  See the GNU Lesser General Public License for more details at gnu.org.
*/

package com.eviware.soapui.impl.wsdl.support.wsa;

import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.AnonymousTypeConfig;
import com.eviware.soapui.impl.wsdl.WsdlOperation;
import com.eviware.soapui.impl.wsdl.panels.teststeps.support.WsaAssertionConfiguration;
import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
import com.eviware.soapui.impl.wsdl.support.wsdl.WsdlUtils;
import com.eviware.soapui.model.testsuite.AssertionError;
import com.eviware.soapui.model.testsuite.AssertionException;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.xml.XmlUtils;

/**
* Validating class for WS Addressing implemented according to WSDL 1.1
* specification
*
* @author dragica.soldo
* @see {@link}http://www.w3.org/TR/2006/WD-ws-addr-wsdl-20060216/#WSDL11MEPS
*/
public class WsaValidator
{
  WsdlMessageExchange messageExchange;
  Element header;
  String wsaVersionNameSpace;
  StringBuilder cumulativeErrorMsg;
  WsaAssertionConfiguration wsaAssertionConfiguration;

  public WsaValidator( WsdlMessageExchange messageExchange, WsaAssertionConfiguration wsaAssertionConfiguration )
  {
    this.messageExchange = messageExchange;
    this.wsaAssertionConfiguration = wsaAssertionConfiguration;
    cumulativeErrorMsg = new StringBuilder();
  }

  public static String getWsaVersion( XmlObject contentObject, SoapVersion soapVersion )
  {
    String wsaVns = null;
    try
    {
      // XmlObject xmlObject = XmlObject.Factory.parse( content );
      XmlObject[] envS = contentObject.selectChildren( soapVersion.getEnvelopeQName() );
      Element envelope = ( Element )envS[0].getDomNode();

      Element hdr = ( Element )SoapUtils.getHeaderElement( contentObject, soapVersion, true ).getDomNode();

      if( !hdr.hasChildNodes() )
      {
        return null;
      }

      String wsaNameSpace = XmlUtils.findPrefixForNamespace( hdr, WsaUtils.WS_A_NAMESPACE_200508 );
      if( wsaNameSpace != null )
      {
        wsaVns = WsaUtils.WS_A_NAMESPACE_200508;
      }
      else
      {
        wsaNameSpace = XmlUtils.findPrefixForNamespace( hdr, WsaUtils.WS_A_NAMESPACE_200408 );
        if( wsaNameSpace != null )
        {
          wsaVns = WsaUtils.WS_A_NAMESPACE_200408;
        }
        else
        {
          wsaNameSpace = XmlUtils.findPrefixForNamespace( envelope, WsaUtils.WS_A_NAMESPACE_200508 );
          if( wsaNameSpace != null )
          {
            wsaVns = WsaUtils.WS_A_NAMESPACE_200508;
          }
          else
          {
            wsaNameSpace = XmlUtils.findPrefixForNamespace( envelope, WsaUtils.WS_A_NAMESPACE_200408 );
            if( wsaNameSpace != null )
            {
              wsaVns = WsaUtils.WS_A_NAMESPACE_200408;
            }
            else
            {
              return null;
            }
          }
        }
      }
    }
    catch( XmlException e )
    {
      SoapUI.logError( e );
    }
    return wsaVns;
  }

  private void validateWsAddressingCommon( String content )
  {
    if( wsaAssertionConfiguration.isAssertTo() )
    {
      Element toNode;
      if( wsaVersionNameSpace != null )
      {
        toNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "To" );
        parseToNode( toNode );
      }
      else
      {
        toNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200508, "To" );
        if( toNode == null )
        {
          toNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200408, "To" );
        }
        parseToNode( toNode );
      }
    }
    // if fault_to is specified check if anonymous allowed; faultTo is never
    // asserted
    Element faultToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "FaultTo" );
    if( faultToNode != null )
    {
      Element addressNode = XmlUtils.getFirstChildElementNS( faultToNode, wsaVersionNameSpace, "Address" );
      if( addressNode != null )
      {
        String faultToAddressValue = XmlUtils.getElementText( addressNode );
        if( !StringUtils.isNullOrEmpty( faultToAddressValue ) )
        {
          // check for anonymous
          if( AnonymousTypeConfig.PROHIBITED.toString().equals( messageExchange.getOperation().getAnonymous() )
              && WsaUtils.isAnonymousAddress( faultToAddressValue, wsaVersionNameSpace ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader FaultTo , Anonymous addresses are prohibited. " );
          }
          else if( AnonymousTypeConfig.REQUIRED.toString().equals(
              ( ( WsdlMessageExchange )messageExchange ).getOperation().getAnonymous() )
              && !( WsaUtils.isAnonymousAddress( faultToAddressValue, wsaVersionNameSpace ) || WsaUtils
                  .isNoneAddress( faultToAddressValue, wsaVersionNameSpace ) ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader FaultTo , Anonymous addresses are required. " );
          }
        }
      }
    }

  }

  private void parseToNode( Element toNode )
  {
    if( toNode == null )
    {
      cumulativeErrorMsg.append( "WS-A To property is not specified. " );
    }
    else
    {
      String toAddressValue = XmlUtils.getElementText( toNode );
      if( StringUtils.isNullOrEmpty( toAddressValue ) )
      {
        cumulativeErrorMsg.append( "WS-A To property is empty. " );
      }
      else
      {
        // check for anonymous - in case of mock response to=request.replyTo
        if( AnonymousTypeConfig.PROHIBITED.toString().equals( messageExchange.getOperation().getAnonymous() )
            && WsaUtils.isAnonymousAddress( toAddressValue, wsaVersionNameSpace ) )
        {
          cumulativeErrorMsg.append( "WS-A InvalidAddressingHeader To , Anonymous addresses are prohibited. " );
        }
      }
    }
  }

  public void validateWsAddressingRequest() throws AssertionException, XmlException
  {
    String content = messageExchange.getRequestContent();
    SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

    // XmlObject xmlObject = XmlObject.Factory.parse( content );
    XmlObject xmlObject = XmlUtils.createXmlObject( content );
    header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();

    wsaVersionNameSpace = getWsaVersion( xmlObject, soapVersion );
    // not checking because of possibility of having wsaVersionNamespace
    // specified inside property tag itself
    // if (wsaVersionNameSpace == null)
    // {
    // throw new AssertionException( new AssertionError( "WS-A not enabled" )
    // );
    // }

    WsdlOperation operation = messageExchange.getOperation();

    if( wsaAssertionConfiguration.isAssertAction() )
    {
      assertProperty( "Wsa:Action", "Action" );
    }
    validateWsAddressingCommon( content );
    if( operation.isRequestResponse() )
    {
      if( wsaAssertionConfiguration.isAssertMessageId() )
      {
        // MessageId is Mandatory
        assertProperty( "Wsa:MessageId", "MessageId" );
      }
      if( wsaAssertionConfiguration.isAssertReplyTo() )
      {
        // ReplyTo is Mandatory
        Element replyToNode;
        String currentTagWsaNs;
        if( !StringUtils.isNullOrEmpty( wsaVersionNameSpace ) )
        {
          replyToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "ReplyTo" );
          parseReplyToNode( replyToNode, wsaVersionNameSpace );
        }
        else
        {
          replyToNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200508, "ReplyTo" );
          currentTagWsaNs = WsaUtils.WS_A_NAMESPACE_200508;
          if( replyToNode == null )
          {
            replyToNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200408, "ReplyTo" );
            currentTagWsaNs = WsaUtils.WS_A_NAMESPACE_200408;
          }
          parseReplyToNode( replyToNode, currentTagWsaNs );
        }
      }
    }
    String cumulativeError = cumulativeErrorMsg.toString();
    if( !StringUtils.isNullOrEmpty( cumulativeError ) )
    {
      throw new AssertionException( new AssertionError( cumulativeError ) );
    }
  }

  private void parseReplyToNode( Element replyToNode, String wsaNsStr )
  {
    if( replyToNode == null )
    {
      cumulativeErrorMsg.append( "WS-A ReplyTo property is not specified. " );
    }
    else
    {
      Element addressNode = XmlUtils.getFirstChildElementNS( replyToNode, wsaNsStr, "Address" );
      if( addressNode == null )
      {
        cumulativeErrorMsg.append( "WS-A ReplyTo Address property is not specified. " );
      }
      else
      {
        String replyToAddressValue = XmlUtils.getElementText( addressNode );
        if( StringUtils.isNullOrEmpty( replyToAddressValue ) )
        {
          cumulativeErrorMsg.append( "WS-A ReplyTo Address property is empty. " );
        }
        else
        {
          // check for anonymous
          if( AnonymousTypeConfig.PROHIBITED.toString().equals(
              ( ( WsdlMessageExchange )messageExchange ).getOperation().getAnonymous() )
              && WsaUtils.isAnonymousAddress( replyToAddressValue, wsaNsStr ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader ReplyTo , Anonymous addresses are prohibited. " );
          }
          else if( AnonymousTypeConfig.REQUIRED.toString().equals(
              ( ( WsdlMessageExchange )messageExchange ).getOperation().getAnonymous() )
              && !( WsaUtils.isAnonymousAddress( replyToAddressValue, wsaNsStr ) || WsaUtils.isNoneAddress(
                  replyToAddressValue, wsaNsStr ) ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader ReplyTo , Anonymous addresses are required. " );
          }
        }
      }
    }
  }

  public void validateWsAddressingResponse() throws AssertionException, XmlException
  {
    String content = messageExchange.getResponseContent();
    SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();

    // XmlObject requestXmlObject = XmlObject.Factory.parse(
    // messageExchange.getRequestContent() );
    XmlObject requestXmlObject = XmlUtils.createXmlObject( messageExchange.getRequestContent() );
    // XmlObject xmlObject = XmlObject.Factory.parse( content );
    XmlObject xmlObject = XmlUtils.createXmlObject( content );
    header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();

    wsaVersionNameSpace = getWsaVersion( xmlObject, soapVersion );

    if( wsaAssertionConfiguration.isAssertAction() )
    {
      String defaultWsdlAction = WsdlUtils.getDefaultWsaAction( messageExchange.getOperation(), true );
      // Wsa:Action is assertion text, not property tag
      assertProperty( "Wsa:Action", "Action", defaultWsdlAction );
    }
    validateWsAddressingCommon( content );

    if( wsaAssertionConfiguration.isAssertRelatesTo() )
    {
      // RelatesTo is Mandatory
      Element relatesToNode;
      if( !StringUtils.isNullOrEmpty( wsaVersionNameSpace ) )
      {
        relatesToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "RelatesTo" );
        parseRelatesToNode( soapVersion, requestXmlObject, relatesToNode );
      }
      else
      {
        relatesToNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200508, "RelatesTo" );
        if( relatesToNode == null )
        {
          relatesToNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200408, "RelatesTo" );
        }
        parseRelatesToNode( soapVersion, requestXmlObject, relatesToNode );
      }
    }
    // if fault_to is specified check if anonymous allowed
    Element replyToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "ReplyTo" );
    if( replyToNode != null )
    {
      Element addressNode = XmlUtils.getFirstChildElementNS( replyToNode, wsaVersionNameSpace, "Address" );
      if( addressNode != null )
      {
        String replyToAddressValue = XmlUtils.getElementText( addressNode );
        if( !StringUtils.isNullOrEmpty( replyToAddressValue ) )
        {
          // check for anonymous
          if( AnonymousTypeConfig.PROHIBITED.toString().equals(
              ( ( WsdlMessageExchange )messageExchange ).getOperation().getAnonymous() )
              && WsaUtils.isAnonymousAddress( replyToAddressValue, wsaVersionNameSpace ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader ReplyTo , Anonymous addresses are prohibited. " );
          }
          else if( AnonymousTypeConfig.REQUIRED.toString().equals(
              ( ( WsdlMessageExchange )messageExchange ).getOperation().getAnonymous() )
              && !( WsaUtils.isAnonymousAddress( replyToAddressValue, wsaVersionNameSpace ) || WsaUtils
                  .isNoneAddress( replyToAddressValue, wsaVersionNameSpace ) ) )
          {
            cumulativeErrorMsg
                .append( "WS-A InvalidAddressingHeader ReplyTo , Anonymous addresses are required. " );
          }
        }
      }
    }
    if( wsaAssertionConfiguration.isAssertReplyToRefParams() )
    {
      // check if request ReplyTo ReferenceParameters are included in
      // response
      NodeList requestReplyToRefProps = WsdlUtils.getRequestReplyToRefProps( messageExchange,
          getWsaVersion( requestXmlObject, soapVersion ) );
      for( int i = 0; i < requestReplyToRefProps.getLength(); i++ )
      {
        Node refProp = requestReplyToRefProps.item( i );
        String refPropName = refProp.getNodeName();
        NodeList existingResponseRefs = XmlUtils.getChildElementsByTagName( header, refPropName );
        if( existingResponseRefs != null && existingResponseRefs.getLength() > 0 )
        {
          // TODO check if tag is well formed: wsa:IsReferenceParameter
          continue;
        }
        else
        {
          cumulativeErrorMsg.append( "Response does not have request ReferenceProperty " + refPropName + ". " );
        }

      }
    }
    if( wsaAssertionConfiguration.isAssertFaultToRefParams() )
    {
      // check if request FaultTo ReferenceParameters are included in
      // response
      NodeList requestFaultToRefProps = WsdlUtils.getRequestFaultToRefProps( messageExchange,
          getWsaVersion( requestXmlObject, soapVersion ) );
      for( int i = 0; i < requestFaultToRefProps.getLength(); i++ )
      {
        Node refProp = requestFaultToRefProps.item( i );
        String refPropName = refProp.getNodeName();
        NodeList existingResponseRefs = XmlUtils.getChildElementsByTagName( header, refPropName );
        if( existingResponseRefs != null && existingResponseRefs.getLength() > 0 )
        {
          continue;
        }
        else
        {
          cumulativeErrorMsg.append( "Response does not have request ReferenceProperty " + refPropName + ". " );
        }

      }
    }
    String cumulativeError = cumulativeErrorMsg.toString();
    if( !StringUtils.isNullOrEmpty( cumulativeError ) )
    {
      throw new AssertionException( new AssertionError( cumulativeError ) );
    }
  }

  private void parseRelatesToNode( SoapVersion soapVersion, XmlObject requestXmlObject, Element relatesToNode )
  {
    if( relatesToNode == null )
    {
      cumulativeErrorMsg.append( "WS-A RelatesTo property is not specified. " );
    }
    else
    {
      String relatesToValue = XmlUtils.getElementText( relatesToNode );
      if( StringUtils.isNullOrEmpty( relatesToValue ) )
      {
        cumulativeErrorMsg.append( "WS-A RelatesTo property is empty. " );
      }
      else
      {
        String requestMsgId = WsdlUtils.getRequestWsaMessageId( messageExchange,
            getWsaVersion( requestXmlObject, soapVersion ) );
        if( !relatesToValue.equals( requestMsgId ) )
        {
          cumulativeErrorMsg.append( "WS-A RelatesTo property is not equal to request wsa:MessageId. " );
        }
      }
      /*
       * When absent, the implied value of this attribute is
       * "http://www.w3.org/2005/08/addressing/reply". question is does it
       * have to be present as 'reply' ???
       */

      // String relationshipType =
      // relatesToNode.getAttribute("RelationshipType");
      // if (StringUtils.isNullOrEmpty(relationshipType))
      // {
      // relationshipType =
      // relatesToNode.getAttributeNS(WsaUtils.WS_A_VERSION_200508,
      // "RelationshipType");
      // if (StringUtils.isNullOrEmpty(relationshipType))
      // {
      // relationshipType =
      // relatesToNode.getAttributeNS(WsaUtils.WS_A_VERSION_200408,
      // "RelationshipType");
      // if (StringUtils.isNullOrEmpty(relationshipType))
      // {
      // cumulativeErrorMsg.append("WS-A RelationshipType is not specified. ");
      // }
      // }
      // }
    }
  }

  /*
   * asserts specific property
   */
  private void assertProperty( String propertyName, String wsaProperty, String expectedValue )
  {
    Element propertyNode;

    if( wsaVersionNameSpace != null )
    {
      propertyNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, wsaProperty );
      parsePropertyNode( propertyName, propertyNode, expectedValue );
    }
    else
    {
      propertyNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200508, wsaProperty );
      if( propertyNode == null )
      {
        propertyNode = XmlUtils.getFirstChildElementNS( header, WsaUtils.WS_A_NAMESPACE_200408, wsaProperty );
      }
      parsePropertyNode( propertyName, propertyNode, expectedValue );
    }
  }

  private void assertProperty( String propertyName, String wsaProperty )
  {
    assertProperty( propertyName, wsaProperty, null );
  }

  private void parsePropertyNode( String propertyName, Element propertyNode, String expectedValue )
  {
    if( propertyNode == null )
    {
      cumulativeErrorMsg.append( propertyName + " property is not specified. " );
    }
    else
    {
      String actionValue = XmlUtils.getElementText( propertyNode );
      if( StringUtils.isNullOrEmpty( actionValue ) )
      {
        cumulativeErrorMsg.append( propertyName + " property is empty. " );
      }
      else if( !StringUtils.isNullOrEmpty( expectedValue ) )
      {
        if( !actionValue.equals( expectedValue ) )
        {
          cumulativeErrorMsg.append( propertyName + " expecting [" + expectedValue + "], actual value is ["
              + actionValue + "]." );
        }
      }
    }
  }
}
TOP

Related Classes of com.eviware.soapui.impl.wsdl.support.wsa.WsaValidator

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.