Monday, September 8, 2014

ESB Guaranteed Delivery with client acknowledgement for synchronous clients

A typical guaranteed delivery scenario covered as an Enterprise Integration ensures the delivery of a message to a given backend endpoint. As per this pattern the ESB would attempt to delivers the message to the backend endpoint and if it fails, the message would be stored and delivered once the backend endpoint becomes available. If the above guaranteed delivery mechanism is implemented to a message flow that is synchronous the client would be waiting for a response from the ESB until the message times out. To accommodate synchronous clients in a guaranteed delivery scenario, it is possible for the ESB to respond to the client with a fault message in case the message is not delivered and stored for later delivery. The following diagram depicts the message flow of the guaranteed delivery scenario with client acknowledgement using the WSO2 ESB.




1.      Client sends the message to the ESB.
2.      ESB try to deliver the message to the backend system, and the message fails
3.      ESB stores the message in a message queue
4.      ESB sends a response back to the client (response can be customized as required)
5.      ESB picks the message from the queue and try to deliver the message to the backend system; ESB retry can be customized to retry a given number of attempts.



The following synapse configuration can be used to configure this scenario. The configuration includes a proxy service, message broker, message processor, sequences and endpoints required to create the required mediation flow. Please note that the configuration is based on storing messages in an ActiveMQ based message queue. Hence it is required to follow the steps mentioned in the following link [1] setting up ActiveMQ with WSO2 ESB.

<proxy name="StockQuoteProxy"
          transports="https http"
          startOnLoad="true"
          trace="disable">
      <description/>
      <target>
         <inSequence>
            <sequence key="delivery_seq"/>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
      </target>
  <publishWSDL uri="file:repository/samples/resources/proxy/sample_proxy_1.wsdl"/>
   </proxy>
   <endpoint name="queueEP">
      <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
   </endpoint>
   <endpoint name="StockQuoteFO">
   <address uri="http://localhost:9000/services/SimpleStockQuoteService"</endpoint>
   <sequence name="delivery_seq" onError="errorHandler">
      <enrich>
         <source type="envelope" clone="true"/>
         <target type="property" property="mssg"/>
      </enrich>
      <send>
         <endpoint key="StockQuoteFO"/>
      </send>
   </sequence>
   <sequence name="SendResponse">
      <header name="To" action="remove"/>
      <property name="RESPONSE" value="true"/>
      <send/>
   </sequence>
   <sequence name="errorHandler">
      <makefault version="soap11">
         <code xmlns:tns="http://www.w3.org/2003/05/soap-envelope" value="tns:Receiver"/>
         <reason value="Message has been stored."/>
      </makefault>
      <clone>
         <target sequence="SendResponse"/>
         <target sequence="queueMessage"/>
      </clone>
   </sequence>
  
   <sequence name="queueMessage">
      <enrich>
         <source type="property" clone="true" property="mssg"/>
         <target type="envelope"/>
      </enrich>
      <property name="target.endpoint" value="queueEP"/>
      <property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
      <property name="OUT_ONLY" value="true"/>
      <store messageStore="JMStore"/>
   </sequence>
  
   <messageStore class="org.apache.synapse.message.store.impl.jms.JmsStore"
                 name="JMStore">
      <parameter name="java.naming.factory.initial">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter>
      <parameter name="store.jms.cache.connection">false</parameter>
      <parameter name="java.naming.provider.url">tcp://localhost:61616</parameter>
      <parameter name="store.jms.JMSSpecVersion">1.1</parameter>
   </messageStore>
   <messageProcessor class="org.apache.synapse.message.processor.impl.forwarder.ScheduledMessageForwardingProcessor"
                     name="ScheduledProcessor"
                     messageStore="JMStore">
      <parameter name="interval">20000</parameter>
      <parameter name="is.active">true</parameter>

   </messageProcessor>


[1] https://docs.wso2.com/display/ESB481/Configure+with+ActiveMQ

Monday, July 14, 2014

Restricting grant types for an application in WSO2 API Manager

WSO2 API Manager has the capability of restricting which grant types are enabled to a given application. This functionality is provided via the management console of the API Manager. Given below are the steps required

1. App developers should have the required permission in order to restrict the grant types available for an application. Permission given below should be set to a user role associate to the App developer.

2. Once this is done please log out and log into the API Manager's admin console

3. Now you would see the OAuth URL available in the left navigation, click on this.


4. Here you would see all the applications that are created by the App developer, from this menu select the relevant application to which the grant types should be restricted.

5. Once you are inside the selected application you can define which grant types should be allowed to a given application. By default all grant types are 'un-checked' and all grant types are allowed. If you want to override this default configuration select on the required grant types that should be allowed to a given application.

6. Once you are done click on the update button and the configuration would be updated.

Tuesday, July 8, 2014

IP based filtering for Proxy services exposed by WSO2 ESB

WSO2 ESB provides the ability to filter messages based on different parameters. These parameters include data in the message header, message content or even data relating to the message sender. This blog looks into how WSO2 ESB can be used to filter a message based on the IP Address of a client. The below ESB configuration would filter a message and send it to the beackend service only if it arrives from a pre-defined IP address range (192.168.1.*). If the message is recieved from any other IP address the message is dropped. This type of IP based filtering can be applied to secure a backend service from unauthorized access.


<proxy name="IpFilteringProxy"
          transports="https http"
          startOnLoad="true"
          trace="disable">
      <description/>
      <target>
         <inSequence>
            <log level="full">
               <property name="TO Property" expression="get-property('axis2','REMOTE_ADDR')"/>
            </log>
            <filter source="get-property('axis2','REMOTE_ADDR')" regex="192\.168\.1.*">
               <then>
                  <send>
                     <endpoint>
                        <address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
                     </endpoint>
                  </send>
               </then>
               <else>
                  <drop/>
               </else>
            </filter>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
         <faultSequence/>
      </target>
   </proxy>

Tuesday, May 20, 2014

How to retrieve token information using REST API in WSO2 API Manager


WSO2 API Manager provides a host of REST API's that are capable of performing many operations in the API Manager. Given below are the steps to follow to retrieve token information such as the Consumer Key,Consumer Secret, and Access Token using the REST API. In order to perform this we assume that an instance of the API Manager is running(in port offset 0) and an application is already available in the API Store.

1. Initially you need to login to the API Store and create a cookie that can be used in subsequent REST calls. Login to the store using the following command. Replace the username and the password with the relavent values
curl -X POST -c cookies http://localhost:9763/store/site/blocks/user/login/ajax/login.jag -d "action=login&username=xxxx&password=xxxx"

2. Call the Generate Application Key API that would generate the required access keys. Use the below command to generate the application keys. The following command would generate keys for the default applications. Change the parameters accordingly based on your application.
curl -X POST -b cookies http://localhost:9763/store/site/blocks/subscription/subscription-add/ajax/subscription-add.jag -d "action=generateApplicationKey&application=DefaultApplication&keytype=PRODUCTION&provider=&tier=&version=&callbackUrl=&authorizedDomains="



Wednesday, May 14, 2014

Secure, Expose and Manage a SOAP Service using WSO2 API Manager and WSO2 ESB.



WSO2 API Manager provides support for both REST and SOAP based web services. However the API Manager doesn’t support WS Standards. The API Manager and the WSO2 ESB can be used in conjunction to support WS Standards to API’s exposed via the API Manager. In this blog we look at how WSO2 API Manager can be used with the WSO2 ESB to secure and expose a SOAP based API.

Given below is a diagram depicting the message flow on how WS-Security is implemented using WSO2 API manager and WSO2 ESB.


The message from the client would be encrypted using the public key of the ESB. The encrypted message would be sent along with the acquired OAuth token to the API Manager. The API Manager would validate the OAuth token and enforce throttling on the message. The API Manager would send the encrypted message to the ESB. The ESB would decrypt the content of the message using its own private key and send the request to the backend service.

Once the response is received from the backend service, the ESB would encrypt the message using client’s public key and send it to the API Manager. The API Manager would pass-through the message back to the client. The client would decrypt the message using its own private key.

This type of a scenario is useful in a case where
1.WS-Security needs to be enforced but cannot be enforced directly at the backend service (hence needs be enforced in an intermediary stage in the message flow).
2. Client should be provided with a portal to explore and subscribe to API’s.
3. API Publisher wants to manage life-cycle and manage API versioning of the exposed API’s.
4. Throttling and other security mechanisms has to be enforced on-top of WS-Security.
5. Statistics on API invocations needs to be gathered.



Thursday, April 3, 2014

Using WSO2 ESB to modify messages with text content

WSO2 ESB provides 1st class support to SOAP and REST message formats. The WSO2 ESB is also capable of mediating messages with plain text contents. This can be done using a script mediator. You can read more about the script mediator from this link[1]. For this scenario I would be sending a text payload over HTTP. The ESB would extract the message payload and perform text manipulation using the script mediator and send the modified payload to the backend service. The script used in the script mediator is Javascripts. The following diagram illustrates the message flow.


Given below is a sample synapse configuration for the scenario. In the example below HTTP POST with a payload "Text send by Nadeesha" is sent to the ESB, which would be replaced as "Text from Nadeesha" and sent to the backend service.

<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="testProxy"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <log level="full"/>
         <log>
            <property xmlns:m0="http://ws.apache.org/commons/ns/payload"
                      name="payload"
                      expression="$body/m0:text"/>
         </log>
         <property xmlns:m0="http://ws.apache.org/commons/ns/payload"
                   name="payload"
                   expression="$body/m0:text"/>
         <script language="js">var payload= mc.getProperty('payload').trim();var newPayload= payload.replace("send by","from");mc.setProperty("newPayload",newPayload);</script>
         <enrich>
            <source type="property" clone="true" property="newPayload"/>
            <target type="body"/>
         </enrich>
         <log level="full"/>
      </inSequence>
      <outSequence>
         <send/>
      </outSequence>
      <endpoint>
         <address uri="http://localhost/testEP"/>
      </endpoint>
   </target>
   <description/>
</proxy>


The same functionality can also be done using a class mediator where by a Java class can be written to perform the same task.

[1] https://docs.wso2.org/display/ESB481/Script+Mediator

Thursday, March 20, 2014

Integrating WSO2 API Manager with a 3rd Party Billing tool

How can we integrate 3rd party billing to the WSO2 API Manager? 
The API Manager already collects all API related data when an API invocation is made by a service consumer. The API Manager can publish them to the WSO2 Business Activity Monitor (WSO2 BAM) out of the box, which the WSO2 BAM uses to generate information required for API statistics. The same process can be utilized by a 3rd party tool to access API information from the API Manager. Once the data is published to the WSO2 BAM, WSO2 BAM would stores the data in a Cassandra data-store and summarize these data periodically based on a set of Apache Hive queries. The summarized information can then be inserted to a RDBMS which can be accessed by the 3rd party billing tool. This can be illustrated by the diagram below

The WSO2 API Manager is shipped with a standard set of Hive queries(As part of the BAM toolbox) to summarize API data. It is possible to modify or write your own Hive queries to summarize the API information based on your own KPI's to fit the needs of the 3rd party billing system. The billing system can directly access the RDBMS and use it as a data source to generate billing information.