Wednesday, May 11, 2016

How to deal with spaces when doing conversions from json to xml or wise versa in WSO2 ESB

In this blog post what I'm going to mention is a valuable feature which resides in WSO2 ESB.

When we think of json, we can have spaces in json element names, for example, below is a valid json string
{
  "abc def" : "this is a sample value"
}
but when we think about XML specification [1], [2], XML element names cannot have spaces, In WSO2 ESB we can convert json to xml and vise versa, so how are we going to convert above mentioned json(with space for json element name) and have a valid XML string,

What we have to do is simple, we have to specify "synapse.commons.json.buildValidNCNames" to value "true" in "$ESB_HOME/repository/conf/synapse.properties" file, then ESB will do the conversion as follows
input Json -
 
{
  "abc def" : "this is a sample value"
}
output XML -
 
this is a sample value

And this works other way around as well, say you need to convert XML to json and json element should need to have a space within it, then you can use "_JsonReader_32_" in xml to get the space in json output, for example,
input xml -
 
this is a sample value
output json -
  
{
  "abc def" : "this is a sample value"
}

For your reference below is a sample API configuration which will convert json input and send you back converted xml



    
        
            
            
            
        
        
        
        
    

you can invoke above API using a Rest client with POST url "http://localhost:8280/sample3/abc" and a json payload. Hope this helps

[1] - https://www.w3.org/TR/REC-xml/#sec-common-syn
[2] - http://www.w3schools.com/xml/xml_elements.asp

Wednesday, July 8, 2015

Enable CORS WSO2 Data services server

This post is about how to enable CORS in Wso2 Data Services server.

I'll explain in point form as it will be easy for readers to understand and test the scenario. (I have tested this in DSS 3.2.2 version)

1) downloaded "cors-filter-2.4.jar" and "java-property-utils-1.9.1.jar" from the site [1] and added those jars to DSS/repository/components/lib folder

2) added below config elements to DSS/repository/conf/tomcat/web.xml file
   
  CORS
  com.thetransactioncompany.cors.CORSFilter  
 


        CORS
        /*

3) restarted the DSS and then CORS will work fine now

PS - you can fine tune url pattern to allow this to limited url patterns. for example you can use pattern as below
/services/*
using this you can fine tune it to allow CORS for only some of the services hosted in DSS

[1] - http://software.dzhuvinov.com/cors-filter-installation.html

Hope this helps :-)

Wednesday, June 17, 2015

Use Intellij IDEA to make your debugging life easy

Here is a simple tip which will make it easy to debug codes and try out new things in Intellij IDEA

First thing is we can use Intellij IDEA to remote debug codes which runs in servers. But this post is not about configuring remote debugging in Intellij IDEA.

Lets take an example - We use WSO2 server, say WSO2-AS. We are remote debugging an application we deployed in AS for a issue with IDEA. Say we find the solution. Normal procedure is to implement the solution, build it, and redeploy it. But this may take considerable amount of time. But using Intellij Idea, we can reduce this burden. What we have to do is attach IDEA remote debugger to AS, implement the required code and then compile that code within IDEA. After compiling the code IDEA will automatically reloads the attached JVM's class instance with newly compiled code.

This makes life easy, as we don't need to rebuild and redeploy codes to apply the changes.

Bellow are the steps listed down again for clarity

1) Attach IDEA remote debugger to the server
2) Do the required code change in the source
3) Compile the code within IDEA (You can do this by right clicking on the class and select "compile")

And that's it, IDEA will reload the attached JVM with newly changed class.

Notes -
1) We can't use this method to reload big changes done on the source. Say like implementing new class, adding new dependency etc
2) This method will be very much useful in scenarios where we even have to restart the servers to apply changes. Say debugging component issues in wso2 products.
3) This reload only affects current running JVM instance. If we restart the server, these changes will be gone as server will reload original classes from bundles

Monday, May 11, 2015

Writing a custom Grant Handler for WSO2 APIM

Here is a how to guide for writing custom grant handler to WSO2 APIM

I have used WSO2 APIM 1.8 for this example

Simply what you have to do is as follows

1) Implement the "org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler" api class in bundle "org.wso2.carbon.identity.oauth" versoin "4.3.2". Maven dependency for this would be



            org.wso2.carbon.identity

            org.wso2.carbon.identity.oauth

            4.3.2



to simplify, instead of implementing the above api class you can extend the "org.wso2.carbon.identity.oauth2.token.handlers.grant.AbstractAuthorizationGrantHandler" class which will be an abstract class implemented on "AuthorizationGrantHandler" api. This class will have the basic implementation we need. So we can simply extend this class, override methods we need, call the super method withing those implementations so that default implementation(which is in abstract class "AbstractAuthorizationGrantHandler") will get called.

Basic method we need to override will be "public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception" method.

Below is a sample implementation of this scenario

public class CustomGrantHandler extends AbstractAuthorizationGrantHandler {    

    @Override
    public boolean validateGrant(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception {        

        super.validateGrant(tokReqMsgCtx);

        //Things you need to do 
        return true;
    }

    @Override
    public boolean validateScope(OAuthTokenReqMessageContext tokReqMsgCtx) {
        ScopesIssuer scopesIssuer = new ScopesIssuer();
        return scopesIssuer.setScopes(tokReqMsgCtx);
    }

    @Override
    public boolean authorizeAccessDelegation(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception {
        
        //things you need to do
        return true;
    }   
}

Here within the "tokReqMsgCtx" object you will have all the request parameters you need. as a array of "org.wso2.carbon.identity.oauth2.model.RequestParameter" objects.
You can access this object array as follows

tokReqMsgCtx.getOauth2AccessTokenReqDTO().getRequestParameters();


2) Implement  "org.apache.amber.oauth2.common.validators.OAuthValidator" api class in bundle "amber" which will be imported via above mentioned "oauth" dependency. Then override required methods.

3) bundle them to a jar file and deploy it into "<APIM_HOME>/repository/components/lib" folder

4) add this custom authenticator to "<APIM_HOME>/repository/conf/identity.xml" file under "<SupportedGrantTypes>" element as follows.


    {grant_type_name}
    {your custom grant handler implementation}
    {your custom oauth validator implemention}
 

sample would be as follows

        
 custom_grant
        com.custom.grant.handler.handlers.CustomGrantHandler
        com.custom.grant.handler.handlers.CustomValidator



Restart APIM and you are set. Invoke the token api with your custom request with providing grant type as "custom_grant" and this handler will get invoked. Sample will be as follows

curl -k -d "grant_type=custom_grant" -H "Authorization: Basic YlB5NzZGNmYyRHYzMmJLeXFSaXVnVWJmM1pRYTpueXFWZ3Y0TTRldFdhRV9JS2NFNXBPYmYyVEVh, Content-Type: application/x-www-form-urlencoded" https://localhost:8244/token

There is an important point you have to take into notice. If you are extending "org.wso2.carbon.identity.oauth2.token.handlers.grant.AbstractAuthorizationGrantHandler" class instead of implementing "org.wso2.carbon.identity.oauth2.token.handlers.grant.AuthorizationGrantHandler" api, then make sure you are overriding the method "public boolean authorizeAccessDelegation(OAuthTokenReqMessageContext tokReqMsgCtx)
            throws IdentityOAuth2Exception" and not invoking the super method within the implementation. Reason is, in the "AbstractAuthorizationGrantHandler" abstract class, there is a implementation for above method which validates the grant type against wso2 custom grant types and oauth2 grant types. Since which we write is a custom grant type, it won't be there in the default wso2 implementations. So the validation fails. Overriding the method will resolve that problem as mentioned above.

Another side note if you are going to use IS as keymanager setup.
Then you'll need to have this custom implementation in IS instead of APIM. for that, do the following.(Needs to have IS 5 for this)

1) Create a IS as a keymanager setup as instructed in [1]

2) copy the jar bundle you created with your custom implementations to "<IS_HOME>/repository/components/lib" folder

3) follow the step 4) for the APIM instructions above and change "identity.xml" file inside "<IS_HOME>/repository/conf" folder and add the "SupportedGrantType" as instructed.

Restart the IS and you are set.

Hope this will be some help for the people who struggles trying to write custom grant handlers for APIM or IS

[1] - https://docs.wso2.com/display/CLUSTER420/Configuring+WSO2+Identity+Server+as+the+Key+Manager


Monday, March 3, 2014

WSO2 ESB Performance round 7.5


The latest performance test results indicates that the WSO2 ESB outperforms all other existing ESBs. The test results has been published by WSO2 - WSO2 ESB Performance Round 7.5

These tests have been done on various indicators with various ESBs around the globe. All of them are leading opensource ESBs. As the following results indicate WSO2 ESB outperforms all the other open source ESBs around the globe


Thursday, January 23, 2014

How to write Simple Axis2 Service

Since I have struggled writing an Axis2 service, I thought of preserving and sharing the knowledge I acquired.

Let's begin,

There are so many tutorials explaining how to write an Axis2 services but they seems not adequate for a beginner in Axis2. So I'll take an step by step approach.

Step one
downloading all necessary and required resources. (in this post I'm not going to use axis2 server directly, I'm going to use Apache Tomcat server as the server and use Axis2 as a service inside it and host my service inside Tomcat)

1) so you should need Apache Tomcat, download it from here (since I am using jdk6, I had to use Tomcat 7 or below)
2) Download Axis2 WAR distribution zip and Binary distribution zip from here (download the latest version, in this example I used 1.6.2)

Step two
when you creates an axis2 service you simply have to create the service and define the service in a services.xml then you can package them to a "aar" package using maven "axis2-aar-maven-plugin".

In a web service we invoke a method in a class. So here comes the question, how do we pass parameters to that method and how can we return a result from that, should we only use String format? or can we use objects for that purpose? actually that was the question I faced when creating my first axis2 service.

The answer is you can use any type of objects as your input to the axis2 service and you can return any kind of object from the service. But as I learn there is a exception, we cannot use Collections in those input parameters or return values. Reason for that is Axis2 use its own object processor and it cannot handle collections.

Step three
So lets begin coding :)
first create a folder and file structure as given below

Image 1 - Folder Structure
Don't worry about the contents of files such as pom.xml, service.xml yet, just create the above structure. I think you will understand the above structure. I'll give a simple description

Since I'm creating a maven project there is that pom.xml. The services.xml file I mentioned above is located in resources--> META-INF folder there is a log4j.properties file in case we use log4j for logging purposes and finally there is the Orderservice.java class which contains the service methods and a bean class which I'm intend to use as a return value of my service

Step four
using any of your favorite editors, edit the pom.xml file as below


    4.0.0


    
        1.6
        1.0-SNAPSHOT
        1.2.17
    


    service
    axis2_service
    ${SERVICE_VERSION}
    aar
    Axis2 Server App


    
        
            log4j
            log4j
            ${log4j.version}
        

    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                2.5.1
                
                    ${JDK_VERSION}
                    ${JDK_VERSION}
                    

                    
                
            
            
                org.apache.axis2
                axis2-aar-maven-plugin
                1.4
                true
                
                    OrderService
                
                
                    
                        create-aar1
                        install
                        
                            aar
                        
                        
                            
                                OrderService
                            
                            
                                src/main/resources/META-INF/services.xml
                            
                            false
                        
                    
                
            

            
                org.apache.maven.plugins
                maven-dependency-plugin
                2.5.1
                
                    
                        copy-dependencies
                        package
                        
                            copy-dependencies
                        
                        
                            log4j
                            ${project.build.directory}/dependency-jars/
                        
                    
                
            
        

    



I think the pom file is also self explanatory. but for the sake of this post I'll give some brief introduction

There is only one dependency for the log4j library. And there are three plugins, maven compiler plugin for the compilation process, maven dependency plugin to copy dependencies to the final package, and finally "axis2-aar-maven-plugin" to create the "aar" bundle. It's straight forward, as you can see I have given the path where my services.xml file reside and given the OrderService as "aar" file a name, thats pretty much it.

Step five
Now let's move on to OrderService.java class, edit it as below

public class OrderService {
    public static Logger logger = Logger.getLogger(OrderService.class);
    
    public BuyResponse buyProduct(int requestType, String productName, int quantity) {
        logger.info("OrderService::buyProduct --> process invoked, requestType - " + requestType + " productName - " + productName + " quantity - " + quantity);
        //what ever u need to do with the data anc create the return object


        BuyResponse response = new BuyResponse();
        response.setStatus("success");
        response.setPrice(45);

        return response;
    }


}

Little bit about the code. In OrderService.java class there is a method called buyProduct. that's our service method. when ever we invoke our orderservice this method get invoked. So when we are going to invoke this service we have to provide those parameters, requestType, productName, quantity

If you think this parameter declaration is not a correct way, you can create one single object and use that as a parameter as given below

    public BuyResponse buyProduct(BuyProductRequest req) {
        logger.info("OrderService::buyProduct --> process invoked, requestType - " + requestType + " productName - " + productName + " quantity - " + quantity);
        //what ever u need to do with the data anc create the return object


        BuyResponse response = new BuyResponse();
        response.setStatus("success");
        response.setPrice(45);

        return response;
    }


Now we have created our web service implementation.

Step six
Then we have to mention about the service in "services.xml" file as given below

   

  service.impl.OrderService
  
    
  



There are two xml elements parameter element and operation element. In parameter element we define which is the service class. In operation element we define which are the service methods in the service class.

That's it almost finished, let's build it and deploy it.

Step seven
use maven to build the project (mvn install)

1) Unzip the downloaded Tomcat distribution. 
2) Unzip the downloaded axis2-1.6.2-war.zip file
3) Copy axis2.war file inside that in to the tomcat distribution's webapps directory.
Next step is to start tomcat server. To do that run the startup.sh or startup.bat file depending on whether you work in windows or Linux which reside inside tomcat distribution's bin directory.

Then go to this (http://localhost:8080/axis2/axis2-admin/) url and login with username admin and password axis2

Then go to Upload Service link and upload the "OrderService.aar" file which is inside target directory of your project.

It's done :) you have successfully created and deployed an axis2 service
In my next blog post I'll show you how to create a client application to consume this web service. 

(for your convenience I have attached the full source code for above example here)


Tuesday, November 12, 2013

How to use Intellij idea Live templates to make your life easy

Hi,
As to begin with this is my very first blog post. Here I'm going to explain how to use the concept of Live Templates in intellij idea IDE to make your coding life easy. (in this example I'm working with intellij idea version 12.1.4)

This is a feature which is in intellij idea IDE although people doesn't take full use of it.

Lets begin with an example. Intellij idea already have some live templates embedded with it. For example open one of your java classes in the editor and type "itar" as shown in below image

Image 1 - Example of using Live Template

Then press tab key and you'll see a iteration block generated as shown below.

Image 2 - After Live Template get expanded

This is an existing live template in intellij idea. Don't be amazed you can do lot more things by creating these kinds of customized Live templates.
So lets begin creating our own live template. I will keep to a step by step approach so it will be easy for you to grab.

1. First go to intellij idea settings window by File --> Settings (or by pressing ctrl+alt+s  keys together) using either way you will be directed to the settings window,

2. In the left pane there, find the list item called "Live Templates", which resides under "IDE settings", Once you click on that you'll get a window as shown below.

Image 3 - Settings window

Here you will see the existing live templates are grouped in to several groups in the right side pane. Examine them by expanding those nodes and clicking on those live templates. You will be able to get an idea of how they are formed.

3. There you will see a plus sign as marked in the above image in black. By clicking it you can create your own Live template. Resultant window is shown below.

Image 4 - Newly created Live Template

As you can see intellij idea will create a new group called "user" and create your new template inside it. Don't worry about the group though.
In this example I'm going to create a live template which can be used in the beginning of a method to check whether the given parameter is null or empty and if so throw and Exception after logging what happened there(this can be used for validation purposes).

4. Put the abbreviation you would like to use for invoking this live template in the abbreviation text box. Keeping this simple and short will be helpful since this will be the text you have to type to invoke the template using the tab key. For this example I'll put "cifne" (my way of shorting "Custom IF Null or Empty",  :-) )

5. Then put a description of what you are going to accomplish using the live template in the Description text box

6. We can define our own variables in these templates by enclosing them between two dollar marks
("$TEMP$" would be a variable), so that you can assign their values dynamically according to the context where they are going to be used rather than hard coding them. For example we can get the class name of the class we are going to use this template and use it as a template value.
Enough talking let's do some real coding

if ($VAR$ == null || $VAR$.equalsIgnoreCase("")) {
    logger.error("$CLASS_NAME$::$METHOD_NAME$ --> Error given $VAR$ is null or empty");
    throw new $EXEPTION$("$CLASS_NAME$::$METHOD_NAME$ --> Error given $VAR$ is null or empty");
}

7. Put the above code segment in to the template text field, you will be able to recognize the variable fields I have defined in the above code segment. Now lets see how to edit those variable values so that they will be automatically filled up when you use the template. You will see a "Edit variables" button is disabled in the above image (Image 4). After you put the code segment in template text, that button gets enabled. That's where you can edit those variables. Clicking that button will pop up a window as below, though it wont be filled up as below.

Image 5 -Edit variables

8. In the "Name" column it is the names of the variables which resides in the template text code segment, in the "Expression" column we can put expressions which will execute automatically and assign appropriate values to those variables according to the context. In the default column has the default values for those variables, those can be either generated values as "Expression" column or hard coded values, next column name is self explanatory.

9. There are so many methods we can use in the above "Expression" column, methods to retrieve class name, methods to suggest variable names, methods to retrieve current method name etc
you can find a list of usable methods in the jetbrains official web site - http://www.jetbrains.com/idea/webhelp/edit-template-variables-dialog.html
in this example I have used methods to retrieve class name, current method name, exception type and object type.

10. You can also change the way we intend to expand the live template, (default key is "Tab" key) in the "Options" section "Expand with" drop down list

11. Then its better to define applicable context. click the "Define" link in the window as marked in the image (Image 5), there you can mark the context where you want this template to apply. As you can see in the below image, in this example I have selected the "java-statement" context and "groovy-statement" context. you can define the context where you wish to use the template accordingly.

Image 6 - Selecting Context

12. Almost forgot. how are we going to use this template? Lets see. Assume we have a method which has a "String" parameter as an input. Then we have to validate that parameter and give a fair warning, not to mention that we have to log the incident too. So as you can see in the below image type "cifne" at the start of the method and press "Tab" key then intellij idea will expand the template you created and let you fill the empty slots that it cannot generate by itself and even it will suggestions to you for filling them.

Image 7 - Final outcome

Amazing isn't it? how the technology can ease our life. have fun with Live Templates