Monday, July 25, 2016

foreach sample configuration in WSO2 ESB

foreach mediator helps you to iterate through a element array. For a example, if you need to iterate xml array and concatenate them together, bellow configuration read all the id and concatenate them.


 <foreach xmlns:ns1="http://ws.wso2.org/dataservice"  
          id="Idforeach"  
          expression="//ns1:Entries/ns1:Entry/ns1:id">  
       <sequence>  
        <property name="ID"  
             expression="fn:concat($ctx:ID,//ns1:id, ',')"  
             type="STRING"/>  
       </sequence>  
     </foreach>  
     <log level="custom">  
       <property name="IDs" expression="$ctx:ID"/>  
     </log>  
Ex: ESB will log "IDs = 105,106," for below request payload

 <Entries xmlns="http://ws.wso2.org/dataservice">  
 <Entry><id>105</id></Entry>  
 <Entry><id>106</id></Entry>  
 </Entries>



How to secure a queue with username and password in ActiveMQ


How to secure a queue with username and password in ActiveMQ

By Default, Queue in a ActiveMQ server can be access without username and password. Adding below configuration in to activemq.xml will make sure that queue is secure with username and password. Then you need to provide a username and password when you create a connection.



 <broker  
   xmlns="http://activemq.apache.org/schema/core"   
 brokerName="localhost" dataDirectory="${activemq.data}">  
 ...........     
 <plugins>  
     <simpleAuthenticationPlugin>  
       <users>  
         <authenticationUser username="nuwan"   
                   password="mypassword"   
                   groups="admins,publishers,consumers" />  
       </users>  
     </simpleAuthenticationPlugin>  
   </plugins>   
 ................   
  </broker>  



Wednesday, March 11, 2015

Getting Date String from unix time stamp in HIVE Query

if You try to get the Date String from hive query as below, You will get an invalid date.

SELECT timestamp, from_unixtime(timestamp, 'yyyy-MM-dd HH:mm:ss') FROM TableName

1426109700733 > 47161-08-14 00:32:13
 
 from_unixtime expect the time in seconds and you have to use below query to get the date correct.

SELECT timestamp, from_unixtime(CAST(timestamp/1000 as BIGINT), 'yyyy-MM-dd HH:mm:ss') FROM TableName

1426109700733 > 2015-03-11 14:35:00

Thursday, August 7, 2014

How to send a HTTP POST or PUT request with empty content message body into a backend server using WSO2 ESB

How to send a HTTP POST or PUT request with empty content message body into a backend server using WSO2 ESB

By the design, ESB expects a message body to send the request to backend server when the http method is POST or PUT. But you can overwrite this behavior by using the property FORCE_POST_PUT_NOBODY. Then you can post or put the request without message body or with the message body if exist to the backend server.

Bellow is the sample proxy service which capable for sending empty messages

<proxy xmlns="http://ws.apache.org/ns/synapse" name="httpendpoint" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">  
   <target>  
    <inSequence>  
      <log level="full" />  
      <property name="FORCE_POST_PUT_NOBODY" value="true" scope="axis2" type="BOOLEAN" />  
    </inSequence>  
    <outSequence>  
      <send />  
    </outSequence>  
    <endpoint>  
      <http uri-template="http://localhost:8080/echoempty/echoemptyrequest" />  
    </endpoint>  
   </target>  
   <description />  
 </proxy>  

         
Then you can send the http messages as bellow to the proxy service.

POST /services/httpendpoint HTTP/1.1
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 0
Host: 127.0.0.1:8282
User-Agent: Apache-HttpClient/4.2.3 (java 1.5) 

                     

Monday, July 7, 2014

How to Send a String Parameter to an Axis2 Web Service

If you have written a web service operation which accept a String parameter, You will not be able to pass a string value directly. The below operation is required a string parameter. Then you need to wrap the text inside the CDATA tag. Other wise it will not read the parameter value.

     public void echo(String request)  {
        System.out.println(request);
    }

If you want to send a simple string , You need to wrap it with CDATA. The the output will be >> "Text Content"

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wso2="http://wso2.org">
   <soapenv:Header />
   <soapenv:Body>
      <wso2:echo>
         <!--Optional:-->
         <wso2:request><![CDATA[Text Content]]></wso2:request>
      </wso2:echo>
   </soapenv:Body>
</soapenv:Envelope>
 
If you want to pass a xml content as a string then you have to use CDATA tag as bellow.
Then the output will be >> "<foo>Test</foo>"
 
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wso2="http://wso2.org">
   <soapenv:Header />
   <soapenv:Body>
      <wso2:echo>
         <!--Optional:-->
         <wso2:request><![CDATA[<foo>Test</foo>]]></wso2:request>
      </wso2:echo>
   </soapenv:Body>
</soapenv:Envelope> 

You need CDATA tag always to send the String value to a web service operation if they have String type parameter

Friday, May 16, 2014

How to append a query parameter to an API published from WSO2 API Manager

How to append a query parameter to an API published from WSO2 API Manager

There are some situations where you need to send some url query parameters with the request when publishing an API through the API Manager. But You do not need client to send those parameters with the request URL. In that case how do you append those parameters to the endpoint url. In this blog post see how to append a query parametr to endpoint url.

First you need to create an API and published the API. Please refer how to create an API to create an API in WSO2 API Manager.

Then the requirement is once you invoke the API with some query parameter, It will call the actual service endpoint with some other query parameter.

You can append query parameters to the endpoint url from API Manager. synapse property 'REST_URL_POSTFIX' can be used to manage the query parameter. Once you create an api, what you have to do is that, you need to update the synapse configuration of the api created with the relevant property. the property REST_URL_POSTFIX will give you the query string coming into the api from the client. Then you can change the query string as you need.

<property name="REST_URL_POSTFIX" expression="fn:concat(get-property('axis2','REST_URL_POSTFIX'), '&amp;exchange=xyz')" scope="axis2" type="STRING"/>

Once You create an API, You can add parameter by following bellow steps.
1) Login to AM(https://ipaddress:port/carbon/) and Click on main > Source View
Then you can see the synapse configuration

2) Find the api configuration you have created by the api name.

3) Then update the insequence of the api with bellow property.
<property name="REST_URL_POSTFIX" expression="fn:concat(get-property('axis2','REST_URL_POSTFIX'), '&amp;exchange=xyz')" scope="axis2" type="STRING"/>

4) Click on update button.

Then your api looks as bellow. 

 <api xmlns="http://ws.apache.org/ns/synapse" name="admin--testapi" context="/testapi" version="1.0.0" version-type="url">  
   <resource methods="GET" url-mapping="/*">  
     <inSequence>  
       <property name="POST_TO_URI" value="true" scope="axis2"/>  
       <property name="REST_URL_POSTFIX" expression="fn:concat(get-property('axis2','REST_URL_POSTFIX'), '&amp;exchange=xyz')" scope="axis2" type="STRING"/>  
       <filter source="$ctx:AM_KEY_TYPE" regex="PRODUCTION">  
         <then>  
           <send>  
             <endpoint name="admin--testapi_APIEndpoint_0">  
               <address uri="http://localhost:8080/stockquote/getQuote">  
                 <timeout>  
                   <duration>30000</duration>  
                   <responseAction>fault</responseAction>  
                 </timeout>  
                 <suspendOnFailure>  
                   <errorCodes>-1</errorCodes>  
                   <initialDuration>0</initialDuration>  
                   <progressionFactor>1.0</progressionFactor>  
                   <maximumDuration>0</maximumDuration>  
                 </suspendOnFailure>  
                 <markForSuspension>  
                   <errorCodes>-1</errorCodes>  
                 </markForSuspension>  
               </address>  
             </endpoint>  
           </send>  
         </then>  
         <else>  
           <sequence key="_sandbox_key_error_"/>  
         </else>  
       </filter>  
     </inSequence>  
     <outSequence>  
       <send/>  
     </outSequence>  
   </resource>  
   <handlers>  
     <handler class="org.wso2.carbon.apimgt.gateway.handlers.security.APIAuthenticationHandler"/>  
     <handler class="org.wso2.carbon.apimgt.gateway.handlers.throttling.APIThrottleHandler">  
       <property name="id" value="A"/>  
       <property name="policyKey" value="gov:/apimgt/applicationdata/tiers.xml"/>  
     </handler>  
     <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtUsageHandler"/>  
     <handler class="org.wso2.carbon.apimgt.usage.publisher.APIMgtGoogleAnalyticsTrackingHandler"/>  
     <handler class="org.wso2.carbon.apimgt.gateway.handlers.ext.APIManagerExtensionHandler"/>  
   </handlers>  
 </api>


Ex: Client request  http://localhost:8280/testapi/1.0.0?symbol=abc
Actual request required for back end
http://localhost:8080/stockquote/getQuote?symbol=abc&exchange=xyz

Here you have added exchange parameter to the service call. As above you can modify the query string as you required.

Wednesday, March 26, 2014

How to secure your services with OAuth2 using WSO2 API Manager

Securing Your Service with OAuth2 Using WSO2 API Manager

If you host a service, You may need some access control on that service. Otherwise any one can access that service. In such case you can use WSO2 API Manager to achieve this easily. API Manager can secure your service with OAuth2.

I have a backend service host on apache tomcat server. It can be invoked both http GET and POST method.

if I send a bellow request, It will receive a response
http://localhost:8080/stockquote/getQuote?symbol=wso2

Response:
<getQuoteResponse>
       <symbol>wso2</symbol>
       <lastPrice>67.73111720684315</lastPrice>
       <company>wso2 Company</company>
       <timeStamp>Wed Mar 26 17:49:25 IST 2014</timeStamp></getQuoteResponse>

Then I am going to create an api on WSO API Manager (wso2am-1.6.0) and keep my actual backend service behind the API Manager.

Steps to create an api
1) First I start a wso2am-1.6.0
2) Login to Publisher using user credential admin
       https://localhost:9443/publisher/ 
3) Add a api with below parameters.

       Name    : stockQuoteApi
       Context : stockquote
       Version : 1.0.0
       Tier Availability : Gold
       Production Endpoint : http://localhost:8080/stockquote/getQuote

With the above parameters, We can create an api successfully.

4) Publish the created api
      Select the created api and change LifeCycle  to Publish

Then We have to subscribe for the created api.

5) Login to Store using user credential admin then you can see the api cretaed
       https://10.100.1.107:9443/store/
6) Then select the api. You can see the access URL of the created api "http://10.100.1.107:8280/stockQuote/1.0.0"
Then choose DefaultApplication in Applications drop down box lay on right corner.

7) Then Click On Subscribe button.

8) Then click On Generate button in Keys - Production. Then you can see the Access Token.

Now API Creation is completed.

Then Try to access the api. You can use any http client to access the service. Inv this case I am going to use curl.

Now I am trying to invoke the api with below command.

curl  http://localhost:8280/stockQuote/1.0.0?symbol=wso2

Then I will receive a below response.

<ams:fault xmlns:ams="http://wso2.org/apimanager/security">
     <ams:code>900902</ams:code>
     <ams:message>Missing Credentials</ams:message>
     <ams:description>Required OAuth credentials not provided</ams:description>
</ams:fault>

That means Your api is secured. So you need to provide the access token to invoke the service. You can find the access token in subscription page.

Then invoke the service with below command.

curl  -H "Authorization :Bearer gQsoJqhYv15f_JiEVg46y44olcUa" http://localhost:8280/stockQuote/1.0.0?symbol=wso2

Now I get the correct response which is provided by my actual backend service running on tomcat server.

<getQuoteResponse>
      <symbol>wso2</symbol>
      <lastPrice>147.95183566530514</lastPrice>
      <company>wso2 Company</company>
      <timeStamp>Wed Mar 26 18:32:30 IST 2014</timeStamp></getQuoteResponse>

As the below api, You can create any number of api to secure your services. It is very easy and useful.