Library

How to Build a Custom Stack with WSO2 Carbon

  • By Shameera Rathnayaka
  • 10 Sep, 2013

Table of contents

  • Introduction
  • The feature/component concept in the WSO2 Carbon platform
  • Installing features using the Feature Manager
  • How to create your custom products for cluster wide deployment
  • Configuring logs/adding configs

Introduction

The WSO2 Carbon middleware stack consists of more than 175 OSGi-based components. Even though WSO2 Carbon ships some of the well-defined component configurations as a set of products, it is also possible for organizations to come up with their own product configurations through a mix and match of available components with WSO2 Carbon. The custom product gets not only an osgi-based deployment, but it gets Distributed Caching, Clustering, Deployment Synchronize, Ghost Deployment, Registry Capability and Multiple Profile Support too. In this article, we explain how you could create a customized stack with WSO2 Carbon and provide a step-by-step guide. As this article is related to a recent webinar that was conducted under “Carbon Webinar Series - Part III” you can also find the demonstration on how to create a custom component in the References section.

So, here's the step-by-step guide. Firstly, it's important to understand the basic structure of the WSO2 Carbon platform.

The feature/component concept in the WSO2 Carbon platform

What is a Component?

A component is a simple OSGi bundle, which is what we develop. A component in Carbon should follow the rules defined in the carbon framework. The component has a core runtime that will provide a clean SOA management interface. There are two types of components in WSO2 Carbon, namely, Back-end components and Front-end components. With this categorization, the user is capable of deploying Back-End components and Front-End components even in two different machines. The front-end component uses Web Service calls for sending and receiving messages from and to the back-end. Under the hood, Carbon uses Apache Axis2 to expose Back-end services. It is easy to generate wsdl of a particular service and generate a client stub from that wsdl and use that stub to issue Web Service calls to the back-end service. All the business logics goes with the back-end components while the front-end component holds all the client-side code. A component can use core Carbon services like Registry Service, UserManager Service etc. via OSGi services registry. These services will get bound and unbound at runtime when a component registers above services against its interface class. A component can register and unregister service at any time and the Carbon Osgi framework will then fire bind and unbind operations.

Figure 1.

What is a Feature ?

In the Carbon world a feature is the installable unit that we install on Carbon. A feature has one or more logically related Carbon components. We can write an aggregate feature that has two or more features within it. These features can be installed into Carbon-based products using feature manager service, provided by the Carbon Framework. It is possible to run touchpoint actions (copy, rename, move and delete files) when a feature gets installed and uninstalled to and from the environment. With Carbon 4.2.0 onward, it is also possible to modify (e.g. add or remove an element from the xml file) these too. Further, you can write your own touchpoint actions. These touchpoint actions are defined with the p2.inf resource file in a feature. The next paragraph explains how to install features in the Carbon Framework using the Feature Manager.

Installing features using the Feature Manager

The Feature Manager service provides a nice and easy way to install and uninstall features on Carbon-based products. Once you install or uninstall features to your Carbon-based product you must restart the system to activate them. This supports multiple feature repositories (both local or remote). Feature Manager shows feature installation history with the timestamp and it is also possible to revert to a given timestamp.  With the use of Feature Manager you can install features only at runtime. However, if you need to install some custom features at the build time, you can also do that, not with feature manger but using Carbon p2 maven plugin. In order to do this, you would only need to add that plugin to the pom.xml file with few configurations.

We have learnt how to create customs features and install them up to now; the next section is about how to configure your custom products in a clustered environment.

How to create your custom products for cluster-wide deployment

In productions, you may need to scale up or down your system, or to avoid a single point of failure using two or more instances at runtime. One way to do this is clustering your runtime instances and exposing it as a single service. In order to do that, your product should have clustering capability. WSO2 Carbon kernel provides clustering support for all products that are built on top of that. What this means is if you build your custom products on top of Carbon (as a carbon component) you will get the clustering capability for your product by default. There are two clustering membership schemes “multicast” and “wka” (well-known address). Carbon's clustering power comes with Apache Axis2. WSO2 maintains WSO2 versions of Axis2 (e.g. 1.6.2-wso2v10). Therefore, you will find a few improvements on Clustering implementation of Axis2 than the official Apache axis2 1.6.2 release. Apache Axis2 has tribes clustering implementation, and with Carbon 4.2.0 (which is the latest version at the moment), you will get hazelcast clustering implementation instead of tribes. As mentioned above, there are two modes of membership discover schemes multicast and wka. In the multicast mode cluster, membership is automatically discovered using multicasting. With wka (well-known address)-based multicasting, membership is discovered with the help of one or more nodes running at a well-known address. New members joining a cluster will first connect to a well-known node, register with the well-known node and get the membership list from it. When new members join, one of the well-known nodes will notify the others in the group. When a member leaves the cluster or is deemed to have left the cluster, it will be detected by the Group Membership Service (GMS) using a TCP ping mechanism.

One of the other barriers in production deployment is handling the increasing volume (in other words scaling up the system). Even if you start your product with a low number of requests per seconds at first, with the growth of the business, you may need to handle a large number of requests per second for the majority of the systems. One way to handle this is use caching. With caching, you can store stateless data used in requests other than using the back-end database. So where should we store and retrieve the common data per request? As you know, a database call is very expensive. Therefore, caching is the best solution for that kind of situation. Carbon kernel itself comes up with a Caching implementation. With 4.2.0, it has been implemented with hazelcast. Not only local caching, it also provides distribute caching where we can use this in a clustering environment. Similarly, you will also get advanced features like depsync, Ghost Deployment, multiprofile and patching capabilities with the WSO2 Carbon framework. In a worker-manager separated cluster, we have managers who have admin console and do all admin level operations such as artifact deployment, undeployment, change configurations, apply security policies for services etc. and workers who don't have admin console or UI. All admin operations have been blocked for workers that we can do by removing admin functionalities from workers (this can be done easily by writing a simple worker profile that doesn’t have admin components at runtime). Hence, workers only process incoming requests and send responses back. There can be multiple workers as well as multiple managers in one cluster.

You need to enable Deployment synchronize of all instances in cluster and point to a single svn (or git) repository to sync the artifacts across the cluster. Once you deploy a new artifact using the admin console of one of the managers in a cluster it will commit that artifact to the svn repo and worker will get a notification message about the svn repo change. Then workers will checkout (svn up) the change and deploy that artifact. Note that only managers can made commit requests and workers can do checkout requests.

Figure 2.

Configuring the customs products

The WSO2 Carbon framework is a customizable framework that provides a number of configuration files to customize the runtime behavior of component/product. All these configuration files are placed under /repository/conf directory. The following are a set of important configuration files.

  • axis2.xml - Used for configure MessageBuilders, MessageFormatters , Clustering etc.
  • carbon.xml - Used for configure Ports, KeyStores, DeploymentSynchronizer , Ghost Deployment and JNDI etc.
  • catalina-server.xml - Used for configure TransportListeners and TransportSenders, Tomcat valves etc.
  • registry.xml - All registry related configurations go here (e.g. registry handlers)
  • log4j.properties - Carbon log related properties go here
  • master-datasources.xml - All datasource related configurations go here. By default you will find an h2 database with this and you can define any RDBMS datasource here

Example scenario

As we have a clear idea on above concepts now, let’s move on to see how we can build a custom component and deploy it in the Carbon framework. Here, I have used the student management sample that comes with Carbon kernel since the 4.2.0 release to explain the process. This sample consists of two carbon components that are Student management back-end component and Student management front-end component. There are three features; the first one isthe  org.wso2.carbon.student.mgt.server.feature, which is for student management back-end component, org.wso2.carbon.student.mgt.ui.feature, which is for student management front-end component, and the last one org.wso2.carbon.student.mgt.feature is an aggregate feature of both server feature and ui feature. The student manager feature repository is used to install Student manager back-end and front-end components to carbon framework via carbon feature manager at runtime. The Script will install both student management back-end and front-end components at build time.

Student manager back-end component

Student Manager Class, as explained in the above business logic, defined in the back-end component. Here, we have three admin functions that are addStudent, deleteStuduent and getStudents. These functions are used to add and delete Student and retrieve all Students, respectively. Student manager has used a map to store student data with NIC of students.

import java.util.Map;
import java.util.HashMap;
import org.wso2.carbon.student.mgt.data.Student;
public class StudentManager {

   private Map

Student Class, This is a simple Student pojo class which represent Student object in OOP world.

public class Student {

   private String nicNumber;
   private String fName;
   private String lName;
   private int age;

    public String getNICNumber(){
       return nicNumber;
    }

    public void setNICNumber(String nicNumber){
       this.nicNumber = nicNumber;
    }

   public String getFirstName(){
       return fName;
   }

   public void setfirstName(String fName){
       this.fName = fName;
   }

   public String getLastName(){
       return lName;
   }

   public void setLastName(String lName){
       this.lName = lName;
   }                   

   public int getAge(){
       return age;
   }

   public void setAge(int age){
       this.age = age;
   }
}

services.xml - As you know, all admin services are axis2 services. Carbon uses apache axis2 for deploy admin services. To deploy the service under axis2, it requires the service descriptor file, which is servcies.xml. Following is the services.xml file for our Student manager back-end component.

httpsorg.wso2.carbon.student.mgt.StudentManagertruetrue/permission/protected/manage

Generate WSDL for above Student manager class this can be done by java2wsdl tool, which comes with carbon product (see /bin directory) and generate client stub from that WSDL using wsdl2java tool, which also comes with the Carbon product.

Student management front-end component

Student manager Client class; this class is written by wrapping Student manager stub to do the Web Service call to Student manager back end. Here, it has two functions to do - get Students and add Student admin requests.

import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.context.ConfigurationContext;
import org.wso2.carbon.student.mgt.data.xsd.Student;
import java.lang.Exception;

public class StudentManagerClient {

   private StudentManagerStub stub;

   public StudentManagerClient(ConfigurationContext configCtx, String backendServerURL, String cookie) throws Exception{
       String serviceURL = backendServerURL + "StudentManager";
       stub = new StudentManagerStub(configCtx, serviceURL);
       ServiceClient client = stub._getServiceClient();
       Options options = client.getOptions();
       options.setManageSession(true);
       options.setProperty(org.apache.axis2.transport.http.HTTPConstants.COOKIE_STRING, cookie);
   }
   
   public void addStudent(Student student) throws Exception{
       try{
           stub.addStudent(student);
       }catch (RemoteException e) {
           String msg = "Cannot add the student"
               + " . Backend service may be unvailable";
           throw new Exception(msg, e);
       }
   }

   public Student[] getStudents() throws Exception{
       try{
           return stub.getStudents();
       }catch (RemoteException e) {
           String msg = "Cannot get the list of students"
               + " . Backend service may be unvailable";
           throw new Exception(msg, e);
       }
   }    

}

Student Manager UI jsp page; this is the page that gets displayed when you click the student manager icon on the left menu. This will show all students stored in Student manager at runtime. Inside this jsp it uses Student manager client to do the required admin calls to get the data from Student manager back end.

Generate Student Manager P2-Repo

Here, we use Carbon-p2 maven plugin to generate the p2-repo for student management features. Following is the configuration we will use for it. This will generate p2-repository in target/p2-repo using org.wso2.carbon.student.mgt.feature aggregate feature. You can point it as a p2 repository in feature management and install Student management features.

If you need to install your custom component at build time, it can also be done using carbon-p2 plugin. Following is how we configure carbon-p2 plugin to install Student management features at build time and create a new pack. Here you have to provide p2-repo and carbon-product path as properties.

eg:


If you need to try out the whole example, the source code for this sample can be download from here.

Summary

WSO2 Carbon provides a solid, robust, flexible osgi framework to implement custom products on it. Using the rich in-built features and components already provided by the Carbon framework, any organization/user can build a customized product stack for their needs. This tutorial is intended to provide a detailed guide on how to create customized new components on top of the WSO2 Carbon framework.

About Author

  • Shameera Rathnayaka
  • Software Enigineer
  • WSO2