Tuesday, 21 November 2017

Kotlin RESTful Microservices using Open Liberty


Kotlin is not a new language, but there's no doubt it's received a huge boost with the announcement earlier this year that it was now an official language for Android development.  As Kotlin use grows on Android, so does the need for Kotlin on the server.  "Backend for frontend" is the concept of having server-side components that are aligned with the front-end user experience.  Both are usually created and maintained by the same team and so using the same technologies makes a lot of sense.  For example, Node.js services supporting a JavaScript-based Web frontend, or Java services supporting an Android front-end.  So this raises the question, "What backend can I use for a Kotlin front-end?".

New languages often struggle to gain adoption early on because they're missing the richness of frameworks and standards that communities provide over time.  Kotlin has cleverly avoided this problem by being fully interoperable with Java.  This means that, for example, to create a RESTful backend in Kotlin, we can make use of existing Java server-side technologies, such as those supported by Eclipse MicroProfile (e.g. JAX-RS, JSON-P, etc).

To that end, I thought I'd write a little sample just to see what the experience was like...

Disclaimer:  I'm not a Kotlin expert.  I can spell it (most of the time) and occasionally get the code to compile.  If you are a Kotlin expert, go easy, or even send me a PR if you spot bad stuff, so I can learn.  Thanks :)

The Sample

The code for what I created is at - https://github.com/gcharters/Kotlin-REST-Service.  There's a README that explains how to build and run it.

The sample is essentially a simple REST service implemented using JAX-RS.  The service is very, very basic and doesn't really take advantage of any Kotlin features other than its interoperability with Java and its concise syntax.  For now, the goal is to just show how to get things working together.

I created the sample by first using the liberty-archetype-webapp to generate a sample web app project with build and a test.  I then gutted it and replaced it with a REST service written in Java, then finally, I rewrote everything in Kotlin.  Ideally there'd be a liberty-archetype-rest and I'd have written the service straight off in Kotlin, but this was a learning exercise so I wanted to take baby steps.

There are four main parts to the sample:
  1. The maven build - Kotlin-REST-Service/pom.xml
  2. The server configuration - Kotlin-REST-Service/src/main/liberty/config/server.xml
  3. The service - Kotlin-REST-Service/src/main/kotlin/gcc/kt/rest/HelloService.kt
  4. The test case - Kotlin-REST-Service/src/test/kotlin/gcc/kt/rest/it/HelloServiceIT.kt

The build

The build is maven-based and uses the liberty-maven-plugin to work with the Open Liberty server - create a server package, start/stop the server, and so on.  It uses the maven-war-plugin to build a WAR file containing the Kotlin REST application, and the maven-failsafe-plugin for running integration tests.  The last, but rather important, plugin to mention that's used is the kotlin-maven-plugin to compile the Kotlin code.  The maven build in this sample only compiles Kotlin code; if you want to compile Kotlin and Java in the same project you'll need to use the Compiling Kotlin and Java sources configuration.

All but one of the dependencies in the maven pom are the ones you would use when writing a JAX-RS Java REST service.  The one that's new is for the Kotlin language library:

 <dependency>  
   <groupId>org.jetbrains.kotlin</groupId>  
   <artifactId>kotlin-stdlib</artifactId>  
   <version>${kotlin.version}</version>  
 </dependency>   


The absence of an explicit maven scope for this dependency means it will be packaged in the WAR file, as it's required at runtime.  There are other approaches we could take, such as adding it as a shared or global library or a Liberty feature, but this is the simplest.  The downside is every app you build this way will have its own copy of Kotlin.  It's not a large library, but the more copies you have, the more you have to patch if there are any issues (e.g. security vulnerabilities, etc).

The server

There is nothing unique about the server configuration.  It specifies that we only need the JAX-RS capability, what ports to use, and then the application to be deployed.  The one thing to note is that the context root for the application will be the value specified in the name attribute of the webApplication element - i.e., "helloKotlin".

  <webApplication id="kotlinHello" location="kotlinHello.war"
     name="kotlinHello"/>  

The service

If you're familiar with JAX-RS, then you'll recognize the JAX-RS annotations and inheritance for specifying the application and path information, in the service implementation.  When deployed for testing, the WAR context root is "helloKotlin" (see the earlier server configuration), the application path is "/", the path to the service is "/hello" and on an HTTP GET, the service is expecting a "name" path parameter.  There's no error handling, so it breaks in ugly ways if you don't get the URL right. 

An example request would be:

http://localhost:9080/helloKotlin/hello/gcharters

 @Path("/hello")  
 @ApplicationPath("/")  
 class HelloService : Application() {  
   @GET  
   @Path("/{name}")    
   fun sayHello(@PathParam("name") name: String): Response {  
     println("HelloService sayHello called: " + name)  
     val response = Response.ok("Hello " + name).build()  
     return response  
 }  

The test case

The test case is very basic, just checking that it gets an HTTP return code of 200 from the service.  The location of the service to test is built up from values provided by the maven-failsafe-plugin as system properties .  The request itself is made using the JAX-RS Client (introduced in JAX-RS 2.0).
     // Set up the path to the service  
     val port = System.getProperty("liberty.test.port")  
     val contextName = System.getProperty("app.context.root")  
     val path = "hello"  
     val person = "Fred"  
     val url = "http://localhost:" + port + "/" + contextName 
               + "/" + path + "/" + person 

     // Make the request  
     val client = ClientBuilder.newClient()  
     val target = client.target(url)  
     val response = target.request().get() 

     // Test we got an OK response  
     assertEquals("Incorrect response code from " + url, 200, 
                  response.getStatus())  

Tools

In the course of writing the sample, I tried a couple of tools options.  The Eclipse IDE with the Open Liberty Tools and the Kotlin tools gives you a reasonable experience.  I also tried out VS Code with Kotlin Language extension.  This is ok for syntax highlighting, but is not a language server (there is, as yet, no language server for Kotlin, and this post would suggest there may not be one for a while).  The lack of language server means you need to run a maven build each time you make changes to see the results.

Summary

Kotlin is definitely an interesting language and one with what looks like a bright future.  If you're looking for a server-side option for Kotlin, using it with Open Liberty and picking from the existing MicroProfile and Java EE technologies is a great place to start.

There's a lot more to Microservices than writing a REST service, but the great thing about re-using existing backend technologies with Kotlin is you inherit all of the existing capabilities.  If you're already deploying the chosen backend infrastructure, there's no need to make new choices around how to do containerization, clustering, configuration, security, etc., all of your approaches simply apply as-is.

Friday, 18 September 2015

Using WAS Liberty with added IBM Java

Alasdair Nottingham gave a nice overview of the options we have for installing WAS Liberty.  There are a few options, but I think he did a good job of explaining their existence.  One thing I wondered about was the broader use of the IBM Java once you got hold of it.  For example, how do I know the Java is being used?  Can I package it back up with my server?  So, I did a bit of experimenting.

Downloading

You can download the WAS Liberty Zip that includes IBM Java from the WebSphere Liberty Repository here.  This zip, as the name suggests, includes all the features required to run Java EE 7 Web Profile applications.  At the time of writing, the server is licensed for development use, with limited production use (just in case it changes ;) ). 

Installing

To get started with Liberty and IBM Java, you just unzip the package.  E.g.

unzip wlp-webProfile7-java8-win-x86_64-8.5.5.7.zip

This will create a directory called wlp and under that directory you should see the following directories and files:


















If you're familiar with other Liberty packages, the new directory to note is the one called java.  That's it, that's the IBM Java. 

Creating a Server

The install doesn't contain a server configuration so you next need to create one.  In a command prompt (yes, I use Windows :S) in the wlp directory, type:

bin\server create myServer

This creates a server called myServer with the default configuration to start the webProfile-7.0 feature (see the featureManager entry in wlp\usr\servers\myServer\server.xml).

From here you can install more features using bin\installUtility, develop and deploy applications and so on. 

Starting the Server

You can start the server using the start or run commands.  E.g.

bin\server start myServer

Check to see which Java is being used (e.g. using Task Manager or ps).  I got a bit of a surprise as mine wasn't using the included IBM Java.  This was because I already had Java on my system and so it picked that one up based on my JAVA_HOME setting.  You need to unset that to get it to pick up the included IBM Java (e.g. set JAVA_HOME= ).

Packaging it up

Let's say you've finished developing your super awesome application or you've created a custom server install that you want to package up, including the IBM Java.  This is useful if for example to create a distribution to put on another system whilst not having to rely on the right level of Java being provided on that system.  Before you do this, though, you might want to change the licensing for production use.  If you've purchased a WAS Edition, you can apply the license using a license.jar that you download for Passport Advantage.  OK, back to packing up the server.  This is simple, using the server package command.

To just package up the server install and not your server.xml and application, you do the following:

bin\server package --include=wlp

This creates a wlp.zip file with all the runtime, include IBM Java under the wlp\usr\servers directory.

To package up the server install along with your server configuration and application, you do the following:

bin\server package myServer --include=all

This creates a myServer.zip with all the runtime, IBM Java, server configuration and application(s) under the wlp\usr\servers\myServer directory.

That's it!  Pretty simple really.  The only real gotcha from my perspective was the JAVA_HOME.  I hope you find this useful.  Please comment if there's something I could explain better or you spot a mistake.  Thanks.

Thursday, 29 November 2012

Enabling the Felix Web Console in a WAS Liberty Profile OSGi Application

UPDATE: Since writing this blog Liberty has added the Felix Web Console as a first-class feature.  See: https://developer.ibm.com/wasdev/docs/osgi-application-console-feature/

The full profile WebSphere Application Server (WAS) has supported the deployment of applications written using OSGi for many years now.  The latest version, 8.5, has support for both a command line console and a web-based console as part of the WebSphere Admin Console.  Both consoles are very useful for tracking down dependency and lifecycle problems within an application, but unfortunately, these capabilities are not available in the Liberty profile of WAS and so determining what is happening inside your OSGi application can be a bit of a challenge.  And now for what might seem like a slight digression...

Over the years, I've heard quite a bit of interest in using the OSGi Http Service for developing and deploying Web applications to WAS.  WAS does not directly support this model, but instead supports the Web Application Bundle model standardized in the Enterprise OSGi specification.  This lack of support for the Http Service did not stop Ralf Zahn of ARS getting the Eclipse Equinox implementation of the Http Service running in WAS by deploying it as part of a Web Application Bundle.  The details of what he did, including a little demo, can be found on his blog, here.  OK, back to the console topic...

The Felix Web Console provides a nice set of console capabilities for OSGi runtimes and there are also some plugins to augment the out-of-the-fox support.  It just so happens that the only mandatory pre-requisite service (other than an OSGi Framework, of course) is the Http Service.  So, I wondered if we could combine the approach taken by Ralf to enable the Felix Web Console and thus get useful insights into what's going on inside an OSGi application running on the Liberty Profile.  Well, not surprisingly, the answer is "yes".

Before I go into the details, first the disclaimer:
  1. You need to add four bundles to your OSGi application and so it's not the most elegant solution in the world (note, I used Felix Web Console 3.1.8. which has a distribution that includes its pre-req's.  If you use the latest Web console (4.0), or the 'bare' distribution you will need to also add its pre-req's to the application).
  2. The Felix Web Console is for managing OSGi frameworks and so it lets you modify the life-cycle of individual bundles  This is not advisable for OSGi applications, where the OSGi application runtime manages the life-cycles of these bundle for you.
The four bundles are as follows:

Bundle Purpose
org.apache.felix.webconsole The Felix Web Console.  This can be downloaded from here.
gcc.samples.httpservice.wab The Web Application Bundle that registers the Equinox HttpServiceServlet. It's this servlet that provide the Http Service implementation. The WAB has a default context route of /httpservice.  This can be downloaded from here.  It contains no code, simply web.xml configuration for the HttpServiceServlet.
org.eclipse.osgi.services Provides the APIs for the Http Service implementation. This can be downloaded from here.
org.eclipse.equinox.http.servlet Provides the HttpServiceServlet implementation.  This can be downloaded from here.  For some reason this jar is not available in later equinox releases, but I believe that to be a infrastructure mistake, not a sign it was removed, so I'd hope that will be fixed soon.

The application definition that uses these bundles should look something like this (note, this one does not contain any application bundles, only those required to enable the Web console):


Application-Name: Application with Web Console
Application-SymbolicName: web.console-3.1.8.eba
Application-ManifestVersion: 1.0
Application-Version: 1.0.0
Application-Content: gcc.samples.httpservice.wab;version="[1.0.0, 1.1.0)",
  org.apache.felix.webconsole;version="[3.1.8, 3.2)",
  org.eclipse.equinox.http.servlet;version="[1.1,1.2)",
  org.eclipse.osgi.services;version="[3.3, 3.4)"
Manifest-Version: 1.0


The documentation for the Felix Web Console can be found here.

If you use the bundles as-is, without changing the context route, you should be able to point your browser at http://<server>:<port>/httpservice/system/console (as described on the Web Console documentation).  Log in with "admin" & "admin" and the console should be displayed.  From the bundles view, you can see bundle status, package imports/exports, navigate package dependencies.  There's a services view where you can see the registered services, who's providing them, who's using them, and so on - all the sorts of things you need to be able to do to track down problems.

The following is an example screenshot of the Web Console for the above application definition.


Bundles 2-5 are the bundles we configured in the application definition.  Bundle 0 is the system bundle and bundle 1 is the bundle providing imports into the application.  If you drill down on this you'll see it provided the servlet packages required by the Web Application Bundle.

I hope you find this useful.


Friday, 4 June 2010

WebSphere OSGi Applications and SCA

For the past few years I've been working in the OSGi and SCA standards groups with a view to bringing together the best of both worlds in a complementary way. I gave a presentation at the OSGi Users' Forum UK at the beginning of this year on OSGi and SCA and how the two can be combined to add heterogeneous integration capabilities to OSGi services. This included a demo of Apache Aries and Apache Tuscany, turning an Aries OSGi application service into a Web service.

I'm also a member of the WebSphere Application Server team and for the past couple of years have been working on enabling OSGi applications in the WebSphere Application Server programming model and their integration with SCA. Last week IBM made generally available the two feature packs with this support:

The OSGi Applications and JPA 2.0 Feature Pack enables you to develop and deploy modular enterprise OSGi applications, in production and at no additional expense (sounding like a salesman...must stop). Building applications in this way enables greater flexibility, re-use and sharing of components between applications, which itself reduces disk and memory footprint.

The SCA Feature Pack refresh adds a new implementation type (osgiapp) that allows you to take an OSGi application and integrate it with other component types (e.g. Java EE), and/or add protocol bindings to OSGI application services or references (e.g. Web services, Atom, EJB).

All in all, pretty cool, I think, but then I would say that. Hopefully others will agree, but only time will tell....

Thursday, 6 May 2010

Free OSGi Application Tools

One of the problems with developing applications using OSGi is the limited capabilities of the tools. Also, many of the Enterprise OSGi technologies are new, or have recently added OSGi capabilities to existing technologies and hence, require new tools or the existing tools to catch up.

IBM has just made available some free OSGi application tools on DeveloperWorks. These enable you to develop OSGi applications following the design used in Apache Aries and also the WebSphere OSGi application feature pack. They also enable you to develop Web Application Bundles (essentially a WAR with Bundle metadata), Persistence Bundles (a JPA persistence archive with bundle metadata), vanilla OSGi bundles, and to edit Blueprint XML files (a standardized form of the Spring Framework component model). The same tools, and more, are also available in the current RAD beta.


If you give the tools a try, I'd be interested to know what works for you and what doesn't. If you have any problems or require assistance, there's also a forum for you to ask questions.