Skip to content

Commit

Permalink
Updates for Spring Boot externalized configuration (#1199)
Browse files Browse the repository at this point in the history
Part of #1060
  • Loading branch information
edeandrea authored Jun 21, 2021
1 parent de13ae1 commit 2dc41bf
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 64 deletions.
Binary file removed assets/middleware/rhoar-microservices/configmap.png
Binary file not shown.
Binary file modified assets/middleware/rhoar-microservices/editconfigmap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed assets/middleware/rhoar-microservices/edityaml.png
Binary file not shown.
Binary file modified assets/middleware/rhoar-microservices/greeting-service-mini.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion developing-with-spring-pathway.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"pathway_id": "middleware/middleware-spring-boot",
"course_id": "microservices-1",
"title": "Externalized Configuration",
"description": "Externalized Configuration and Health Checks"
"description": "Externalized Configuration"
},
{
"external_link": "https://learn.openshift.com/middleware/courses/middleware-spring-boot/monitoring",
Expand Down
2 changes: 1 addition & 1 deletion middleware/middleware-spring-boot-pathway.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"external_link": "https://learn.openshift.com/middleware/courses/middleware-spring-boot/microservices-1",
"course_id": "microservices-1",
"title": "Externalized Configuration",
"description": "Externalized Configuration and Health Checks"
"description": "Externalized Configuration"
},
{
"external_link": "https://learn.openshift.com/middleware/courses/middleware-spring-boot/monitoring",
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
In this scenario you will learn more about developing Spring Boot Microservices using the [Red Hat OpenShift Application Runtimes](https://developers.redhat.com/products/rhoar) platform. You will learn about Externalized Configurations and how we can use Externalized Configurations to change specific values/variables without having to take down the entire application. <!-- and Health Checks. -->
In this scenario you will learn more about developing Spring Boot Microservices using the [Red Hat Runtimes](https://www.redhat.com/en/products/runtimes) platform. You will learn about Externalized Configurations and how we can use Externalized Configurations to change specific values/variables without having to take down the entire application.
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# Review the base structure of the application

For your convenience, this scenario has been created using the OpenShift Launcher found [here](https://launch.openshift.io/launch/filtered-wizard/all). This launcher will automatically generate a zip file of a project that's in a ready-to-deploy state. We've selected the `Externalized Configuration` project and will be using the Spring Boot runtime option.
# Import the code
Let's refresh the code we'll be using. Run the following command to clone the sample project:

`cd /root/projects && rm -rf rhoar-getting-started && git clone https://github.com/openshift-katacoda/rhoar-getting-started && cd rhoar-getting-started/spring/microservices-externalized-config`{{execute}}

# Review the base structure of the application
**1. Understanding the Application**

The project is a simple Greeting application, where a user inputs a fruit and is greeted by our service. Opening up our ``greeting-service/src/main/java/io/openshift/booster/service/FruitController.java``{{open}} file we can see the logic used to respond to our user. The interesting part of this logic is right here, where we retrieve the message:
The project is a simple Greeting application, where a user inputs a fruit name and is greeted by our service. Opening up our ``src/main/java/com/example/service/FruitController.java``{{open}} file we can see the logic used to respond to our user. The interesting part of this logic is right here, where we retrieve the message:

```java
String message = String.format(properties.getMessage(), name);
```

If we take a closer look at this `properties` object, we see that it's of type `MessageProperties`. When we look at that file ``greeting-service/src/main/java/io/openshift/booster/service/MessageProperties.java``{{open}} we see an annotation linking to a configuration file, `@ConfigurationProperties("greeting")`, which is pointing to our ``greeting-service/src/main/resources/application-local.properties``{{open}} file.
If we take a closer look at this `properties` object, we see that it's of type `MessageProperties`. When we look at that file ``src/main/java/com/example/service/MessageProperties.java``{{open}} we see an annotation linking to a configuration prefix, `@ConfigurationProperties("greeting")`, which is pointing to our ``src/main/resources/application-local.properties``{{open}} file.

Our `application-local.properties` file contains only one property, `greeting.message`. This is the message that we return and display to the user. In order to get an understanding of the flow, let's run the application locally. On the terminal build the project:

Our `application-local.properties` file contains only one property, `greeting.message`. This is the message that we return and display to the user. In order to get an understanding of the flow, let's run the application locally. First cd into the project directory and build the project:
``mvn -f greeting-service spring-boot:run``{{execute}}

``mvn spring-boot:run``{{execute}}
``mvn spring-boot:run``{{execute}}

When the application finishes building click the **local web browser** or click [here](https://[[HOST_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com/). You should see the same message that is in the `application-local.properties` file.
When the application finishes building, click the **local web browser** or click [here](https://[[CLIENT_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com). You should see the same message that is in the `application-local.properties` file.

Be sure to stop the application with `ctrl-c`.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,48 @@
# Login and Deploy to OpenShift Application Platform
# Deploy to OpenShift Application Platform

**1. Login to the OpenShift Container Platform**
**1. Create a project**

To login, we will use the `oc` command and then specify a username and password like this:

``oc login [[HOST_SUBDOMAIN]]-8443-[[KATACODA_HOST]].environments.katacoda.com --insecure-skip-tls-verify=true -u developer -p developer``{{execute}}

Next we create the project that we'll be adding our application to:
Let's first create a new project:

``oc new-project dev --display-name="Dev - Spring Boot App"``{{execute}}

**2. Additional Configuration**

Before we deploy the application, we have to make a few changes so our application runs smoothly using External Configurations.

The first step is we're going to assign view access rights to the our deveoper account. We have to do this before deploying the application so that it's able to access the OpenShift API and read the contents of the ConfigMap. We can do that with the following command:
The first step is we're going to assign view access rights to the service account we're logged in as. We have to do this before deploying the application so that it's able to access the OpenShift API and read the contents of the `ConfigMap`. We can do that with the following command:

``oc policy add-role-to-user view -n $(oc project -q) -z default``{{execute}}

We should see `role "view" added: "default"` as output. The next step is to create our ConfigMap configuration and deploy it to OpenShift using:
We should see `clusterrole.rbac.authorization.k8s.io/view added: "default"` as output. The next step is to create our `ConfigMap` configuration and deploy it to OpenShift using:

``oc create configmap app-config --from-file=greeting-service/src/main/etc/application.properties``{{execute}}
``oc create configmap spring-boot-configmap-greeting --from-file=src/main/etc/application.properties``{{execute}}

We will talk about ConfigMaps in greater detail in the next section.
We will talk about `ConfigMap`s in greater detail in the next section.

>**NOTE:** The only two parameters this command needs are the name of the ConfigMap to create and the file location. This command is creating a ConfigMap named `app-config`. We're going to be using that name in future commands. If you decide to manually run the command or give the ConfigMap a different name, make sure you modify the other commands accordingly.
>**NOTE:** The only two parameters this command needs are the name of the ConfigMap to create and the file location. This command is creating a `ConfigMap` named `spring-boot-configmap-greeting`, which also happens to be the name of the application we're deploying. We're going to be using that name in future commands. If you decide to manually run the command or give the `ConfigMap` a different name, make sure you modify the other commands and configuration accordingly.
Now we're ready to deploy!

**3. Deploy the application to OpenShift**

Run the following command to deploy the application to OpenShift
Run the following command to deploy the application to OpenShift:

``mvn package fabric8:deploy -Popenshift``{{execute}}
``mvn oc:deploy -Popenshift``{{execute}}

There's a lot that happens here so lets break it down:

The `mvn package` piece of the above command instructs Maven to run the package lifecycle. This builds a Spring Boot JAR file which is a Fat Jar containing all dependencies necessary to run our application.
For the deployment to OpenShift we are using the [JKube](https://www.eclipse.org/jkube/) tool through the [`openshift-maven-plugin`](https://www.eclipse.org/jkube/docs/openshift-maven-plugin), which is configured in our ``pom.xml``{{open}} (found in the `<profiles/>` section). The deployment may take a few minutes to complete.

For the deployment to OpenShift we are using the [Fabric8](https://fabric8.io/) tool through the `fabric8-maven-plugin` which is configured in our ``pom.xml``{{open}} (found in the `<profiles/>` section).
You can run the command ``oc rollout status -w dc/spring-boot-configmap-greeting``{{execute}} to watch and wait for the deployment to complete.

Now that our application is deployed, navigate to our route in the OpenShift Web View or click [here](http://spring-boot-configmap-greeting-dev.[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/). We should see the following screen, meaning everything was successful:
Once the application deployment completes, navigate to our route in the OpenShift Web View or click [here](http://spring-boot-configmap-greeting-dev.[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/). We should see the following screen, meaning everything was successful:

![Greeting Service](/openshift/assets/middleware/rhoar-microservices/greeting-service-mini.png)

**4. Test functionality**

As the page suggests, we're going to put in a name and let our greeting service reply with a given greeting. Since our default value is `Greetings, you picked %s as your favorite fruit!`, that's what we should see after we fill in the textbox and click the button.

<!-- And indeed that's what we see:
![Hello Message](/openshift/assets/middleware/rhoar-microservices/hello-message.png) -->

As the page suggests, we're going to put in a name of a fruit and let our greeting service reply with a given greeting. Since our default value in our `ConfigMap` is `Greetings, you picked %s as your favorite fruit!`, that's what we should see after we fill in the textbox and click the button.

## Congratulations

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,38 @@

**1. The ConfigMap**

Configs maps are a useful tool for decoupling configuration settings from the code. ConfigMaps can be used to inject configuration data into a container in much the same way that secrets do, though ConfigMaps should not store confidential information. ConfigMap objects hold key-pair values representing all of your configuration data.
`ConfigMap`s are a useful tool for decoupling configuration settings from the code. `ConfigMap`s can be used to inject configuration data into a container in much the same way that secrets do, though `ConfigMap`s should not store confidential information. `ConfigMap` objects hold key-pair values representing all of your configuration data.

Notice the following dependency that was added to our `greeting-service/pom.xml`{{open}}. This allows us to integrate with OpenShift's ConfigMaps.
Notice the following dependency that was added to our `pom.xml`{{open}}. This allows us to integrate with OpenShift's ConfigMaps.

``` <dependency>
```
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
```

**2. Modify the ConfigMap**

Let's modify the greeting that our service is returning to the user. Since we set up the greeting in a properties file, we will not need to make any code change to change the functionality. This means that we won't need to have any downtime for this change, we're able to modify the response through our newly created ConfigMap from the previous step. We can edit our config map in the OpenShift Console. Click the **OpenShift Console** tab, select `Resources > Config Maps`. Then Select our ConfigMap `app-config`
Let's modify the greeting that our service is returning to the user. Since we set up the greeting in a properties file, we will not need to make any code change to change the functionality. This means that we won't need to have any downtime for this change, we're able to modify the response through our newly created `ConfigMap` from the previous step. We can edit our config map in the OpenShift Console. [Click here](https://console-openshift-console-[[HOST_SUBDOMAIN]]-443-[[KATACODA_HOST]].environments.katacoda.com/k8s/ns/dev/configmaps/spring-boot-configmap-greeting/yaml) to open our `ConfigMap` in a YAML editor.

![Greeting Service](/openshift/assets/middleware/rhoar-microservices/configmap.png)

Now Select `Edit YAML` from the actions menu in the upper right corner of the page.

![Greeting Service](/openshift/assets/middleware/rhoar-microservices/edityaml.png)
> **NOTE:** The username/password for the OpenShift console is `admin`.
Change the `greeting.message` property to: `greeting.message=Bonjour, you picked %s as your favorite fruit!`

![Greeting Service](/openshift/assets/middleware/rhoar-microservices/editconfigmap.png)

Hit `Save` and that's all there is to it!
Hit `Save` (at the bottom of the editor) and that's all there is to it!

**3. Test changes**

Now that we've modified the ConfigMap and deployed our changes, let's test the greeting service and see if it's returning our new value.
Now that we've modified the `ConfigMap` and deployed our changes, let's test the greeting service and see if it's returning our new value.
Click [here](http://spring-boot-configmap-greeting-dev.[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/) and put in a test value and click the button. Now instead of seeing `Greetings ...`, we should be seeing:

`Bonjour, you picked %s as your favorite fruit!`

<!-- `Bonjour <name>...`!
![Bonjour Message](/openshift/assets/middleware/rhoar-microservices/bonjour-message-minier.png) -->

This means that we were able to modify our application behavior through External Configuration of the `application.properties` file using a ConfigMap without having to even take down the application. That's pretty powerful!

## Congratulations

You have now learned how to handle Externalized Configuration with ConfigMaps through OpenShift. By creating a configmap, we're able to modify application properties on the fly and simply rollout the new changes to our application.
You have now learned how to handle Externalized Configuration with ConfigMaps through OpenShift. By creating a `ConfigMap`, we're able to modify application properties on the fly and simply rollout the new changes to our application.
4 changes: 2 additions & 2 deletions middleware/middleware-spring-boot/microservices-1/99-outro.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Spring Boot is a powerful and easy to use framework for developing everything fr

More background and related information on Red Hat OpenShift Application Runtimes and Eclipse Vert.x can be found here:

* [Red Hat OpenShift Application Runtimes for Developers](https://developers.redhat.com/rhoar) - Here you can get started with a project using different boosters and clone that project to your local computer. This also enables you to deploy your application on your own private OpenShift Container Platform or use OpenShift Online that is provided for free from Red Hat.
* [Project Snowdrop homepage](https://snowdrop.me/) - This site has a lot of details of the work that Red Hat is doing to make Spring work great on Kubernetes and OpenShift.
* [Red Hat Runtimes](https://www.redhat.com/en/products/runtimes) - Here you can get started with a project using different boosters and clone that project to your local computer. This also enables you to deploy your application on your own private OpenShift Container Platform or use OpenShift Online that is provided for free from Red Hat.
* [Project Snowdrop homepage](https://snowdrop.dev/) - This site has a lot of details of the work that Red Hat is doing to make Spring work great on Kubernetes and OpenShift.


5 changes: 2 additions & 3 deletions middleware/middleware-spring-boot/microservices-1/env-init.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
ssh root@host01 "git --git-dir=/root/projects/rhoar-getting-started/.git --work-tree=/root/projects/rhoar-getting-started pull"
ssh root@host01 "yum install tree -y"
ssh root@host01 "touch /etc/rhsm/ca/redhat-uep.pem"
mkdir -p /root/projects/rhoar-getting-started/spring/microservices-externalized-config
echo "-w \"\n\"" >> ~/.curlrc
20 changes: 15 additions & 5 deletions middleware/middleware-spring-boot/microservices-1/index.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"pathwayTitle": "RHOARSpringBoot",
"icon": "fa-openshift",
"title": "Externalized Configuration and Health Checks",
"description": "Externalized Configuration and Health Checks",
"icon": "fa-java",
"title": "Externalized Configuration",
"description": "Externalized Configuration",
"difficulty": "beginner",
"time": "15 minutes",
"details": {
Expand All @@ -23,16 +23,26 @@
"files": [],
"environment": {
"showdashboard": true,
"dashboards": [{"name":"Local Web Browser","port":8080},{"name":"OpenShift Console","port":8443}],
"dashboards": [
{
"name": "Local Web Browser",
"href": "https://[[CLIENT_SUBDOMAIN]]-8080-[[KATACODA_HOST]].environments.katacoda.com"
},
{
"name": "OpenShift Console",
"href": "https://console-openshift-console-[[HOST_SUBDOMAIN]]-443-[[KATACODA_HOST]].environments.katacoda.com"
}
],
"uilayout": "editor-terminal",
"uisettings": "java",
"hideintro": false,
"hideHiddenFiles": true,
"uieditorpath": "/root/projects/rhoar-getting-started/spring/microservices-externalized-config",
"uimessage1": "\u001b[32mYour Interactive Bash Terminal. A safe place to learn and execute commands.\u001b[m\r\n"
},
"backend": {
"autoUpgrade": false,
"imageid": "openshift-middleware-3-7",
"imageid": "openshift-4-7",
"port": 8443
}
}
17 changes: 15 additions & 2 deletions middleware/middleware-spring-boot/microservices-1/set-env.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
#!/bin/bash
cd projects/rhoar-getting-started/spring/microservices-externalized-config
~/.launch.sh

mkdir -p /root/projects/rhoar-getting-started/spring/microservices-externalized-config
cd /root/projects/rhoar-getting-started/spring/microservices-externalized-config

# Install Java 11
wget -O /tmp/jdk.tar.gz https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz && \
pushd /usr/local && \
tar -xvzf /tmp/jdk.tar.gz && \
rm -rf /tmp/jdk.tar.gz && \
export JAVA_HOME="/usr/local/jdk-11.0.10+9" && \
export PATH=$JAVA_HOME/bin:$PATH && \
echo "export JAVA_HOME=$JAVA_HOME" >> ~/.bashrc && \
echo "export PATH=$JAVA_HOME/bin:\$PATH" >> ~/.bashrc && \
popd

clear

0 comments on commit 2dc41bf

Please sign in to comment.