Thursday, September 12, 2013

Why I need a port.mapping property when clustering WSO2 API Manager/ WSO2 ESB?

In a dynamically clustered set-up where you front a carbon instance using a WSO2 ELB, it is a responsibility of a Carbon server to send its information to ELB. You can visualize this as a "Member object somehow getting passed to ELB from Carbon server instance". In Carbon server's clustering section, under properties, you can define any Member property. This way, you can let ELB know about the information other than the basic ones. What are the basic information, you might think. Typically those are host name, http port, https port etc.

WSO2 ESB, WSO2 API Manager etc. are bit special w.r.t. ports since they usually have 2 http ports (compare to 1 http port of WSO2 AS). Hence, here we have to somehow send this additional information to ELB. Easiest way to do that is by setting a member property. Here, we use port.mapping property. Also, in order to front these special servers we need 2 http ports in ELB too, which are exposed to outside. There's a deployment decision to be made here, i.e. which http port of ELB should map to which http port of the server (i.e. servlet http port or Nhttp http port). With that in mind, let me explain, how you should use this port.mapping property.
Let me consider only the http scenario. Say, in your API-M instance, you have used 8280 as the Nhttp transport port (axis2.xml) and 9763 as the Servlet transport port (catalina-server.xml). Also ELB has 2 http ports one is 8280 and the other is 8290. Imagine there's a Member object, and in this case Member's http port would be 8280 (usually the port defined in axis2.xml gets here). But since ELB has 2 ports, there's no way to correctly map ports, by only specifying Member's http port. There arises the importance of port.mapping property. You have to think this property from the perspective of ELB.

<property name="port.mapping.8290" value="9763"/>

Let's assume we define the above property, now this means, if a request comes to ELB, in its 8290 port (see... we're thinking from ELB's perspective), forward that request to the 9763 port of the Member. Having only this property is enough, we do not need following property,

<property name="port.mapping.8280" value="8280"/>

Let me explain why. The logic was written in a way, that port.mapping properties get higher precedence over the default ports. This means, that when a request comes to ELB, ELB will first check whether the port it received the request from, is specified as a port.mapping property. If it is, it will grab the target port from that property. If not, it will send the request to the default http port. Hence, if a request received to the 8280 port of ELB, it will be automatically get redirected to 8280 port of the Member (since it's the http port of Member).

Similarly, we should define a mapping for https servlet port.

Hope someone find this useful.

Thursday, September 5, 2013

Checking the non-existent of a property using WSO2 ESB 4.6

You can't simply do a string regex matching, if you are to check the non-existence of a property. What you could do is to leverage the boolean Xpath function [1], within a filter mediator.

Please see the following sample proxy configuration:

<proxy xmlns="" name="TEST" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
         <filter source="boolean(get-property('accept'))" regex="false">
               <log level="custom">
                  <property name="*********" value="NULL Property Value"/>
               <log level="custom">
                  <property name="*********" value="NOT NULL Property Value"/>

Hope this will save some amount of time of quite a bit of you :-)