Skip to content
This repository has been archived by the owner on May 29, 2024. It is now read-only.

Creator: Architecture

Tako Schotanus edited this page Jul 29, 2019 · 4 revisions

How does it work?

The implementation of the Launcher Creator is based on a paradigm that uses Capabilities and Generators to do its work, all of which will be explained below.

Capabilities are classes that bundle one or more Generators to add a set of features to a generated project that together implement a useful and fleshed-out use-case.

Generators on the other hand are packages of files and resources that are used to add features and make changes to a user's project. Each Generator generally only makes a very specific and limited set of changes, using the UNIX philosophy of "Do one thing and do it well".

Capabilities Generators
manage do
Manage the creation of fully working code Create highly specific pieces of code or configuration
Are completley independent of each other Are generally very dependent on the work done by other Generators
Don't make changes to the project Make changes to the project
Don't have resources, never copy any files Can have resources, can copy, create and change files
Can have complex heuristics Are generally very simple
Are visible to the user Never show up in the UI
Get their input from the user Get their input from Capabilities or other Generators

Generators

So more specifically a Generator named "mysql" might create the necessary OpenShift/K8s Resources to set up a database service on OpenShift. Another one named "node-database" might create the code to connect to a database from Node.js. And so forth.

The following diagram shows how a generator would receive input from its caller (either a Capability or another Generator) and how its output would be new files copied to (or existing files being changed in) the target project:

A diagram of a Generator

In the basic HOWTO Create a Generator you can read how Generators can delegate part of their work to other Generators, which would change the diagram to look somewhat like this:

A diagram of a Generator applying another Generator

Capabilities

On the other hand, a "Database" Capability might call on a Generator that would create a mySQL database service, as described above, while using another to create the Secret that will store the database's connection information. Yet another Generator would create the Java code based on the Vert.x framework and copy that to the user's project. The choice of database (mySQL, PostgreSQL, etc) and code language and framework (Node.js, Vert.x, Spring Boot, etc) could be options that the user can pass to the Capability. In that aspect a Capability can be as complex as you want it to be.

Combining all that with the diagrams seen above we get:

A diagram of a Capability using Generators

These diagrams might all be a bit abstract, so let's take a look what would happen if you would run the following command:

$ creator apply --project test --name test --runtime vertx database

Which would create an application with the name "test" in a local folder also named "test" using Vert.x as its runtime and adding a "database" Capability.

You could of course also use the Launcher Web UI to do the same thing, the result would be the same.

So the following diagram shows the flow from the Database Capability through all the Generators that get called. Each indent to the right shows a caller-callee dependency:

A diagram showing a Capability and Generators being applied

If we number from top to bottom the flow would be:

  1. The "Database" Capability gets applied. Nothing changes yet because as explained before Capabilities don't make changes.
  2. The "database-postgresql" Generator gets applied by the Capability. It doesn't add any files itself, it just delegates to the next Generator in point 3 and afterwards adds some ENV vars to the Resource Definitions that were created.
  3. The "app-images" Generator gets applied. An .openshiftio/application.yaml file gets created with Resource Definitions for starting a Service running a PostgreSQL container image on a Kubernetes or OpenShift cluster.
  4. The "database-crud-vertx" Generator gets applied by the Capability. It adds all the code, configuration and resources needed to access the database.
  5. The "runtime-vertx" Generator gets applied. It copies all the files necessary to build and run a Vert.x project.
  6. The "language-java" Generator gets applied. It copies just a single file: the gap script used to easily build and deploy projects to a Kubernetes or OpenShift cluster.
  7. The "app-images" Generator gets applied. The .openshiftio/application.yaml file that was created earier gets updated with Resource Definitions for starting a Service running a Java container image on a Kubernetes or OpenShift cluster.
  8. The "runtime-base-support" Generator gets applied. It takes care of some infrastructure issues when dealing with multiple public services in a single project.
  9. The "maven-setup" Generator gets applied. This updates the main POM file for Maven based Java project.

The final directory structure of the created project would look somewhat like this (simplified):

test
├── deployment.json [1]
├── gap [6]
├── LICENSE [5]
├── .openshiftio
│   └── application.yaml [3, 7]
├── pom.xml [5]
├── README.md [5]
└── src [4, 5]
    └── main [4, 5]
        └── java [4, 5]
            └── io [4, 5]
                └── openshift [4, 5]
                    └── booster [4, 5]
                        ├── database [4]
                        │   ├── CrudApplication.java
                        │   ├── DBInitHelper.java
                        │   ├── Errors.java
                        │   └── service
                        │       ├── impl
                        │       │   └── JdbcProductStore.java
                        │       └── Store.java
                        ├── MainApplication.java [5]
                        └── RouterConsumer.java [5]