Thing which seemed very Thingish inside you is quite different when it gets out into the open and has other people looking at it

Tuesday, July 31, 2012

Enabling VFS transport marks certain services as 'faulty'. How to resolve this?


When enabling the VFS transport in the WSO2 admin console there are a number of axis2 services which are marked as being faulty. None of these services (the default Echo service is one of these) have the VFS transport configured explicity in their transports list.
The message shown in the admin console for each of these faulty services is 'Unable to configure the service echo for the VFS transport: Service doesn't have configuration information for transport vfs. This service is being marked as faulty and will not be available over the VFS transport.'

Why it happens? and How to Resolve it?
   
This is because when you enable VFS transport that transport gets enabled to other services as well (including axis2 services) But they don't have necessarry properties needed for VFS to be properly enabled. So when you enable VFS ESB default axis2 services like echo/version services will get faulty. There are two ways to resolve this issue. Since WSO2 ESB is not meant to deploy Application service and it should be used as routing/hub purposes you can undeploy those services. However, if you still want to keep those axis2 services you can go to services.xml and add http and https transports as shown below.

<service name="echo">
   <schema elementFormDefaultQualified="false"/>
   <description>
       This service echos the input provided to it.
   </description>
     <transports>
      <transport>https</transport>
      <transport>http</transport>
   </transports>
   <parameter name="ServiceClass" locked="true">org.wso2.carbon.core.services.echo.Echo</parameter>
</service>

Once you added them you need to redeploy the services.

Monday, July 9, 2012

How To Use Validate Mediator to Validate the SOAP request using WSO2 ESB

Lets say you have a service with the following soap request and you need to validate the input message,  through a proxy service, for those kind of instances you can use WSO2 ESB Validate Mediator.

For this demonstration I am going to create a proxy service which is deployed and hosted under my tenant in StratosLive you can use the same service for sample purposes. This is a service which takes an input string and send a response along with the given input String.

My End point is
http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService/              
The WSDL for my Service
http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService?wsdl

First Lets Create a proxy service which access this service

 <proxy name="MyValidatorProxy"
          transports="https http"
          startOnLoad="true"
          trace="disable">
      <description/>
      <target>
         <inSequence>
            <log level="full">
               <property name="Message" value="Inside Insequance"/>
            </log>
            <send>
               <endpoint>
                  <address uri="http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService/"/>
               </endpoint>
            </send>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
      </target>
      <publishWSDL uri="http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService?wsdl"/>
   </proxy>

Go to ESB Management Console and copy paste the following code in Source View (Under Main -> Service Bus -> Source View) and click on update.

This will create a proxy service which will create the service I hosted in my tenant.

You can invoke this service by going into Services List and click on try it. Which is a client we use to invoke the service.

Now When you click on the try-it, you will get redirected to a page which has a request and a response.
So for a given request like this

<body>
   <p:greet xmlns:p="http://www.wso2.org/types">
      <!--0 to 1 occurrence-->
      <name>Amani</name>
   </p:greet>
</body>

You should get a response like this.

<ns:greetResponse xmlns:ns="http://www.wso2.org/types">
   <return>Hello World, Amani !!!</return>
</ns:greetResponse>

So lets see how we can validate the request. Lets say you want to make sure the value of the name element is not empty and you want to enforce that for every service innovation there must be a value for the Name element. Then you need to use the ESB validate Mediator.

In order to create a proxy with a validate mediator we need to create a XSD schema. I have created a schema to validate the name element of the request.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ns="http://www.wso2.org/types"
attributeFormDefault="qualified" elementFormDefault="unqualified"
targetNamespace="http://www.wso2.org/types">
<xs:element name="greet">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="name" >
 <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:minLength value="1" />
        </xs:restriction>
    </xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Here the main thing you need to focus is this part

<xs:element minOccurs="1" name="name" >
 <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:minLength value="1" />
        </xs:restriction>
    </xs:simpleType&gt;
</xs:element>

We are using the restriction element which says to restrict the type as String and the input should be a non-zero value (basically this means element cannot be empty). Now we need to upload this in the registry.

Uploading the validation schema in the registry.

Go to Browse in the Registry menu. And there click on config and under that click on Add New Resource. And upload the file as xsd file.

Add Validator Mediator

<validate>
        <schema key="conf:/HelloSchema.xsd"/>
               <on-fail>
                  <makefault version="soap11">
                     <code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
                     <reason value="Invalid Request!!!"/>
                     <role/>
                  </makefault>
                  <log level="full" />
                  <property name="RESPONSE" value="true"/>
                  <header name="To" action="remove"/>
                  <send/>
                  <drop/>
               </on-fail>
            </validate>

In here we add the Schema from the registry, If the validation fails it will send a message saying "Invalid Request" and we will terminate the flow using the drop mediator.

Now we will ad this validate mediator in the in sequence of our proxy service.

<proxy xmlns="http://ws.apache.org/ns/synapse" name="MyValidatorProxy" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
   <target>
      <inSequence>
         <log level="full">
            <property name="Message" value="Inside Insequance"/>
         </log>
         <validate>
            <schema key="conf:/HelloSchema.xsd"/>
            <on-fail>
               <makefault version="soap11">
                  <code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
                  <reason value="Invalid Request!!!"/>
                  <role/>
               </makefault>
               <log level="full"/>
               <property name="RESPONSE" value="true"/>
               <header name="To" action="remove"/>
               <send/>
               <drop/>
            </on-fail>
         </validate>
         <send>
            <endpoint>
               <address uri="http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService/"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </target>
   <publishWSDL uri="http://appserver.stratoslive.wso2.com/services/t/amani123.com/HelloService?wsdl"/>
   <description></description>
</proxy>
                              
Now if you invoke this using try it without a content in the name element you will get the message as Invalid Request.

Request
<body>
   <p:greet xmlns:p="http://www.wso2.org/types">
      <!--0 to 1 occurrence-->
    <name></name>
   </p:greet>
</body>

Response
<soapenv:Fault xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <faultcode>tns:Receiver</faultcode>
   <faultstring>Invalid Request!!!</faultstring>
</soapenv:Fault>