2009/12/10
10 Dec, 2009

How to Deploy a Web service as an OSGi Bundle in WSO2 Web Services Application Server

  • Isuru Suriarachchi
  • Technical Lead and Product Manager - WSO2

WSO2 Web Services Application Server [1] version 3.0 and later versions are developed on top of the OSGi [2] based WSO2 Carbon [3] framework. Therefore, WSO2 Web Services Application Server or any other WSO2 Carbon based product is basically a collection of OSGi bundles.

Normally, the Web services in WSO2 Web Services Application Server are deployed through the repository. Even if you use the management console, those artifacts are copied into the repository and are deployed from there. So can a Web service come from an OSGi bundle? Yes, WSO2 Web Services Application Server provides this facility. All you have to do is to follow the simple steps provided below.

Step 01 : Write your Web service logic as you normally do in developing AAR artifacts. This can be a generated code or a simple POJO type code. To demonstrate this, I'm using a simple POJO as follows.

package org.wso2.wsas.bundleservice;

import org.apache.axis2.context.MessageContext;

public class SampleService {

    private double exchangeRate = 110;

    public double convert(double usd) throws Exception{
        if(usd <= 0){
            throw new Exception("Please send a valid amount of USD");
        }

        //Access the MessageContext to demonstrate osgi package import
        MessageContext.getCurrentMessageContext()
                .getConfigurationContext().setProperty("name", "bundleservice");

        return usd * exchangeRate;
    }
}

Step 02 : Write your services.xml also in the normal way.

<service name="SampleService">
    <description>
        This service convert USD to LKR.
    </description>
    <parameter name="ServiceClass" locked="true">org.wso2.wsas.bundleservice.SampleService</parameter>
    <messageReceivers>
        <messageReceiver mep="https://www.w3.org/ns/wsdl/in-out"
                         class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
</service>

Step 03 : Make your service an OSGi bundle [4]. For this, you can use the Apache Maven bundle plugin in your pom.xml file and it will generate the MANIFEST.MF file with the required OSGi headers.

<project xmlns="https://maven.apache.org/POM/4.0.0"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>org.wso2.carbon</groupId>
    <artifactId>service-in-bundle</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>
    <name>Service in Bundle</name>
    <url>https://wso2.org</url>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <version>1.4.0</version>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-Vendor>WSO2 Inc</Bundle-Vendor>
                        <Bundle-SymbolicName>org.wso2.wsas.bundleservice</Bundle-SymbolicName>
                        <Export-Package>
                            org.wso2.wsas.bundleservice.*
                        </Export-Package>
                        <Import-Package>
                            org.apache.axis2.*;
                        </Import-Package>
                        <DynamicImport-Package>*</DynamicImport-Package>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.apache.axis2.wso2</groupId>
            <artifactId>axis2</artifactId>
            <version>1.5.0.wso2v2</version>
        </dependency>
    </dependencies>
</project>

As shown in the above pom.xml, it's better to export (using Export-Package) the package in which your service class exists. Optionally you can make that package private using Private-Package header. And also, you can import any package which is exported from some other bundle into your service bundle. It's always recommended to use the DynamicImport-Package header such that your service bundle will find all needed packages at runtime even though those are not specifically imported.

If your service depends on any third party libraries, you can place those libraries inside CARBON_HOME/repository/components/lib folder and your service will find those packages at runtime.

Step 04 : Build your service bundle using Apache Maven. It will create the bundle artifact with the following structure.

Step 05 : Extract your WSO2 Web Services Application Server instance and copy your bundle into CARBON_HOME/repository/components/dropins folder (Create it if not already there). If you have any third party dependencies, copy those into CARBON_HOME/repository/components/lib folder.

Step 06 : Start the server and log into the management console. You will see your service in the service listing page and invoke it using the Try-it tool.

You can find the above sample in the attached zip file.

References

[1] WSO2 Web Services Application Server 
[2] OSGi
[3] WSO2 Carbon
[4] Building bundles using Apache Maven

Author

Isuru Suriarachchi, Senior Software Engineer, WSO2, [email protected]

 

 

About Author

  • Isuru Suriarachchi
  • Technical Lead and Product Manager
  • WSO2 Inc.