Home United States USA — software Cloud Foundry Application Manifest Using a Kotlin DSL Cloud Foundry Application Manifest...

Cloud Foundry Application Manifest Using a Kotlin DSL Cloud Foundry Application Manifest Using a Kotlin DSL

285
0
SHARE

Kotlin’s excellent support for functional programming makes it a great language for creating DSLs. Here’s one for Cloud Foundry application manifests.
I had a blast working with and getting my head around the excellent support for creating DSLs in Kotlin Language. This feature is now being used for creating Gradle build files, for defining routes in Spring Webflux, and for creating HTML templates using kotlinx.html library .
Here, I am going to demonstrate how to create a Kotlin based DSL to represent a Cloud Foundry Application Manifest content .
A sample manifest looks like this when represented as a YAML file:
And here is the kind of DSL I am aiming for:
Let me start with a simpler structure that looks like this:
And I want this kind of DSL to map to a structure that looks like this:
It would translate to a Kotlin function which takes a Lambda expression:
The parameter looks like this:
That is fairly self-explanatory: a lambda expression that does not take any parameters and does not return anything.
The part that took a while to seep into my mind is this modified lambda expression, referred to as a lambda expression with a receiver:
It does two things, at least the way I have understood it:
It defines, in the scope of the wrapped function, an extension function for the receiver type — in my case the CfManifest class.
this within the lambda expression now refers to the receiver function.
Given this, the cf function translates to:
Which can be succinctly expressed as:
So now when I call:
It translates to:
Expanding on the basic structure:
The routes and the envs, in turn, become methods on the CfManifest class and look like this:
See how the routes method takes in a lambda expression with a receiver type of ROUTES? This allows me to define an expression like this:
Another trick here is the way a route is being added using:
Which is enabled using a Kotlin convention that translates specific method names to operators, here the unaryPlus method. The cool thing for me is that this operator is visible only in the scope of ROUTES instance!
Another feature of the DSL making use of Kotlin features is the way a memory is specified. There are two parts to it — a number and the modifier, 2G, 500M etc.
This is being specified in a slightly modified way via the DSL as 2 (G) and 500 (M) .
The way it is implemented is using another Kotlin convention where, if a class has an invoke method then instances, can call it the following way:
So implementing the invoke method as an extension function on Int in the scope of the CFManifest class allows this kind of a DSL:
This is pure experimentation on my part. I am both new to Kotlin as well as Kotlin DSLs so it’s very likely that there are a lot of things that can be improved in this implementation. Any feedback and suggestions are welcome. You can play with this sample code at my GitHub repo here.

Continue reading...