Showing posts with label carbon. Show all posts
Showing posts with label carbon. Show all posts

Sunday, March 6, 2016

How to write OSGi tests for C5 compoments

WSO2 C5 Carbon Kernel will be the heart of all the next generation Carbon products. With Kernel version 5.0.0 we introduced PAX OSGi testing.

Now we are trying to ease the life of C5 components developers by providing a utility, which will take care of most of the generic configurations need in OSGi testing. This will enable the C5 component developer to just specify a small number of dependencies and start writing PAX tests for C5 components.

You will have to depend on the following library, except for other PAX dependencies


1
2
3
4
5
6
<dependency>
    <groupId>org.wso2.carbon</groupId>
    <artifactId>carbon-kernel-osgi-test-util</artifactId>
    <version>5.1.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>


You can find a working sample on the following Git repo
https://github.com/jsdjayanga/c5-sample-osgi-test

Above will load the dependencies you need by default to test Carbon Kernel functionalities. But as a component developer you will have to specify your components jars into the testing environment. This is done via @Configuration annotation in your test class.

Lets assume you work on a bundle org.wso2.carbon.jndi:org.wso2.carbon.jndi, below is how you should specify your dependencies.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    @Configuration
    public Option[] createConfiguration() {
        List<Option> customOptions = new ArrayList<>();
        customOptions.add(mavenBundle().artifactId("org.wso2.carbon.jndi").groupId("org.wso2.carbon.jndi")
                .versionAsInProject());

        CarbonOSGiTestEnvConfigs configs = new CarbonOSGiTestEnvConfigs();
        configs.setCarbonHome("/home/jayanga/WSO2/Training/TestUser/target/carbon-home");
        return CarbonOSGiTestUtils.getAllPaxOptions(configs, customOptions);
    }


Once these are done, your test should ideally work :)

Wednesday, December 23, 2015

The core of the next-generation WSO2 Carbon platform : WSO2 Carbon Kernel 5.0.0

A whole new revamp of the heart of all WSO2 products : WSO2 Carbon Kernel 5.0.0, was released 21 Dec 2015.

Previous versions of the WSO2 Carbon Kernel, (1.x.x to 4.x.x) had a much similar architecture and was tightly coupled with relatively old technologies (axiom, axis2, SOAP, etc.). Which is the same reason, which made us to re-think and re-architecture everything from the ground, and to come up with WSO2 Carbon Kernel 5.0.0.

The new Kernel is armed with the latest technologies and patterns. It will provide the key functionality for server developers on top of the underline OSGi runtime.

Key Features
  • Transport Management Framework
  • Logging Framework with Log4j 2.0 as the Backend
  • Carbon Startup Order Resolver
  • Dropins Support for OSGi Ready Bundles
  • Jar to Bundle Conversion Tool
  • Artifact Deployment Engine
  • Pluggable Runtime Support

You can download the product from [1], and find more information on [2].

[1] http://product-dist.wso2.com/products/carbon/5.0.0/wso2carbon-kernel-5.0.0.zip
[2] https://docs.wso2.com/display/Carbon500/WSO2+Carbon+Documentation

Monday, April 6, 2015

Error occurred while applying patches {org.wso2.carbon.server.extensions.PatchInstaller}

I have seen people complaining that WSO2 servers logs the following error message at server start up.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[2015-04-06 15:48:57,572] ERROR {org.wso2.carbon.server.extensions.PatchInstaller} -  Error occurred while applying patches
java.io.IOException: Destination '/home/jayanga/WSO2/wso2am-1.7.0/repository/components/plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.1.200.v20120522-1813' exists but is a directory
 at org.wso2.carbon.server.util.FileUtils.copyFile(FileUtils.java:145)
 at org.wso2.carbon.server.util.PatchUtils.copyNewPatches(PatchUtils.java:211)
 at org.wso2.carbon.server.extensions.PatchInstaller.perform(PatchInstaller.java:80)
 at org.wso2.carbon.server.Main.invokeExtensions(Main.java:152)
 at org.wso2.carbon.server.Main.main(Main.java:94)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)
 at org.wso2.carbon.bootstrap.Bootstrap.loadClass(Bootstrap.java:63)
 at org.wso2.carbon.bootstrap.Bootstrap.main(Bootstrap.java:45)


The main reason to see such error message is, some erroneous entries in the patch metadata files for files itself.

This might happen if you try to forcefully stop the server as soon as you start the server

When the server start up, it copies the patch files. If the server is forcefully stopped at that time using [ctrl+c], patching processes get immediately stopped and patch meta-data will get corrupted.

You can get rid of this issue by removing corrupted patch related meta-data manually and restating the server, so that the server will apply all the patches form the beginning.

  1. remove [CARBON_HOME]/repository/components/patches/.metadata
  2. restart the server. (do not interrupt while starting up)

Thursday, March 26, 2015

WSO2 Carbon : Get notified just after the server start and just before server shutdown

WSO2 Carbon [1] is a 100% open source, integrated and componentized middleware platform which enables you to develop your business and enterprise solutions rapidly. WSO2 Carbon is based on OSGi framework [2]. It inherits molecularity and dynamism from the OSGi.

In this post I am going to show you how to get notified, when the server is starting up and when the server is about to shut down. 

In OSGi, bundle start up sequence is random. So you can't rely on the bundle start up sequence.

There are real world scenarios where you have some dependencies amount bundles, hence need to perform some actions before other dependent bundles get deactivated in the server shutdown.

Eg. Let's say you have to send messages to a external system. Your message sending module use your authentication module to authenticate the request and send it to the external system and your message sending module try to send all the buffered messages before the server shutdown.

Bundle unloading sequence in OSGi not happened in a guaranteed sequence. So, what would happen if your authentication bundle get deactivated before your message sending bundle get deactivated. In this case message sending module can't send the messages

To help these type of scenarios WSO2 Carbon framework provide you with a special OSGi service which can be used to detect the server start up and server shutdown

1. How to get notified the server startup

Implement the interface org.wso2.carbon.core.ServerStartupObserver [3], and register it as a service via the bundle context.

When the server is starting you will receive notifications via completingServerStartup() and completedServerStartup()


2. How to get notified the server shutdown

Implement the interface org.wso2.carbon.core.ServerShutdownHandler [4], and register it as a service via the bundle context.

When the server is about to shutdown you will receive the notification via invoke()

eg:

1
2
3
4
5
6
7
protected void activate(ComponentContext componentContext) {
 try {
     componentContext.getBundleContext().registerService(ServerStartupObserver.class.getName(), new CustomServerStartupObserver(), null) ;
 } catch (Throwable e) {
     log.error("Failed to activate the bundle ", e);
 }
}



Sunday, October 5, 2014

How to register a custom deployer in Carbon

Deployers in Axis2 are used to track the new file additions, file updates and file deletes. Writing an custom deployer is not a difficult task. A deployer is an implementation of org.apache.axis2.deployment.Deployer interface. You can find more details on how to write a deployer on : http://wso2.com/library/3708/

Once you write your custom deployer, you have to register it. Following  is how to register a custom deployer.

Add the deployer details to the component.xml file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<component xmlns="http://products.wso2.org/carbon">
   <deployers>
       <deployer>
           <directory>sample</directory>
           <extension>xml</extension>
           <class>
               org.wso2.carbon.samples.deployer.CustomDeployer
           </class>
       </deployer>
   </deployers>
</component>

As the information given in the above configuration, a directory named ‘sample’ in the location ‘repository/deployment/server’ will be monitored. Whenever file with extension ‘xml’  is added, modified or removed deployed() method will be called.

Add the following entry to the <configuration> <instructions> list of the maven-bundle-plugin in your pox.xml file.

<Axis2Deployer>CustomDeployer</Axis2Deployer>

To be responsive for real time file additions, updates and deletions configuration ‘hotupdate’ in Axis2.xml has to be set to true.

<parameter name="hotupdate" locked="false">true</parameter>

You can find a sample code in : https://github.com/jsdjayanga/How-to-register-a-custom-deployer-in-Carbon

Friday, October 3, 2014

Internal synchronization of carbon kernel (Holding transports until the kernel get ready)

Starting up sequence of internal components of the carbon kernel is crucial for the kernel to operate  properly. Most importantly kernel should not start accepting external messages until it is ready to process messages. So it is needed to delay the activation of transports until the kernel is ready. Carbon kernel is made up of OSGi based components. According to the OSGi  standards there is no definite order in which the bundles get activated.


To overcome the this sequencing problem, In carbon kernel there is special component which handles this synchronization. ‘StartupFinalizerServiceComponent’ an OSGi component, which delays the activation of transports.


If all the required services are ready by the bundle activation time, then the ‘StartupFinalizerServiceComponent’ call the ‘completeInitialization()’ method which performs the initialization of transports. But if the required services are not available at the bundle activation time, transports will not get activated. And it will wait until the required services are available.


‘StartupFinalizerServiceComponent’ is a ServiceListener. Each time a service change happens serviceChanged() method is called, and this will check for the required service list. Once all the required services are available, it calls the ‘completeInitialization()’ and activate the transports.

Tuesday, September 30, 2014

How to register a servlet from a Carbon Component

There are three ways to register a servlet in carbon.
Specifying the servlet details in the web.xml file
Specifying the servlet details in the component.xml file
Registering the servlet with httpService in your component

You can find the sample code in : https://github.com/jsdjayanga/How-to-register-a-servlet-from-a-Carbon-Component

Specifying the servlet details in the web.xml file

Specifying the servlet details in the web.xml file is not recommended when working with the carbon framework, as it has less control over the servlet when it is directly specified in the web.xml

From the remaining two, neither is bad, its totally up to the developer to decide what is best for a given scenario.

Specifying the servlet details in the component.xml file

Specifying the servlet details in the component.xml file is the easiest way of doing this.

In this approach, you need to have your HttpServlet implementation. Then you have to specify the details about your servlet in the component.xml file. Following is how you should specify details


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<component xmlns="http://products.wso2.org/carbon">
   <servlets>
       <servlet id="SampleServlet">
           <servlet-name>sampleServlet</servlet-name>
           <url-pattern>/sampleservlet</url-pattern>
           <display-name>Sample Servlet</display-name>
           <servlet-class>
               org.wso2.carbon.samples.xmlbased.SampleServlet
           </servlet-class>
       </servlet>
   </servlets>
</component>

Once you restart the servlet, with your compiled .jar in the dropins directory (repository/components/dropins), all the request to the  http://ip:port/sampleservlet will be routed to your custom servlet (org.wso2.carbon.samples.xmlbased.SampleServlet).


Registering the servlet with httpService

Registering the servlet with httpService allows dynamically register and unregister services. This allows you to have more control over the availability of the servlet.

In this approach, you need to have your HttpServlet implementation. Then you have to register your servlet with the org.osgi.service.http.HttpService once your bundle get activated.


httpService.registerServlet("/sampledynamicservlet", new SampleDynamicServlet(), null, null);

Then onwards, requests received for the http://ip:port/sampledynamicservlet will be routed to your custom servlet.

In this approach you can unregister your servlet, this cause the http://ip:port/sampledynamicservlet to be unavailable.


httpService.unregister("/sampledynamicservlet");