Friday, February 27, 2015

Getting Started with SonarQube

What is SonarQube?
SonarQube is an open platform to manage code quality. It covers following aspects of a project
  1. Architecture and Design
  2. Duplication
  3. Unit Testing
  4. Complexity
  5. Potential Bugs
  6. Coding Rules
  7. Comments
There are about 20 plugins available for SonarCube to analyze most of the common programming languages such as Java, C#, C++ etc..

Analyzing a Project with SonarQube Runner
Prerequisites
  • Java should be installed on your machine
First go to the SonarQube official site and download the SonarQube and SonarQube Runner
Extract both SonarQube and SonarQube runner to desired locations. In my machine I've extracted SonarQube to 
/home/thusitha/Training/sonarqube-5.0
and SonarQube Runner to
/home/thusitha/Training/sonar-runner-2.4

Inside the SonarQube you can find there are many directories for each platform. Find the matching platform based on your OS. 
e.g.
If you are using ubuntu x64 bit OS then you must go to linux-x86-64 directoty

Go to the particular directory through the console and run the Sonar script to start the Sonar sever
To start the server run the sonar script in the directory
In Linux
sh sonar.sh console

In Windows
StartSonar.bat

Then open your browser and type following URL there. If Sonar server started successfully you will direct to Sonar dashboard.
Sonar Dashboard http://localhost:9000/

Now go to the project root folder that you want to analyze and create a file and name it as 
sonar-project.properties and have following content to that file In the file you can provide details relate to your project.
Then we can run SonarQube Runner to analyze the project using this file. To do that run the following command from the location where the created file resides.
On Linux
sonar-runner

On Windows
sonar-runner.bat


After a successful execution you can see the project and its' status on the Sonar Dashboard. In the dashboard you can go through the issues etc...

Tuesday, February 24, 2015

Writing First WSO2 Carbon Component

What is Carbon?
WSO2 Carbon is the award-winning, component-based, service oriented platform for the enterprise-grade WSO2 middleware products stack. It is 100% open source and delivered under Apache License 2.0. The WSO2 Carbon platform is lean, high-performant and consists of a collection of OSGi bundles.  - WSO2
Prerequisites
  • Java
  • Maven
  • IDE (eclipse/IdeaJ or any other IDE that supports maven project)
  • Internet connection
  • Any WSO2 Carbon product (I'm using WSO2 Application server. You can download any product that you like from WSO2 products page)
Getting Started
Here I'm going to create a simple order manager carbon component. This will consist of 3 modules.
  1. Back-end service
  2. Service stub
  3. Front-end (UI) 
I'm using Intellij IdeaJ IDE in order to create the project but you can use any IDE that you prefer.

Create a new maven project and give appropriate group ID and artifact ID. I'm using following group id and artifact id. These are very basic names. (Not based on standards naming conventions) You can use anything that you like.
 <groupId>org.wso2.carbon.sample</groupId>  
 <artifactId>ordar-manager</artifactId>  

After creating the maven project you can delete the src folder if you like, because this will not contain any source code.
After creating the main project we must add 3 modules to that project. Make sure you set the parent of each module as the main project that was created first. If you are using IdeaJ, select the main project and then select File -> New Module. It will correctly point to the parent project. You just have to give the artifact Id.
In my project my modules are as follows

Back end Service Module
 <parent>  
    <artifactId>ordar-manager</artifactId>  
    <groupId>org.wso2.carbon.sample</groupId>  
    <version>1.0-SNAPSHOT</version>  
 </parent>  
 <artifactId>backend</artifactId>  

Service Stub
 <parent>  
    <artifactId>ordar-manager</artifactId>  
    <groupId>org.wso2.carbon.sample</groupId>  
    <version>1.0-SNAPSHOT</version>  
 </parent>  
 <artifactId>service-stub</artifactId>  

Front end
 <parent>  
    <artifactId>ordar-manager</artifactId>  
    <groupId>org.wso2.carbon.sample</groupId>  
    <version>1.0-SNAPSHOT</version>  
 </parent>  
 <artifactId>frontend</artifactId>  

After adding the 3 modules your pom file of the main project should be similar to
 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns="http://maven.apache.org/POM/4.0.0"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
   <modelVersion>4.0.0</modelVersion>  
   <groupId>org.wso2.carbon.sample</groupId>  
   <artifactId>ordar-manager</artifactId>  
   <packaging>pom</packaging>  
   <version>1.0-SNAPSHOT</version>  
   <modules>  
     <module>Backend</module>  
     <module>ServiceStub</module>  
     <module>Frontend</module>  
   </modules>  
 </project>  

1. Creating the Back-end Service
My service class is OrderManager. I've created that inside the org.wso2.sample.carbon.order.manager package. This will have 2 service methods. One to add Items and other one is to retrieve the existing Items.

Item class
 package org.wso2.sample.carbon.order.manager.beans;  
 
 import java.io.Serializable;  
   
 public class Item implements Serializable{  
   private int no;  
   private String name;  
   private float price;  

   public Item(int itemNo, String itemName, float itemPrice) {  
     this.no = itemNo;  
     this.name = itemName;  
     this.price = itemPrice;  
   }
  
   public Item(){}  

   public int getNo() {  
     return no;  
   }  

   public void setNo(int no) {  
     this.no = no;  
   }
  
   public String getName() {  
     return name;  
   }
  
   public void setName(String name) {  
     this.name = name;  
   }
  
   public float getPrice() { return price; }  

   public void setPrice(float price) {  
     this.price = price;  
   }  
 }  

Note
I have implement the Serializable interface, since I'm going to use Carbon registry to store the Items in the registry.
Other thing to remember is if you overload the default constructor, You must explicitly define the default constructor, since you must adhere to the JavaBeans standards, which are use in underlying Axis2.

OrderManager class
 package org.wso2.sample.carbon.order.manager;

import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.context.RegistryType;
import org.wso2.carbon.registry.api.Registry;
import org.wso2.carbon.registry.api.RegistryException;
import org.wso2.carbon.registry.api.Resource;
import org.wso2.sample.carbon.order.manager.beans.Item;

import java.io.*;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

public class OrderManager {
    private static int orderID = 1;
    Registry registry = null;
    private static final String ORDER_PATH = "order_location";

    private static Logger logger = Logger.getLogger(OrderManager.class.getName());

    public OrderManager() {
        HashMap orders = new HashMap();

        orders.put(orderID++, new Item(1, "LG G3", 99900.00f));
        orders.put(orderID++, new Item(3, "Iphone 6", 102000.00f));
        orders.put(orderID++, new Item(3, "Sony Z3", 80000.00f));
        orders.put(orderID++, new Item(4, "Nexus 6", 112000.00f));
        orders.put(orderID++, new Item(5, "HTC M8", 88000.00f));

        registry = CarbonContext.getThreadLocalCarbonContext().getRegistry(RegistryType.valueOf(RegistryType.LOCAL_REPOSITORY.toString()));

        try {
            Resource orderRes = registry.newResource();
            orderRes.setContent(serialize(orders));
            registry.put(ORDER_PATH, orderRes);
        } catch (RegistryException e) {
            logger.log(Level.SEVERE, e.getMessage());
        } catch (IOException e) {
            logger.log(Level.SEVERE, e.getMessage());
        }
    }

    public Item[] getOrders() {
        Resource orderRes = null;
        try {
            orderRes = registry.get(ORDER_PATH);
            if (orderRes != null) {
                HashMap tmp = (HashMap) deserialize((byte[]) orderRes.getContent());
                return tmp.values().toArray(new Item[tmp.values().size()]);
            }
        } catch (IOException e) {
            logger.log(Level.SEVERE, e.getMessage());
        } catch (ClassNotFoundException e) {
            logger.log(Level.SEVERE, e.getMessage());
        } catch (RegistryException e) {
            logger.log(Level.SEVERE, e.getMessage());
        }
        return new Item[]{};
    }

    public void addOrder(Item item) {
        Resource orderRes = null;
        try {
            orderRes = registry.get(ORDER_PATH);
            if (orderRes != null) {
                HashMap tmp = (HashMap) deserialize((byte[]) orderRes.getContent());
                tmp.put(orderID++, item);
                orderRes.setContent(serialize(tmp));
                registry.put("orders_location", orderRes);
            }
        } catch (RegistryException e) {
            logger.log(Level.SEVERE, e.getMessage());
        } catch (ClassNotFoundException e) {
            logger.log(Level.SEVERE, e.getMessage());
        } catch (IOException e) {
            logger.log(Level.SEVERE, e.getMessage());
        }
    }

    private static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    private static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return o.readObject();
    }
}
 

Since we are using Carbon registry following dependencies should be added to the back-end module.
 <dependencies>  
     <dependency>  
       <groupId>org.wso2.carbon</groupId>  
       <artifactId>org.wso2.carbon.registry.core</artifactId>  
       <version>4.2.0</version>  
     </dependency>  
     <dependency>  
       <groupId>org.wso2.carbon</groupId>  
       <artifactId>org.wso2.carbon.registry.api</artifactId>  
       <version>4.2.0</version>  
     </dependency>  
 </dependencies>  
Remember to use byte arrays when you are storing the values in the Carbon registry.

Now we should write the service configuration (services.xml) for our service.
Create a folder called META-INF inside the resource folder of the back-end module. Inside the META-INF folder create services.xml file with following content. Change the service and service class names according to your project.

services.xml
 <serviceGroup>  
   <service name="OrderManager" scope="transportsession">  
     <transports>  
       <transport>https</transport>  
     </transports>  
     <parameter name="ServiceClass">org.wso2.sample.carbon.order.manager.OrderManager</parameter>  
   </service>  
   <parameter name="adminService" locked="true">true</parameter>  
   <parameter name="hiddenService" locked="true">true</parameter>  
   <parameter name="AuthorizationAction" locked="true">/permission/protected/manage</parameter>  
 </serviceGroup>  

Now we must package the back-end module as a OSGI bundle. We are using maven-bundle-plugin to do that. We should also mentioned what are the packages that we are exporting from this module.
After adding the dependency and the plugin, pom file of the back-end module will be similar to following pom.
 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns="http://maven.apache.org/POM/4.0.0"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
   <parent>  
     <artifactId>ordar-manager</artifactId>  
     <groupId>org.wso2.carbon.sample</groupId>  
     <version>1.0-SNAPSHOT</version>  
   </parent>  
   <modelVersion>4.0.0</modelVersion>  
   
   <artifactId>backend</artifactId>  
   <packaging>bundle</packaging>  
   
   <dependencies>  
     <dependency>  
       <groupId>org.wso2.carbon</groupId>  
       <artifactId>org.wso2.carbon.registry.core</artifactId>  
       <version>4.2.0</version>  
     </dependency>  
     <dependency>  
       <groupId>org.wso2.carbon</groupId>  
       <artifactId>org.wso2.carbon.registry.api</artifactId>  
       <version>4.2.0</version>  
     </dependency>  
   </dependencies>  
   
   <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.felix</groupId>  
         <artifactId>maven-bundle-plugin</artifactId>  
         <extensions>true</extensions>  
         <configuration>  
           <instructions>  
             <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>  
             <Bundle-Name>${pom.artifactId}</Bundle-Name>  
             <Export-Package>org.wso2.sample.carbon.order.manager.*</Export-Package>  
           </instructions>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  

Now go to the back-end module pom file location from the terminal and use mvn clean install to build the module. If the build get success you will get a jar file like backend-1.0-SNAPSHOT.jar inside the target directory.
Then copy the created jar file to repository/components/dropins directory in the WSO2 product that you are using. Since I'm using WSO2 AS full path is like /home/thusitha/WSO2/wso2as-5.2.1/repository/components/dropins

We can't see the WSDL file of the created service directly accessing the https://localhost:9443/services/OrderManager?wsdl . That is because we have added this as a admin service and by default admin services WSDLs are hidden. In order to view the WSDL file open the carbon.xml file in the repository/conf and set the value of HideAdminServiceWSDLs as false
 <HideAdminServiceWSDLs>false</HideAdminServiceWSDLs>  

Now start the WSO2 AS and put the above URL in the browser (last part should be the Service name that you provide in the services.xml). Save the WSDL file in the disk. I'm saving it inside the resource folder of the service-stub module.
(If you want to check whether your service works as you expected, you can use SOAP UI like a tool. It is easy to comment out AutorizationAction in the services.xml if you do so)

2. Creating the Service-stub
We are using wsdl2java utility to create the stub. Other than that axiom, axis2, maven-antrun-plugin, build-helper-maven-plugin and maven-bundle-plugin are used.
Use following repository in the pom file of service-stub module.
 <repository>  
       <id>wso2-nexus</id>  
       <name>WSO2 internal Repository</name>  
       <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>  
       <releases>  
         <enabled>true</enabled>  
         <updatePolicy>daily</updatePolicy>  
         <checksumPolicy>ignore</checksumPolicy>  
       </releases>  
 </repository>  

At the end pom file of the service-stub module should be look like

 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns="http://maven.apache.org/POM/4.0.0"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
   <parent>  
     <artifactId>ordar-manager</artifactId>  
     <groupId>org.wso2.carbon.sample</groupId>  
     <version>1.0-SNAPSHOT</version>  
   </parent>  
   <modelVersion>4.0.0</modelVersion>  
   <packaging>bundle</packaging>  
   <artifactId>service-stub</artifactId>  

   <repositories>  
     <repository>  
       <id>wso2-nexus</id>  
       <name>WSO2 internal Repository</name>  
       <url>http://maven.wso2.org/nexus/content/groups/wso2-public/</url>  
       <releases>  
         <enabled>true</enabled>  
         <updatePolicy>daily</updatePolicy>  
         <checksumPolicy>ignore</checksumPolicy>  
       </releases>  
     </repository>  
   </repositories>  

   <dependencies>  
     <dependency>  
       <groupId>org.apache.axis2.wso2</groupId>  
       <artifactId>axis2</artifactId>  
       <version>1.6.1.wso2v10</version>  
     </dependency>  
     <dependency>  
       <groupId>org.apache.axis2.wso2</groupId>  
       <artifactId>axis2-client</artifactId>  
       <version>1.6.1.wso2v10</version>  
     </dependency> 
     <dependency>  
       <groupId>org.apache.ws.commons.axiom.wso2</groupId>  
       <artifactId>axiom</artifactId>  
       <version>1.2.11.wso2v4</version>  
     </dependency>  
     <dependency>  
       <groupId>wsdl4j.wso2</groupId>  
       <artifactId>wsdl4j</artifactId>  
       <version>1.6.2.wso2v4</version>  
     </dependency>  
   </dependencies>  

   <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-antrun-plugin</artifactId>  
         <version>1.1</version>  
         <executions>  
           <execution>  
             <id>source-code-generation</id>  
             <phase>process-resources</phase>  
             <goals>  
               <goal>run</goal>  
             </goals>  
             <configuration>  
               <tasks>  
                 <path id="wsdl2java.classpath">  
                   <pathelement location="${settings.localRepository}/org/apache/ws/commons/axiom/wso2/axiom/1.2.11.wso2v4/axiom-1.2.11.wso2v4.jar"/>  
                   <pathelement location="${settings.localRepository}/org/apache/axis2/wso2/axis2-client/1.6.1.wso2v10/axis2-client-1.6.1.wso2v10.jar" />  
                   <pathelement location="${settings.localRepository}/org/apache/axis2/wso2/axis2/1.6.1.wso2v10/axis2-1.6.1.wso2v10.jar" />  
                 </path>  
                 <java classname="org.apache.axis2.wsdl.WSDL2Java" fork="true">  
                   <classpath refid="wsdl2java.classpath" />  
                   <arg line="-uri src/main/resources/OrderManager.wsdl -u -uw  
                    -o target/generated-code -p org.wso2.sample.carbon.order.manager.stub"/>  
                 </java>  
               </tasks>  
             </configuration>  
           </execution>  
         </executions>  
       </plugin>  
       <plugin>  
         <groupId>org.codehaus.mojo</groupId>  
         <artifactId>build-helper-maven-plugin</artifactId>  
         <executions>  
           <execution>  
             <id>add-source</id>  
             <phase>generate-sources</phase>  
             <goals>  
               <goal>add-source</goal>  
             </goals>  
             <configuration>  
               <sources>  
                 <source>target/generated-code/src</source>  
               </sources>  
             </configuration>  
           </execution>  
         </executions>  
       </plugin>  
       <plugin>  
         <groupId>org.apache.felix</groupId>  
         <artifactId>maven-bundle-plugin</artifactId>  
         <extensions>true</extensions>  
         <configuration>  
           <instructions>  
             <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>  
             <Bundle-Name>${project.artifactId}</Bundle-Name>  
             <Private-Package>  
             </Private-Package>  
             <Export-Package>  
               org.wso2.sample.carbon.order.manager.*  
             </Export-Package>  
             <Import-Package>  
               !org.wso2.sample.carbon.order.manager.*  
             </Import-Package>  
             <DynamicImport-Package>*</DynamicImport-Package>  
           </instructions>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  
In the above pom file you can see that I've used the previously saved WSDL file. Do the necessary modifications to the pom file according to the your project.
Go to pom file location of the service-stub and do a maven clean build. If you check the target folder inside the service stub module you can see the generated stub there. Final step is to create the UI to access the created service.

3. Creating the Front-end (UI)
We need to add the service stub module as a dependency to the front-end module since we need to use the generated stub to access the service.  To do that open the pom file of the front-end module and add the service-stub as follows
 dependency>  
       <groupId>org.wso2.carbon.sample</groupId>  
       <artifactId>service-stub</artifactId>  
       <version>1.0-SNAPSHOT</version>  
 </dependency>  

Finally full pom file of the front-end module should be like
 <?xml version="1.0" encoding="UTF-8"?>  
 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns="http://maven.apache.org/POM/4.0.0"  
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
   <parent>  
     <artifactId>ordar-manager</artifactId>  
     <groupId>org.wso2.carbon.sample</groupId>  
     <version>1.0-SNAPSHOT</version>  
   </parent>  
   <modelVersion>4.0.0</modelVersion>  
   
   <artifactId>frontend</artifactId>  
   <packaging>bundle</packaging>  
      
   <dependencies>  
     <dependency>  
       <groupId>org.wso2.carbon.sample</groupId>  
       <artifactId>service-stub</artifactId>  
       <version>1.0-SNAPSHOT</version>  
     </dependency>  
   </dependencies>  
   
   <build>  
     <plugins>  
       <plugin>  
         <groupId>org.apache.felix</groupId>  
         <artifactId>maven-bundle-plugin</artifactId>  
         <extensions>true</extensions>  
         <version>2.5.3</version>  
         <configuration>  
           <instructions>  
             <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>  
             <Bundle-Name>${project.artifactId}</Bundle-Name>  
             <Export-Package>  
               org.wso2.sample.carbon.order.manager.*  
             </Export-Package>  
             <Import-Package>  
               *;resolution:=optional  
             </Import-Package>  
             <Carbon-Component>UIBundle</Carbon-Component>  
           </instructions>  
         </configuration>  
       </plugin>  
     </plugins>  
   </build>  
 </project>  

Next I'm creating the Client inside the front-end module, which will use the generated stub to access the back-end service.

Client class
 package org.wso2.sample.carbon.order.manager.ui;  
   
 import org.apache.axis2.client.Options;  
 import org.apache.axis2.client.ServiceClient;  
 import org.apache.axis2.context.ConfigurationContext;  
 import org.apache.axis2.transport.http.HTTPConstants;  
 import org.wso2.sample.carbon.order.manager.beans.xsd.Item;  
 import org.wso2.sample.carbon.order.manager.stub.OrderManagerStub;  
   
 import java.rmi.RemoteException;  
   
 public class Client {  
   private OrderManagerStub stub;  
   
   public Client(ConfigurationContext ctx, String backendServerUrl, String cookie) throws Exception{  
     String serviceUrl = backendServerUrl + "OrderManager";  
     stub = new OrderManagerStub(ctx, serviceUrl);  
     ServiceClient serviceClient = stub._getServiceClient();  
     Options options = serviceClient.getOptions();  
     options.setManageSession(true);  
     options.setProperty(HTTPConstants.COOKIE_STRING, cookie);  
   
   }  
   
   public Item[] getItems() throws RemoteException {  
     return stub.getOrders();  
   }  
   
   public void addItem(Item item) throws RemoteException {  
     stub.addOrder(item);  
   }  
 }  
   

Then create a directory named web inside resource folder. Inside the web folder, create another directory and named it as order-manager.
Create a file names index.jsp inside that. This is the jsp page that consist of the UI part. I will have a table of existing Items and a form to add new Items.

index.jsp
 <%@ page import="org.apache.axis2.context.ConfigurationContext" %>  
 <%@ page import="org.wso2.carbon.CarbonConstants" %>  
 <%@ page import="org.wso2.carbon.ui.CarbonUIUtil" %>  
 <%@ page import="org.wso2.carbon.utils.ServerConstants" %>  
 <%@ page import="org.wso2.carbon.ui.CarbonUIMessage" %>  
 <%@ page import="org.wso2.sample.carbon.order.manager.ui.Client" %>  
 <%@ page import="org.wso2.sample.carbon.order.manager.beans.xsd.Item" %>  
 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>  
 <%@ taglib uri="http://wso2.org/projects/carbon/taglibs/carbontags.jar" prefix="carbon" %>  
 <%  
     String serverURL = CarbonUIUtil.getServerURL(config.getServletContext(), session);  
     ConfigurationContext configContext =  
         (ConfigurationContext) config.getServletContext().getAttribute(CarbonConstants.CONFIGURATION_CONTEXT);  
     String cookie = (String) session.getAttribute(ServerConstants.ADMIN_SERVICE_COOKIE);  
   
     Client client;  
     Item[] orders;  
   
     try {  
       client = new Client(configContext, serverURL, cookie);  
       orders = client.getItems();  
     } catch (Exception e) {  
       CarbonUIMessage.sendCarbonUIMessage(e.getMessage(), CarbonUIMessage.ERROR, request, e);  
       return;  
     }  
   
     if ("POST".equalsIgnoreCase(request.getMethod())) {  
       try{  
         int itemCode = Integer.parseInt(request.getParameter("itemCode"));  
         String itemName = request.getParameter("itemName");  
         float itemPrice = Float.parseFloat(request.getParameter("itemPrice"));  
               Item newItem = new Item();  
               newItem.setNo(itemCode);  
               newItem.setName(itemName);  
         newItem.setPrice(itemPrice);  
   
         client.addItem(newItem);  
       }catch(Exception e){  
         e.printStackTrace();  
       }  
     }  
 %>  
   
 <div id="middle">  
   <h2>Order Management</h2>  
   
   <div id="workArea">  
     <table class="styledLeft" id="moduleTable">  
         <thead>  
           <tr>  
             <th width="20%">Order ID</th>  
             <th width="40%">Item Name</th>  
             <th width="40%">Price</th>  
           </tr>  
         </thead>  
         <tbody>  
       <%  
         for(Item order:orders){  
       %>  
           <tr>  
             <td><%=order.getNo()%></td>  
             <td><%=order.getName()%></td>  
             <td><%=order.getPrice()%></td>  
           </tr>  
       <%  
         }  
       %>  
         </tbody>  
      </table>  
      </br>  
      </br>  
      </br>  
      <form action="" method="POST">  
        <table>  
          <tr>  
            <td>Item Code</td>  
            <td><input type="text" id="itemCode" name="itemCode"></td>  
          </tr>  
          <tr>  
            <td>Item Name</td>  
            <td><input type="text" id="itemName" name="itemName"></td>  
          </tr>  
          <tr>  
            <td>Item Price</td>  
            <td><input type="text" id="itemPrice" name="itemPrice"></td>  
          </tr>  
          <tr>  
            <input type="submit" value="Add">  
          </tr>  
        </table>  
      </form>  
   </div>  
 </div>  
Here you can see I've used some style classes and IDs. Those are predefined classes and IDs in the Carbon. Don't forget to import the carbon tag library as well.
(Since IdeaJ community edition is not supporting JSP, you may find it very difficult to format and write the code. If you feel so use eclipse and copy back the code to IdeaJ)

Now we must add the UI component as a menu item. In order to do that you must create the component.xml file.
First create a folder named META-INF inside the resource folder of the front-end module and create a file named component.xml inside the META-INF folder with following content.

component.xml
 <component xmlns="http://products.wso2.org/carbon">  
   <menus>  
     <menu>  
       <id>orderservice_menu</id>  
       <i18n-key>orderservice.menu</i18n-key>  
       <i18n-bundle>org.wso2.sample.carbon.order.manager.ui.i18n.Resources</i18n-bundle>  
       <parent-menu>manage_menu</parent-menu>  
       <link>../order-manager/index.jsp</link>  
       <region>region1</region>  
       <order>50</order>  
       <style-class>manage</style-class>  
       <require-permission>/permission/protected/manage</require-permission>  
     </menu>  
   </menus>  
 </component>  
Here i18n-bundle
value depend on the package that the created Client resides. Create folder structure according to the package name inside the web folder.
e.g my Client class resides in org.wso2.sample.carbon.order.manager.ui package. Therefore I must create folder structure as
org/wso2/sample/carbon/order/manager/ui

Then we have to create the resource bundle. To do so create a file named Resource.properties file. inside the above created folder structure.
e.g.
org/wso2/sample/carbon/order/manager/ui/Resources.properties
File content is
 orderservice.menu = Order Service  
Note
orderservice.menu is the i18n-key that we define in component.xml file.

Go to the pom file location of the front-end module and do a maven clean install

Deploy the Component
Now copy the generated jar files inside the back-end module and front-end module (No need of service-stub jar) in to the earlier mentioned dropins folder and restart the WSO2 AS and log back to the server.

You will see a menu item called Order Manager on left hand side menu bar and when you go to that menu item you will see something like

Note
If you don't get the menu item and don't get any errors in the console probably you might have some issues in resource bundle. Check if the location is correct according to the structure.

You can download the sample code from
https://drive.google.com/file/d/0B-jZl7AY9hiibE01X0hFYVg0SkU/view?usp=sharing

Sunday, February 8, 2015

Simple Web Page with Jaggery

In this post I'm going to explain how to write a simple Jaggery web page. It will have a single form, when user submit the form that information will be stored in a JSON file and already existing content will be shown in the page as well.

Prerequisites
  • Jaggery server or WSO2 Application server should be available on the disk
  • Basic HTML knowledge
Getting to Code
Create a directory on your disk with name as Employee. Create a file with following content and name it as something like employee.jag
 <!DOCTYPE html>  
 <html>  
      <head>  
           <title>Employee Details</title>  
      </head>  
      <body>  
           <h2>Add New Employee</h2>  
           <form id="frmNewEmp" method="POST">  
                <table>  
                     <tr>  
                            <td>First Name:</td>  
                            <td><input type="text" name="fname" /></td>  
                      </tr>  
                      <tr>  
                            <td>Last Name:</td>  
                            <td><input type="text" name="lname" /></td>  
                      </tr>  
                      <tr>  
                            <td>Age:</td>  
                            <td><input type="text" name="age" /></td>  
                      </tr>  
                </table>  
                </br>  
                <input type="submit" value="Add">  
           </form>  
           <h2>Current Employees</h2>  
      </body>  
 </html>  
 <%  
      var fileName = "employees.json";  
        var file = new File(fileName);  
      if(!file.isExists()){  
           file.open("w");  
           file.write('{"employees":[]}');  
           file.close();            
      }  
      /*Load JSON object from the require function*/  
      //var employeeJson = require(fileName);  
      // Read the file and parse string as JSON object  
      file.open("r");  
      var employeeJson = parse(file.readAll());  
      file.close();  
      function printEmployees(){  
           //Iterate through the each element in the Employees array and print them  
           for(var i in employeeJson.employees){  
                print(employeeJson.employees[i].fname + " " + employeeJson.employees[i].lname + ", " + employeeJson.employees[i].age);  
                print("</br>");  
           }  
      }  
      // This section will get called when user press the Add button.  
      // Read the POST data and add new employee to the JSOPN array  
      // Save the JSOn object in the file       
      if(request.getMethod() == "POST"){  
           employeeJson.employees.push({"fname":request.getParameter("fname"), "lname":request.getParameter("lname"), "age":request.getParameter("age")});  
             file.open("w");  
             file.write(employeeJson);  
           file.close();  
      }  
      // Print existing Employees  
      printEmployees();            
 %>  

Deploy
Copy your Employee directory (Directory that contains the employee.jag file) to the apps directory in the Jaggery extract path.
Note
Read on Hello Jaggery post to understand how to deploy files, if you are not sure.
If you are using WSO2 Application Server, you must copy the directory to
 repository/deployment/server/jaggeryapps  
path in the WSO2 Application server extracted location.

Run
Open your web browser and go to the URL
http://localhost:9763/Employee/employee.jag
When you load the page for the first time it will look like
After you added few employees it will look like

Saturday, February 7, 2015

Hello Jaggery

What is Jaggery ?
Jaggery is a framework to write webapps and HTTP-focused web services for all aspects of the application: front-end, communication, Server-side logic and persistence in pure Javascript. One of the intents of this framework is to reduce the gap between writing web apps and web services. Importantly, Jaggery is open-source and released under Apache 2.0 - JaggeryJS.org

Prerequisites
Java

Getting Started
You can download the jaggery from JaggeryJS.org website. It will download all the things that you need to get your hands dirt with Jaggery.
Extract the downloaded zip folder to anywhere that you like. It will looks like
Jaggery bundles a server with it. You can start the server using the server.sh/bat script in the bin folder.

If the server get started successfully you can access its management console using the
https://localhost:9443/admin/carbon/
Use admin as both username and password.

Hello Jaggery
Now lets see how to write the simplest program that we tend to write when getting start with a new language. That is Hello World.

Open your favorite text editor and have following code on that

 <%  
     print("Hello World!");  
 %>  

Save this file with some name like hello.jag
Note
Remember file extension should be .jag

Deployment
You deploy the created file manually or through the Management console.

Option 1 - Manual
Go to the apps folder in the Jaggery. Create a new directory inside the apps folder with name Hello and copy the file that you created to that.
Option 2 - Using Management Console
Add the created file to a .zip folder and rename zip folder to Hello.zip.
If you are using ubuntu you can easily do this by terminal. Go to the directory where your file exists on the disk from the terminal and type following command.
 zip -r Hello.zip hello.jag  
In windows you can do the same thing by right click on the file and select Compressed zip folder from the Send to menu

After creating the zip folder, login to the management console and select Jaggery from the left hand side navigation pane. Then select the zip file that you created and do the upload.

Note
Remember folder name that you are using will be your application name.

Run the Hello World
Go to the following url from your browser
Here Hello is your application name. This is the name that we gave to the folder which consist of hello.jag file.

You will see Hello World! text get printed on your screen.

Wednesday, February 4, 2015

Getting Started with WSO2 ESB

In this post I'm going to explain how we can use WSO2 ESB to create a simple proxy service for a web service and how to consume that.

What is an ESB
An enterprise service bus (ESB) is a software architecture model used for designing and implementing communication between mutually interacting software applications in a service-oriented architecture (SOA). As a software architectural model for distributed computing it is a specialty variant of the more general client server model and promotes agility and flexibility with regard to communication between applications. Its primary use is in enterprise application integration (EAI) of heterogeneous and complex landscapes. - Wikipedia

WSO2 ESB is the best 100% open source ESB available in the current market. It can be considered as the highest performance, lowest footprint, and most interoperable SOA and integration middleware today. - WSO2 ESB

Prerequisites 
  • JDK should be installed in your computer
  • HelloAxis.aar (Creating HelloAxis.aar) or some other web service archive file.
  • Maven (To generate the client source)

Getting Started
You can download the latest WSO2 ESB binary distribution from the WSO2 website (WSO2 ESB Download Page). WSO2 ESB 4.8.1 is the latest stable release. Download that and extract it into any place that you like. When will you extract, it will be looks as follows.


Before creating the proxy we need to deploy our web service. Here I'm using a separate axis2 server. Refer HelloAxis2 post to see how to deploy the file in Axis2 server. You can use axis2 server bundle with WSO2 ESB to deploy the service. You are also free to deploy it anywhere that you like.

Deploy using axis2 server in WSO2 ESB
Copy the HelloAxis.aar file to wso2esb-4.8.1/samples/axis2Server/repository/services
You can start the Axis2 server using the axis2server(.bat or .sh) script in the wso2esb-4.8.1/samples/axis2Server folder. By default this axis2 server will starts on port 9000. If the server get started successfully and the web service is deployed without any iussues, you can see the HelloAxis service is available on the Web service list in localhost:9000/services/

Starting ESB
You can start the WSO2 ESB using the wso2server script in the wso2esb-4.8.1/bin directory 

Ubuntu
wso2server.sh
Windows
wso2server.bat

Note
WSO2 ESB get starts in INFO mode by default. If you like to start the ESB in debug mode, you have to do a small change. To do so
Open the log4j.properties file in the wso2esb-4.8.1/repository/conf folder. In the file you can find a entry looks 
log4j.category.org.apache.synapse=INFO
changed that to
log4j.category.org.apache.synapse=DEBUG

When you run the wso2server script you will see some log entries getting print on terminal and if the ESB get started successfully you will see something similar to

You can open the browser and go to the URL mentioned(https://localhost:9443/carbon) there the WSO2 ESB management console. Probably you will see some security warning when you go to the URL. Just ignore it this time.
You can use admin as both username and password to login to the ESB console.

Go to the Proxy services section under the Services and select Pass Through Proxy from the templates.
In the next screen you must specify information relate to your service. 
  1. Proxy service name - This will be use as the name of our proxy. You can give any name that you like
  2. Target URL - Specify the deployed web service URL. This is what you are accessing through the proxy e.g. HelloAxis service
  3. Select Specify source URL in the publishing WSDL section in the Publish WSDL Options and provide URL to WSDL of the deployed service 
  4. Press Create button.

You will see a message box saying proxy is created successfully and you should see the newly created Proxy service in the Deployed service list. 

Creating a Client
Click on the proxy service name that you created from the list. Then click the Generate Axis2 Client in the Client Operation section in the right hand side of the screen.



In the next screen you will see set of options relate to generating client code. I will just provide a custom package name, while keeping other settings as it is. Click generate button.
This will create a .zip file which consists of a pom.xml file. We can use this pom.xml file to generate the client source code.
You can use your favorite IDE or plain maven commands to generate the source code.

Before generating the source, first open the pom.xml from your favorite text editor and changed
   <properties>  
     <axis2_version>1.6.1-wso2v10</axis2_version>  
   </properties>  

to
   <properties>  
     <axis2_version>1.6.1-wso2v9</axis2_version>  
   </properties>  


e.g.
To generate the source code without any IDE support 
 mvn generate-sources  

To generate source and create eclipse project
 mvn eclipse:eclipse  

If you are using IdeaJ IDE you can import this pom.xml file and generate the source code.

After generating the source, create a simple Java class as follows.
 import org.apache.axis2.AxisFault;  
 import java.rmi.RemoteException;  

 public class ESBClient {  
   public static void main(String[] args) {  
     try {  
       SimpleProxyServiceStub stub = new SimpleProxyServiceStub("http://localhost:8280/services/SimpleProxyService");  
       SimpleProxyServiceStub.SayHello sayHello = new SimpleProxyServiceStub.SayHello();  
       sayHello.setName("Thusitha");;  
       System.out.println(stub.sayHello(sayHello).get_return());  
     } catch (AxisFault axisFault) {  
       axisFault.printStackTrace();  
     } catch (RemoteException e) {  
       e.printStackTrace();  
     }  
   }  
 }  
When you run this you will get the output
 Hello Thusitha  

This output implies that our HelloAxis2 web service get called through the proxy service that we create using WSO2 ESB.