Tuesday, February 17, 2015

A sample on a WSO2 ESB proxy with a DBLookup mediator and a dedicated faultSequence to excute during an error

Databases :

DB customer should be created with the required tables.

DB : customerDetails
table :  customers


Proxy :


<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="TestProxyUsh"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence onError="testError">
         <dblookup>
            <connection>
               <pool>
                  <password>root</password>
                  <user>root</user>
                  <url>jdbc:mysql://host:3306/customerDetails</url>
                  <driver>com.mysql.jdbc.Driver</driver>
               </pool>
            </connection>
            <statement>
               <sql>SELECT * FROM customers WHERE name =?</sql>
               <parameter value="WSO2" type="INTEGER"/>
               <result name="company_id" column="id"/>
            </statement>
         </dblookup>
      </inSequence>
      <faultSequence>
         <log level="custom">
            <property name="text" value="An unexpected error occurred for the service"/>
         </log>
      </faultSequence>
   </target>
   <description/>
</proxy>
                               

onError targeting sequence :


<sequence xmlns="http://ws.apache.org/ns/synapse" name="testError">
   <log>
      <property name="error" value="Error Occurred"/>
   </log>
</sequence>


Invoke :

curl -v http://host:8280/services/TestProxyUsh









One possible reason and solution for getting Access denied for user 'username'@'host' in mysql when accessing from outside

Sometimes we might get the below exception when creating a DB connection.

 {org.apache.synapse.mediators.db.DBLookupMediator}
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Access denied for user 'username'@'203.94.95.133'


Reasons :

The particular IP might not be accessible from outside.

Therefore you need to grant priviledges by the below command in mysql :

GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password';


FLUSH PRIVILEGES;


Sometimes you might try out below :

GRANT ALL PRIVILEGES ON *.* TO 'password'@'%' WITH GRANT OPTION;

Eventhough it says Query OK, still the issue can be there since you have not used the password.

Also you must do a Flush privileges to update it.

Hope this might help sometimes.

Monday, February 16, 2015

A possible reason and solution for getting 400 Bad Request even when the synapse configuration in WSO2 ESB is correct

Sometimes you might spend lot of time in analyzing the reason for getting 400 bad request when you invoke an up and running backend service through WSO2 ESB.

When you configure and save the synapse configuration of your proxy, you will not see any issue. But sometimes there can a possible reason for this issue.

One good example is explained below :

Look at the below synapse configuration of WSO2 ESB proxy service.


 <proxy name="statuscodeProxy"
          transports="https http"
          startOnLoad="true"
          trace="disable">
      <description/>
      <target>
         <inSequence>
            <log level="full"/>
            <send>
               <endpoint>
                  <address uri="http://10.100.0.31:8090"/>
               </endpoint>
            </send>
         </inSequence>
         <outSequence>
            <log level="full"/>
            <send/>
         </outSequence>
      </target>
   </proxy>



By the look of it, this is alright and you are good to configure it in WSO2 ESB. But the endpoint defined as : http://10.100.0.31:8090 is not exactly the endpoint the backend service expects.

Sometimes there can be missing parameters etc. But if you exactly know your backend service does not expect any parameters and still it throws a 400 bad reques, can you imagine the reason for this?

After spending hours, I accidently found a possible reason :

 it was due to the backend expects a / at the end of the endpoint. So it expects :

http://10.100.0.31:8090/ except http://10.100.0.31:8090


If you configure a tcpmon in between ESB and the backend, you will see the difference as below :

http://10.100.0.31:8090 :  GET  HTTP/1.1  - 400 bad Request

http://10.100.0.31:8090/ : GET / HTTP/1.1  - 200 OK

So if you too come across this situation, please try out this option. Sometimes this might save your time! :)


One Possible Reason and solution for dropping the client's custom headers when sending through nginx

Problem :

Sometimes you may have experienced that the custom header values defined and sent through client has been dropped off when it goes via the nginx in a setup fronted by nginx.


Solution :

1. First you should check whether the custom headers  contain underscores (_)

2. If so you need to check whether you have configured underscores_in_headers in your nginx.conf under each server.

3. By default, underscores_in_headers is off.

4. Therefore you need to configure it to on.


Reason :


By this property,

It enables or disables the use of underscores in client request header fields. When the use of underscores is disabled, request header fields whose names contain underscores are marked as invalid and become subject to the ignore_invalid_headers directive.

Ref: http://nginx.org/en/docs /http/ngx_http_core_module.html


Example :

Sample configuration would be as below :



server{
      listen 8280;
      server_name wrk.esb.com;
      underscores_in_headers on;

location / {
       proxy_set_header X-Forwarded-Host $host;
       proxy_set_header X-Forwarded-Server $host;.
.
.
.
.
                }
         }

Wednesday, February 11, 2015

Reason and solution for not loading WSDL in a clustered setup fronted by NGINX





For more information about nginx http proxy module please refer : http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version



Issue :
Sometimes a WSDL in a clustered setup fronted by NGINX might not be loaded.



Reason :

By default, http version 1.0 is used in nginx. Version 1.1 is recommended for use with keepalive connections. Therefore sometimes the wsdl will not be loaded.

You can confirm it by doing a curl command to the wsdl ngingx url.

E.g.,  curl http://wrk.test.com:8280/services/test?wsdl
Then you will get half of the wsdl.


Solution :

To avoid this, you will have to configure the nginx configuration file to set it's http version.


       proxy_http_version 1.1;
 

Example :

As an example,

server{
      listen 8280;
      server_name wrk.test.com;

location / {
       proxy_set_header X-Forwarded-Host $host;
       proxy_set_header X-Forwarded-Server $host;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       proxy_http_version 1.1;

        proxy_pass http://esbworkers;
        proxy_redirect http://esbworkers http://wrk.esb.com:8280/;


        }
}

This configuration is applicable for nginx versions above 1.1.4