Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
alisdair73
Participant

The Platform as a Service

I first came across the concept of the Cloud Application Platform at a ThoughtWorks Technology Radar briefing, where both Cloud Foundry and Heroku were being discussed. Although I spend most of my time immersed in ABAP, I found some time and deployed some rudimentary "hello world" apps to both platforms so I could begin to understand what the PaaS concept was all about. This was an enjoyable diversion for me, but it was also more of an academic exercise as I realised fairly quickly that the chances of one of my Customers actually working with one of these platforms was - well - close to zero (I might be wrong here...)

Then came the SAP NetWeaver Cloud, aka Neo. This Platform as a Service from SAP will allow Customers to explore what a Cloud Application Platform can offer, while providing secure connectivity to their "On Premise" investment. By having SAP offer this service, I believe Customers who may have had reservations about services such as Cloud Foundry and Heroku will feel more comfortable about building cloud hosted applications.

Hello World ?

"Hello World" apps are great, and the examples provided by the SAP NetWeaver Cloud team are worth completing so you can understand the tool chain for working with the platform. But what do we do next?

Initially I was interested in discovering how well the platform worked with different open source Java libraries. First I tried the Neo4J graph database. Success! But of course, after a successful "Hello World"  application I got stuck for a really worthy use case. I think I'd like to model and explore the data in the System Landscape Directory - but that will be for another time.

So, what next? I'd seen some presentations on a library called the "Disruptor". The Disruptor is a high performance concurrent programming framework for Java. If you're interested in high speed message processing it's well worth looking at. Would the Disruptor library run on the NetWeaver Cloud? Yes it will - although there are many options for the Disruptor around thread pool size etc that would need to be explored before using this in anger.

So, "Neo" seemed to be pretty happy with a range of Java libraries. What about other JVM based languages? Which brings us to Clojure...

Clojure

Clojure is a dynamic functional programming language that compiles to JVM bytecode. It's fun to work with. And it's concise - programs written in Clojure are small compared with their Java equivalent. Clojure is a dialect of Lisp - so expect some brackets!

One of the example applications provided with the NetWeaver Cloud documentation is "Adding Persistence to a Cloud Application Using JDBC". This is basically a DB backed web application that allows you to store a "Person" using the NetWeaver Cloud Persistence Service. Could this be written in Clojure and run on the NetWeaver Cloud?

The Clojure Web Stack

To build a Clojure Web application we need to use a couple of Clojure libraries. The first is Ring. Ring provides an HTTP abstraction, passing a map representing a request to a handler, and accepting a map representing a response from a handler. Maps are a data structure used widely by Clojure. For example, a map representing a response could look like this:

{:body "Hello, World!" :headers {} :status 200}

In ABAP terms, the Ring Library is similar to an HTTP Handler in the ICF.

The second library we need will handle the routing of requests. For this we will use Compojure. Compojure allows us to define which function will handle which HTTP request. The simplest way to demonstrate Compojure is to show how it's used for the sample web application.

(defroutes build-route-map

  (GET "/" [] (do-get))

  (POST "/" {person :params} (do-post person))

  (route/not-found "Page not found"))

The above code defines the valid routes (urls) for the web application. We use the macro defroutes provided by the Compojure library to do this by defining a function do-get to handle GET requests and a function do-post to handle POST requests. All other requests drop through to the not-found function. Any form parameters sent as part of the POST request are passed directly to the do-post function.

The last library we need is for html generation. For this we will use Hiccup. Hiccup simply uses vectors (a vector can be considered syntactically similar to a Java ArrayList) to represent html elements. . For example,

(html [:span {:class "foo"} "bar"]) produces <span class="foo">bar</span>

Show me the Code!

The source code for the web application can be found at https://github.com/alisdair73/clojure_webapp. Rather than go through a line by line discussion of the code, I encourage you to take a look at the code and work through the process of building and testing the application yourself. When people talk about writing code that is intention revealing, we can really see this in Clojure due to its concise style and low-ceremony syntax.

To help you on your way,

  • project.clj contains the project dependencies required to build the web application. It also contains the entry point for the application (app-setup).
  • To deploy the application to the NetWeaver Cloud, the Clojure web application must first be assembled into a war file. To do this we use a plugin called lein-ring. Lein-ring will also generate a web.xml file for us, but in this case we specifically tell lein-ring to use an already defined web.xml file so we can add the jndi reference for the Cloud Persistence Service.
  • Use the SAP NetWeaver Neo Console Client to deploy your war file. I recommend using a .properties file rather than using the command line directly.

As I mentioned before, Clojure is concise. It's beautiful to work with . Take the following example which shows one of the great capabilities of functional languages.

(defn write-persons[persons]

  (map (fn [person] [:tr [:td (person :firstname)]

                         [:td (person :lastname)]

                         [:td (person :id)]]) persons))

Here we pass in a vector containing all the selected records from the database and get back a vector representing the data as an HTML table. The map function applies the anonymous function to each record in the vector. Very cool stuff...

And in closing, the blog wouldn't be complete without the proof that it actually works!

So, why limit yourself to Java? Get a free account and get started!

1 Comment
Labels in this area