In this exercise we will add a backend database to the previous deployed SpringBoot application.
Important
|
Please replace userxx with the username assigned to you in the commands below. |
If you already created the SpringBoot application in the previous lab, just test one more thing. Try your application url
with /dbtest
(http://bootapp-spring-userxx.{{APPS_ADDRESS}}/dbtest) extension and it should list you some data from
the HSQLDB configured within the same app.
Let’s take a moment to understand how this application is connecting to
the HSQLDB. Look at the application.properties
file in the code
https://github.com/RedHatWorkshops/spring-sample-app/blob/master/application.properties
and we have configured these spring datasource variables to use hsqldb.
spring.datasource.platform=hsqldb spring.datasource.url=jdbc:hsqldb:file:/opt/app-root/src/mydb;shutdown=true spring.datasource.username=user spring.datasource.password=password
Of course, https://github.com/RedHatWorkshops/spring-sample-app/blob/master/pom.xml has the required dependencies. So springboot is able to create the in memory database.
Where is the data coming from? See these two files:
This is the data displayed when you invoke dbtest endpoint. Pretty straight forward.. isn’t it!!
In this lab, we will deploy the same as a 2-tier application by adding a MySQL database running as a separate pod.
Step 1: Add a MySQL database to this project
Based on what you learnt in the previous labs, you know what to do!!
Important
|
Please replace userxx with the username assigned to you in the commands below. |
Make sure you are in the spring-userxx
project where your springboot
application is running. Click on Add to project
on your webconsole,
select MySQL Ephemeral
from the catalog and deploy it.
When you are deploying this database you will have to choose the following values:
Database Service Name: mysql
MySQL Connection Username: user
MySQL Connection Password: password
MySQL Database Name: sampledb
Feel free to use your own values, but make a note of the same (write down..we will need these)
Click on the Create
button and within a few min or two your MySQL
database pod should be up and running.
Step 2: Configuring database connection params
The simplest way is to edit application.properties
file to the values
you noted in the last step i.e.
spring.datasource.platform=mysql spring.datasource.url=jdbc:mysql://mysql.spring-userxx:3306/sampledb?useSSL=false spring.datasource.username=user spring.datasource.password=password
But wait, that requires you to rebuild he code and deploy.
So, is there another way?.. Yes Let’s use a ConfigMap
.
ConfigMaps allow you to keep the configuration artifacts decoupled from the image content. More details here. We will see use them here and understand their flexibility in the next lab.
Lets create configMap in the Web UI.
Important
|
Please replace username with the username assigned to you in the commands below. |
-
Click into the
spring-username
project if you are not in the project -
Click
Resources
-→Config Maps
-
Click
Create Config Map
on top right -
Enter
app-props
as Name -
Enter
application.properties
as key -
Copy and paste following contents to the value text area Make sure you update the
userxx
and the values match what you gave when creating MySQL database``` spring.datasource.platform=mysql spring.datasource.url=jdbc:mysql://mysql.spring-userxx:3306/sampledb?useSSL=false spring.datasource.username=user spring.datasource.password=password ```
-
Click
Create
You need to make sure that you substitute the correct values you noted in the last step when you are creating the service. *Be extra-careful.. read instructions below.* Specifically note the datasource url. It is in the following format: `spring.datasource.url = jdbc:<<databasetype>>://<<service-host>>:<<service-port>>/<<dbname>>?useSSL=false`
You can replace `service-host` by the IP address of your MySQL service or the Service name. In the above example, I am using the service name for example `mysql.spring-userxx`. Here `mysql` is the name of the service and `spring-userxx` is the project name. This is a fully qualified way to let your application do service discovery in OpenShift (it uses SkyDNS).
If you made a mistake you can always edit the ConfigMap using
So far, we have created a ConfigMap in the project but your springboot application does not know how to use it.
Step 3: Edit Deployment Configuration
Now we will mount the ConfigMap so that the springboot application can use it. You can either edit from CLI or from WebConsole.
-
If using WebConsole, navigate to
Applications
→`Deployments`→`bootapp`. The screen should show Deployment Configuration details for thebootapp
application. On the right top, chooseActions
dropdown andEdit YAML
. -
If you are doing from CLI, you can run
oc edit dc bootapp
Scroll down to container spec, that looks like this:
spec: containers: - name: bootapp image: '172.30.85.130:5000/spring-userxx/bootapp@sha256:79e188d712e1209b933870c7d064423af281f16b371fb5e5911dfb09a6867776' ports: - containerPort: 8080 protocol: TCP resources: terminationMessagePath: /dev/termination-log imagePullPolicy: Always restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst securityContext:
Note there could be multiple `spec`s in your DC.
We will now add a volume that points to our ConfigMap right under
spec
. It is explained here
https://docs.openshift.com/container-platform/latest/dev_guide/configmaps.html#configmaps-use-case-consuming-in-volumes
spec: volumes: - name: app-props-volume configMap: name: app-props
Warning
|
Be super-careful with indentation |
We will now add volumeMount
to mount the volume
that we just added
into the pod. It should be right under the container name:
as shown
below.
containers: - name: bootapp volumeMounts: - name: app-props-volume mountPath: /opt/app-root/src/config
Warning
|
Be super-careful with indentation |
After the changes, the template
section in the dc, should now look
like this
template: metadata: creationTimestamp: null labels: app: bootapp deploymentconfig: bootapp spec: volumes: - name: app-props-volume configMap: name: app-props containers: - name: bootapp volumeMounts: - name: app-props-volume mountPath: /opt/app-root/src/config image: '172.30.85.130:5000/spring-userxx/bootapp@sha256:79e188d712e1209b933870c7d064423af281f16b371fb5e5911dfb09a6867776' ports: - containerPort: 8080 protocol: TCP resources: terminationMessagePath: /dev/termination-log imagePullPolicy: Always restartPolicy: Always terminationGracePeriodSeconds: 30 dnsPolicy: ClusterFirst securityContext:
So what is this location /opt/app-root/src/config
?
If you get into the terminal of the pod (you should know how to do this
by now!) and run pwd
, it will show that the home
directory is
/opt/app-root/src
. If you copy the application.properties
file in
the config
folder, SpringBoot will pick that first. Hence we mounted
the folder /opt/app-root/src/config
.
Save the changes and exit. If you now got the Overview
page, you will
see that the pod gets re-deployed. Yes, redeployed, not rebuilt (no S2I
build process).
Step 4: Verify the changes
Once the deployment is complete:
1. Click on the pod circle
2. Click on the pod name
3. Get into the Terminal
tab
4. Verify that your application.properties
are now available in the
config
folder
sh-4.2$ ls config application.properties sh-4.2$ cat config/application.properties # replace your own values based on the database service you created # url = jdbc:mysql://<<service-host>>:<<service-port>>/<<dbname>>?useSSL=false spring.datasource.platform=mysql spring.datasource.url= jdbc:mysql://mysql.spring-userxx:3306/sampledb?useSSL=false spring.datasource.username=user spring.datasource.password=password
Note the contents of this file are what you added to the ConfigMap.
Step 5: Test your application
Go back to the Overview
page. Click on your application url which
would be something like
http://bootapp-spring-userxx.{{APPS_ADDRESS}}/
It will open a new tab and your running application will greet you
Hello from bootapp-2-06a4b
Now move back to your webconsole and watch the pod logs.
Now access the application with the /dbtest
extension -
http://bootapp-spring-userxx.{{APPS_ADDRESS}}/dbtest
It should show the data from your MySQL database.
Customers List CustomerId: 2 Customer Name: Joe Mysql Age: 88 CustomerId: 3 Customer Name: Jack Mysql Age: 54 CustomerId: 4 Customer Name: Ann Mysql Age: 32
Where did this data come from? Look at * https://github.com/RedHatWorkshops/spring-sample-app/blob/master/src/main/resources/schema-mysql.sql was used to initialize the MySQL database * https://github.com/RedHatWorkshops/spring-sample-app/blob/master/src/main/resources/data-mysql.sql was used to populate data. I added 'Mysql' as part of the names to make it easy ;)
Also note that your logs show the connection url, just to verify which database you are connecting to.
connection url: jdbc:mysql://mysql.spring-userxx:3306/sampledb?useSSL=false
Bonus Points: Log into the MySQL instance and verify the data in the customer table for extra points!!
In this lab exercise, you have learnt how to set up a multi-tiered application and also to pass configuration information using ConfigMaps. In the next lab, we will learn to use ConfigMaps to dynamically update the configuration without restarting the pod!!