Polyglot

Build Valuable Systems, Better and Faster

Advanced Development and Delivery (ADD) [Part-10]

This is the tenth installment of describing a radically more productive development and delivery environment.

The first part is here: Intro. In the previous parts I described the big picture, Vagrant and EC2, node initialization, the one minute configuration HeartBeat, HipChat integration, presence, EC2, configuring nodes, and inter-machine presence.

A good, opinionated, framework

Back in 1972, Smalltalk became the first Object-Oriented Programming Language (Simula was Object-Based but there is a difference). For decades this kind of language was ‘esoteric’. It was like LISP or Prolog or APL: somehow exotic and inaccessible. I was lucky: I had access to Smalltalk at Caltech. I had access to lots of crazy expensive things at Caltech and that made the exotic (e.g. making your own chips) into the mundane (e.g. made lots of chips, they were commonly broken, had to be re-fabricated, and I eventually got bored with all that and moved a level up).

But back to the language of Smalltalk. The problem with Smalltalk is that it appears to be a language when it is actually a computer. ‘C’ was a language. It made programs. ‘Pascal’, ‘Lisp’ (sans Machine), ‘Fortan’, and so on… they were all languages. Smalltalk contains a language. It is named Smalltalk (darn). But Smalltalk-80 was not just a language, it was an entire running operating system with applications and full source It could boot on most any machine that you made the ‘bootstrap’ code work on. To make a new Smalltalk-80 machine, you cloned either the primordial Smalltalk-80 ‘image’ from PARC, or you cloned your own modified ‘image’. And by ‘image’ this is basically the same concept as cloning a disk… bit by bit identical copy that happens to be on a different disk / computer.

Eventually OOP became mainstream with Java, C++, Objective-C, Ruby, Python, and the like. So people thought they were getting the “Smalltalk” (or LISP Machine) benefits. But they left out the ‘computer’ that went with the language.

Why opinionated?

The Smalltalk computer was quite functional and thoroughly opinionated. It already did a bunch of things and showed you how it did them. It wasn’t opinionated like a human usually uses the term: “You should build that house out of bricks, not straw”. It was opinionated like the planet is: “I have already created lots of flora and fauna… please use them wisely”. Even how humans on the planet are: “We have already created plenty of roads… please use them instead of driving through yards”

Opinionated is basically a synonym for “Working”. Smalltalk computers “worked” so don’t break it. They work, so you should probably copy them for anything similar. And they work, so you might want to study how they work even if you are going to be creative later.

Modern ‘working’ frameworks

Early frameworks (say for Java) ‘kind-of-worked’. They didn’t fully work, but you could ‘configure’ them to work. That is like getting all ‘IKEA’ furniture for your house. You could easily build it wrong. It could not work together. Yes, you get to ‘tweak’ it, but if someone simply offered “a furnished house” you would save a lot of time and leverage their full sense of design. Or you could go to a different furnished house that more closely matched your tastes.

The later fully-working / opinionated frameworks (like Ruby/Rails) truly worked out of the box. They would come up with a UI, Business/Domain layer, and a Database layer. You could add things to the UI and it would go down the whole stack. Add things to the database or Domain, and it would bubble up/down. For the framework to do these things it had to have a model for what software (in its full form) looks like. These frameworks had patterns/templates/rules for building things at command. This isn’t quite as good as Smalltalk (“it already exists”) but it is getting close, especially with sample applications available. It also gets rid of the one problem / hurdle with Smalltalk full-computers: you had to strip them of things you didn’t want customers to see / use / clone.

Languages

There are many modern languages. They are mostly quite similar and boring in the language themselves. The community around the language makes much more of a difference, and the libraries / frameworks that exist based on that community’s interest.

I mentioned that I switched to Java pretty early on, which cost me productivity. But I wanted the community and their libraries. Java was popular enough that it had multiple communities associated with it. Some were crazy stupid and created things (even tried to mandate use of things) that were completely stupid. But other communities continued to plug along and evolve libraries and frameworks that are better than you can get in other languages. On the whole, I believe the Java ecosystem is by far the best ‘hub’ to build most custom development and to pair with other tools/components in other languages. And by Java, I mean Java, Groovy, and potentially other JVM-targeting languages. The less Java-like the language, the less likely I would consider it acceptably an ‘other’.

Framework

I believe the best (general) application framework in Java is Grails, which lives on top of the Spring stack. It is very mature and has good minds in the drivers seat. It gets simpler and more powerful every generation. If Spring does something right, Grails simply uses it. If not, Grails augments it. Very rational. Very powerful.

The first application

The first application will simply be the default applications with a grails ‘create-app’. To get the application we need to get grails on the ‘app1’ nodes, create the application, and then run it.

Grails needs Java, but ec2 instances automatically have that. In other environments we would use something like:

installJava.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
#================================================
#=== Java
#================================================

export JAVA_VERSION=7u79
export JAVA_FULL_VERSION=jdk-${JAVA_VERSION}-linux-x64

mkdir -p .temp
cp it/resource/${JAVA_FULL_VERSION}.rpm .temp/

./bin/inflatePaths.sh .temp/${JAVA_FULL_VERSION}.rpm

rpm -i .temp/${JAVA_FULL_VERSION}.rpm

The advantage of storing the RPM within our own system is speed of access and reliability. EC2 to S3 communication is very fast. And S3 has never been down (AFAIK) at all, let alone when EC2 is running. We also lock down on the version we want vs. using ‘yum’ without an explicit version.

installGrails3_x.sh

For grails we will get the latest version

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash
#==========================================================
#=== Install Grails 3.x
#==========================================================

curl -s get.sdkman.io | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
yes | sdk install grails

source ~/.bashrc
grails -version

We need to source ‘~/.bashrc’ so we get the additions to our path.

Create ‘test’ application

At this point we have grails on the machine and can simply

1
2
3
4
5
6
mkdir -p /root/app/
cd /root/app

grails create-app test
cd test
grails run-app

The application will come up at ‘localhost:8080’ and if you wget/curl it, it returns the generated ‘index.html’ file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!doctype html>
<html lang="en" class="no-js">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Welcome to Grails</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
...
        <div id="page-body" role="main">
            <h1>Welcome to Grails</h1>
            <p>Congratulations, you have successfully started your first Grails application! At the moment
               this is the default page, feel free to modify it to either redirect to a controller or display whatever
               content you may choose. Below is a list of controllers that are currently deployed in this application,
               click on each to execute its default action:</p>

            <div id="controller-list" role="navigation">
                <h2>Available Controllers:</h2>
                <ul>

                </ul>
            </div>
        </div>

        <div class="footer" role="contentinfo"></div>
        <div id="spinner" class="spinner" style="display:none;">Loading&hellip;</div>
    </body>
</html>

Firewalls

Unfortunately, you won’t be able to test this app from the outside unless you open the ‘8080’ port.

If we open that port either initially or through commands:

1
2
3
4
5
6
{
    "IpProtocol":"tcp",
    "FromPort":"8080",
    "ToPort":"8080",
    "CidrIp":"0.0.0.0/0"
}

We get the latest and greatest ‘Grails’ application (3.0.8 as of this writing)

Demo2: PetClinic

There is a PetClinic demo at: https://github.com/grails-samples/grails-petclinic . Doing the same simple launch procedure you would get something like this:

1
2
3
4
5
6
mkdir -p /root/app/
cd /root/app

git clone git@github.com:grails-samples/grails-petclinic.git
cd grails-petclinic
./gradlew run

And you get:

But an important difference between the two: the second is now wired into the git repository and can ‘pull’ or ‘push’ to it as needed. We now have a live server with both alive ‘IT’ and alive ‘APP’! It will happily and automatically bend to our will and needs.

Comments