Popular Posts

Wednesday, November 21, 2012

TIP: Error handling in WSO2 ESB APIs when the requested API resource does not match with the given URL template or pattern

When you send a HTTP request to an API in WSO2 ESB, if the requested API resource URL does not comply with the API resource definition, ESB returns HTTP 202 accepted response to the user. Due to  this behavior, the client is unable to distinguish if they have made an error. We can use the following procedure to return a fault to the client in case of non-matching API resource is requested by client.

Step 1:

Suppose, we have an API similar to the following. Note that, the target web service is a JAXRS web application (jaxrs_basic) which is included in WSO2 Application Server by default.

<api xmlns="http://ws.apache.org/ns/synapse" name="jaxrs" context="/jaxrs">
   <resource methods="GET" uri-template="/customers/{id}">
      <inSequence>
         <send>
            <endpoint>
               <address uri="http://localhost:9764/jaxrs_basic/services/customers/customerservice"/>
            </endpoint>
         </send>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
   </resource>
</api> 

Step 2:

Send the following HTTP GET request to the above API. (You can use a soapUI web testcase as instructed in one of my previous blog posts).

GET http://localhost:8280/jaxrs/customers-wrong/123

Step 3:

You will get HTTP 202 accepted response because the request URL does not match with the resource url-template defined in the API.

Step 4:

Now, add the following fault handling sequence in ESB. Once the API receives a request which does not match with any of the resource url patterns/templates, this sequence will be invoked. Make sure to name the sequence as _resource_mismatch_handler_

 <sequence xmlns="http://ws.apache.org/ns/synapse" name="_resource_mismatch_handler_">
   <payloadFactory>
      <format>
         <tp:fault xmlns:tp="http://test.com">
            <tp:code>404</tp:code>
            <tp:type>Status report</tp:type>
            <tp:message>Not Found</tp:message>
            <tp:description>The requested resource (/$1) is not available.</tp:description>
         </tp:fault>
      </format>
      <args>
         <arg xmlns:ns="http://org.apache.synapse/xsd" expression="$axis2:REST_URL_POSTFIX"/>
      </args>
   </payloadFactory>
   <property name="RESPONSE" value="true" scope="default"/>
   <property name="NO_ENTITY_BODY" action="remove" scope="axis2"/>
   <property name="HTTP_SC" value="404" scope="axis2"/>
   <header name="To" action="remove"/>
   <send/>
   <drop/>
</sequence>

Step 5:

Send the above HTTP GET request again. This time, you will get a proper error as shown below.

HTTP/1.1 404 Not Found
Content-Type: application/xml; charset=UTF-8
Accept-Encoding: gzip,deflate
Host: 10.100.3.37:8280
Date: Fri, 16 Nov 2012 06:06:51 GMT
Server: Synapse-HttpComponents-NIO
Transfer-Encoding: chunked 

Monday, November 19, 2012

How to enable mail transport for WSO2 data services

We can use mail transport to send and receive messages to and from web services using MIME complaint mail messages. We can configure mail transport for Axis2 services which are deployed in WSO2 Application Server by following the instructions given in the official documentation.
In there, you will notice that, a set of mail transport specific parameters need to be configured in the services.xml of Axis2 service in order to enable mail transport in Axis2 services.
How can we do the same for data services which are deployed in WSO2 Application Server?
This post summarizes the procedure of configuring mail transport for a data service.

Step 1:

Download and install WSO2 Application Server-5.0.0 or a later version. Configure mail transport sender and receiver in axis2.xml configuration file which can be found at CARBON_HOME/repositiry/conf/axis2/axis2.xml (see WSO2 Application Server official documentation on how to configure mail transport sender and receiver in axis2.xml)
After configuring axis2.xml, make sure to restart the server.

Step 2:

Once the server is started, you will see the existing services become faulty with the warnings similar to the following. 

WARN {org.apache.axis2.transport.mail.MailTransportListener} -  Unable to configure the service TestService for the MAILTO transport: Service doesn't have configuration information for transport mailto. This service is being marked as faulty and will not be available over the MAILTO transport.

The reason for this is, though we have configured mail transport globally in axis2.xml configuration file, we have not configured mail transport at individual service level. Thus, if you have Axis2 Services or data services or any other service type, the mail transport will not be enabled for them. You can configure mail transport for specific Axis2 services as instructed in here.

However, data services do not have a services.xml associated with it by default. Thus, we need to follow a different procedure for them.

Step 3:

Locate the *.dbs file in CARBON_HOME/repository/deployment/server/dataservices/ directory. Let's assume the data service is GUEST_T_DataService.dbs. Create a file GUEST_T_DataService_services.xml at the same directory. (Make a note of the name of the file which is in the format; _services.xml)

GUEST_T_DataService_services.xml can be similar to the following. Note the mail related parameters section.

<serviceGroup>
<service name="GUEST_T_DataService">
<Description>This sample demonstrates some of the main functionalities of a dataservice using an RDBMS data source
</Description>
 <!--mail related parameters-->
        <parameter name="transport.mail.Address">synapse.demo.1@gmail.com</parameter>
        <parameter name="transport.mail.Protocol">pop3</parameter>
        <parameter name="transport.PollInterval">5</parameter>
        <parameter name="mail.pop3.host">pop.gmail.com</parameter>
        <parameter name="mail.pop3.port">995</parameter>
        <parameter name="mail.pop3.user">synapse.demo.1</parameter>
        <parameter name="mail.pop3.password">mailpassword</parameter>

        <parameter name="mail.pop3.socketFactory.class">javax.net.ssl.SSLSocketFactory</parameter>
        <parameter name="mail.pop3.socketFactory.fallback">false</parameter>
        <parameter name="mail.pop3.socketFactory.port">995</parameter>
        <parameter name="transport.mail.ContentType">text/xml</parameter>


</service></serviceGroup>


Step 4:

Now, check the dashboard of your data service. You will see mail transport is enabled as shown below. (Restart server if the mail transport is still not enabled for data service).