Skip to content
Guide: Using the java-spring-boot2 collection and Appsody CLI
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
README.adoc

README.adoc

Developing cloud native microservice applications with the Spring Boot Collection and Appsody CLI

Note
This repository contains the guide documentation source. To view the guide in published form, view it on the website.

Explore how to use the Spring Boot Kabanero Collection and Appsody CLI to create, run, update, deploy, and deliver cloud native microservices.

What you’ll learn

You will use the Kabanero Spring Boot Collection with the Appsody CLI to create and run a simple cloud native microservice application. Then, you’ll update the application and deploy it to Kubernetes or Knative.

Kabanero’s Spring Boot Collection contains all the components you need to develop your microservice application, including the Spring Boot application stack and any necessary container build and deployment artifacts.

Prerequisites

  1. Docker must be installed.

  2. You must have access to a Kubernetes cluster. If you are using Docker for Desktop, you can enable Kubernetes from the menu by selecting Preferences → Kubernetes → Enable Kubernetes.

  3. Appsody must be installed.

  4. (Optional) If you have an enterprise-specific Kabanero Collection Hub, you need the URL to your index file.

Getting started

To obtain the Spring Boot Collection, Appsody must be configured to point to the Kabanero repository. The instructions in this guide use the public index for Kabanero Version 0.1.2, which you can replace with your enterprise-specific index if you have one.

Configuring Appsody

To check the repositories that Appsody can already access, run the following command:

appsody repo list

You see an output similar to the following example:

appsody repo list
NAME        URL
*appsodyhub https://github.com/appsody/stacks/releases/latest/download/incubator-index.yaml

Next, run the following command to add the Kabanero index:

appsody repo add kabanero https://github.com/kabanero-io/collections/releases/download/v0.1.2/kabanero-index.yaml

Check the available repositories again to see that the Kabanero repository was added:

appsody repo list
NAME        URL
*appsodyhub https://github.com/appsody/stacks/releases/latest/download/incubator-index.yaml
kabanero    https://github.com/kabanero-io/collections/releases/download/v0.1.2/kabanero-index.yaml

In this example, the asterisk (*) shows that appsodyhub is the default repository. Run the following command to set the Kabanero index as the default repository:

appsody repo set-default kabanero

Check the available repositories again to see that the default is updated:

appsody repo list
NAME        URL
appsodyhub  https://github.com/appsody/stacks/releases/latest/download/incubator-index.yaml
*kabanero   https://github.com/kabanero-io/collections/releases/download/v0.1.2/kabanero-index.yaml

Your Appsody CLI is now configured to use the Kabanero Collections. Next, you need to initialize your project.

Initializing your project

First, create a directory that will contain the project:

mkdir -p ~/projects/simple-spring-boot2
cd ~/projects/simple-spring-boot2

Run the following command to initialize your Spring Boot project with the Appsody CLI:

appsody init java-spring-boot2

The output from the command varies depending on whether you have an installation of Java on your system. The following output is from a system that has Java installed:

Running appsody init...
Downloading java-spring-boot2 template project from https://github.com/kabanero-io/collections/releases/download/v0.1.2/incubator.java-spring-boot2.v0.3.9.templates.default.tar.gz
Download complete. Extracting files from java-spring-boot2.tar.gz
Setting up the development environment
Running command: docker[pull kabanero/java-spring-boot2:0.3]
Running command: docker[run --rm --entrypoint /bin/bash kabanero/java-spring-boot2:0.3 -c find /project -type f -name .appsody-init.sh]
Extracting project from development environment
Running command: docker[create --name my-project-extract -v /home/username/projects/simple-spring-boot2/.:/project/user-app -v /home/username/.m2/repository:/mvn/repository kabanero/java-spring-boot2:0.3]
Running command: docker[cp my-project-extract:/project /home/username/.appsody/extract/simple-spring-boot2]
Running command: docker[rm my-project-extract -f]
Project extracted to /home/username/projects/simple-spring-boot2/.appsody_init
Running command: ./.appsody-init.sh[]
Successfully initialized Appsody project

Your project is now initialized.

Understanding the project layout

Here is an example of the project structure that is visualized from the command line:

./.vscode
./.gitignore
./.appsody-config.yaml


./src/main/java/application/Main.java
./src/main/java/application/LivenessEndpoint.java

./src/test/java/application/MainTests.java

./src/main/resources/application.properties
./src/main/resources/public/index.html

./pom.xml

To avoid deleting unnecessary files, this project is minimized to contain the following artifacts:

  • Main.java, a Spring Application class

  • LivenessEndpoint.java, an example Liveness Endpoint

  • MainTests.java, a simple test class

  • application.properties, containing some configuration options for Spring

  • index.html, a static file

  • pom.xml, the project build file

Running the Appsody development environment

Run the following command to start the Appsody development environment:

appsody run

The Appsody CLI launches a local docker container that compiles and hosts the microservice. After some time, you see a message similar to the following example:

[Container] 2019-09-12 17:28:44.066  INFO 171 --- [  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 4 endpoint(s) beneath base path '/actuator'
[Container] 2019-09-12 17:28:44.205  INFO 171 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
[Container] 2019-09-12 17:28:44.209  INFO 171 --- [  restartedMain] application.Main                         : Started Main in 6.051 seconds (JVM running for 6.923)

This message indicates that the Tomcat server is started and you are ready to begin development.

Creating and updating the application

You will create a simple new REST endpoint and add it to the application.

Navigate to the endpoint with a browser to confirm that the endpoint does not currently exist. Point your browser to the http://localhost:8080/example URL. You see the following HTTP 404 error that shows Spring’s default Whitelabel Error Page:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Thu Sep 12 17:29:43 UTC 2019
There was an unexpected error (type=Not Found, status=404).
No message available

Go to the src/main/java/application directory that’s within your project folder. Create a file named ExampleEndpoint.java. Open the file, populate it with the following code, and save it:

package application;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleEndpoint {

    @RequestMapping("/example")
    public String example() {
        return "This is an example";
    }
}

After you save, the source compiles and the application updates. You see messages similar to the following example:

[Container] Running: /project/java-spring-boot2-build.sh recompile
[Container] Compile project in the foreground
[Container] > mvn compile
[Container] [INFO] Scanning for projects...
[Container] [INFO]
[Container] [INFO] ----------------------< dev.appsody:application >-----------------------
[Container] [INFO] Building application 0.0.1-SNAPSHOT
[Container] [INFO] --------------------------------[ jar ]---------------------------------
[Container] [INFO]
[Container] [INFO] --- maven-resources-plugin:3.1.0:resources (default-resources) @ application ---
[Container] [INFO] Using 'UTF-8' encoding to copy filtered resources.
[Container] [INFO] Copying 2 resources
[Container] [INFO]
[Container] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ application ---
[Container] [INFO] Changes detected - recompiling the module!
[Container] [INFO] Compiling 3 source files to /project/user-app/target/classes
[Container] [INFO]
[Container] [INFO] --- maven-antrun-plugin:1.1:run (trigger-spring-restart) @ application ---
[Container] [INFO] Executing tasks
[Container]      [echo] Triggering Spring app restart.
[Container] [INFO] Executed tasks
[Container] [INFO] ------------------------------------------------------------------------
[Container] [INFO] BUILD SUCCESS
[Container] [INFO] ------------------------------------------------------------------------
[Container] [INFO] Total time:  3.585 s
[Container] [INFO] Finished at: 2019-09-12T17:34:37Z
[Container] [INFO] ------------------------------------------------------------------------
[Container] 2019-09-12 17:34:38.316  INFO 171 --- [      Thread-15] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
[Container]
[Container]   .   ____          _            __ _ _
[Container]  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
[Container] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
[Container]  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
[Container]   '  |____| .__|_| |_|_| |_\__, | / / / /
[Container]  =========|_|==============|___/=/_/_/_/
[Container]  :: Spring Boot ::        (v2.1.6.RELEASE)
...
[Container] 2019-09-12 17:34:39.711  INFO 171 --- [  restartedMain] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 4 endpoint(s) beneath base path '/actuator'
[Container] 2019-09-12 17:34:39.772  INFO 171 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
[Container] 2019-09-12 17:34:39.773  INFO 171 --- [  restartedMain] application.Main                         : Started Main in 1.403 seconds (JVM running for 362.487)
[Container] 2019-09-12 17:34:39.788  INFO 171 --- [  restartedMain] .ConditionEvaluationDeltaLoggingListener : Condition evaluation unchanged

Now if you browse to the http://localhost:8080/example URL, you no longer see the HTTP error. Instead, the endpoint response is displayed, as shown in the following output:

This is an example

Try changing the message in the ExampleEndpoint.java file, then save and refresh the page. You’ll see that it takes only a few seconds for the change to take effect.

Deploying to Kubernetes

After you finish writing your application code, the Appsody CLI makes it easy to deploy to a Kubernetes cluster for further tesing. Ensure that your kubectl command is configured with cluster details and run the following command to deploy the application:

appsody deploy

This command builds a new docker image that is optimised for production deployment and deploys the image to your Kubernetes cluster. After some time you see a message similar to the following example:

Deployed project running at http://localhost:30262

Run the following command to check the status of the application pods:

kubectl get pods

In the following example output, you can see that the simple-spring-boot2 pod is running:

NAME                                   READY   STATUS    RESTARTS   AGE
appsody-operator-859b97bb98-xm8nl      1/1     Running   1          8d
simple-spring-boot2-77d6868765-bhd8x   1/1     Running   0          3m21s

Go to the URL that was returned in the previous step, and you see the Appsody microservice splash screen. Go to http://localhost:30262/example and you see your deployed application response.

Use the following command to stop the deployed application:

appsody deploy delete

After you run this command and the deployment is deleted, you see the following message:

Deployment deleted

Deploying to Knative

You can also choose to deploy the application with Knative serving.

If you do not have Knative installed in your Kubernetes cluster, complete the installation instructions in the Knative documentation before continuing.

Run the following command to generate an app-deploy.yaml file:

appsody deploy —generate-only

Open the app-deploy.yaml file and add the following information to the spec definition:

createKnativeService: true

Run the following command to deploy the application from your local image registry:

appsody deploy --tag dev.local/simple-spring-boot2 --namespace <namespace>

Alternatively, run the following command to deploy the application from Docker Hub:

appsody deploy --push -—tag <my-account>/simple-spring-boot2 --namespace <namespace>

After the application deploys, you see a message similar to the following example that details the serving URL:

Deployed project running at "http://simple-spring-boot2.knative-serving.192.168.1.10.nip.io"

To see the response from your application, point your browser to <URL_STRING>/example, where <URL_STRING> is the URL that was returned in the previous step.

Delivering to enterprise pipelines

After you develop and test your application, it’s time to deliver it to your enterprise Kabanero pipelines. To deliver it to the pipelines, push the project to a pre-configured Git repository. This repository can be public or enterprise. Your operations team configures the webhooks on the repository that trigger the pipelines.

Nice work!

You can’t perform that action at this time.