Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WFLY-14563] todo-backend quickstart
Add a new quickstart `todo-backend` to showcases a typical use of WildFly: a backend that exposes a Web API (using JAX-RS) and connects to a DB (using JPA). The quickstart focuses on local and cloud deployment with Bootable Jar and showcase the following features: * use the wildfly-datasources-galleon-pack to connect to an external PostgreSQL database * Execute a CLI script at build time to specialize the WildFly runtime provisioned by the Bootable Jar * Use of Helm Charts for cloud deployment JIRA: https://issues.redhat.com/browse/WFLY-14563 Signed-off-by: Jeff Mesnil <jmesnil@redhat.com>
- Loading branch information
Showing
14 changed files
with
1,002 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,304 @@ | ||
include::../shared-doc/attributes.adoc[] | ||
|
||
= todo-backend: quickstart for backend deployment on OpenShift | ||
:toc: left | ||
:icons: font | ||
:idprefix: | ||
:idseparator: - | ||
:keywords: openshift,galleon,helm | ||
:level: Intermediate | ||
:technologies: JPA, JAX-RS, OpenShift, Galleon | ||
|
||
[abstract] | ||
The `todo-backend` quickstart demonstrates how to implement a backend that exposes a HTTP API with JAX-RS | ||
to manage a list of ToDo which are persisted in a database with JPA. | ||
|
||
This quickstart shows how to setup a local deployment of this backend as well as a deployment on OpenShift to connect | ||
to a PostgreSQL database also hosted on OpenShift. | ||
|
||
|
||
== What is it? | ||
|
||
The `todo-back` quickstart demonstrates how to implement a backend that exposes a HTTP API with `JAX-RS` | ||
to manage a list of ToDo which are persisted in a database with `JPA`. | ||
|
||
* The backend exposes a HTTP API to manage a list of todos that complies with the specs defined at https://todobackend.com/specs/index.html[todobackend.com]. | ||
* It requires a connection to a PostgreSQL database to persist the todos. | ||
* It uses the Bootable Jar for local and cloud deployment | ||
* It is deployed on OpenShift using the https://docs.wildfly.org/wildfly-charts/[Helm Chart for ${productName}]. | ||
|
||
== Architecture | ||
|
||
// System Requirements | ||
include::../shared-doc/system-requirements.adoc[leveloffset=+1] | ||
|
||
This backend is built and deployed as Bootable Jar that provisions the {productName} application server and all the feature packs it needs for its features. | ||
The layers are defined in the `pom.xml` file in the `<configuration>` section of the `org.wildfly.plugins:wildfly-jar-maven-plugin` plugin: | ||
|
||
[source,xml] | ||
---- | ||
<layers> | ||
<layer>cloud-server</layer> | ||
<layer>postgresql-datasource</layer> | ||
<layer>ejb</layer> | ||
</layers> | ||
---- | ||
|
||
The `cloud-server` and `ejb` layers provides everything need to run the backend on OpenShift. This also includes access to | ||
Jakarta EE APIs such as CDI, JAX-RS, JPA, etc. These two layers comes from the {productName} feature pack provided by the Bootable Jar plugin: | ||
|
||
[source,xml] | ||
---- | ||
<feature-pack> | ||
<location>wildfly@maven(org.jboss.universe:community-universe)#${version.server.bootable-jar}</location> | ||
</feature-pack> | ||
---- | ||
|
||
The `postgresql-datasource` layer provides a JDBC driver and DataSource to connect to a PostgreSQL database. It is not provided | ||
by the {productName} feature pack but by an extra feature pack: | ||
|
||
[source,xml] | ||
---- | ||
<feature-pack> | ||
<groupId>org.wildfly</groupId> | ||
<artifactId>wildfly-datasources-galleon-pack</artifactId> | ||
<version>${version.wildfly-datasources-galleon-pack}</version> | ||
</feature-pack> | ||
---- | ||
|
||
The Git repository for this feature pack is hosted at https://github.com/wildfly-extras/wildfly-datasources-galleon-pack. | ||
It provides JDBC drivers and datasources for different databases but for this quickstart, we will only need the `postgresql-datasource`. | ||
|
||
=== Connection to the PostgreSQL database | ||
|
||
As mentioned, the JDBC drivers and datasource configuration that the backend uses to connect to the PostgreSQL database | ||
is provided by the `org.wildfly:wildfly-datasources-galleon-pack` feature pack. By default, it exposes a single datasource. | ||
In the backend, the name of this datasource is `ToDos` and is specified in the `persistence.xml` to configure JPA: | ||
|
||
[source,xml] | ||
---- | ||
<persistence-unit name="primary"> | ||
<jta-data-source>java:jboss/datasources/ToDos</jta-data-source> | ||
</persistence-unit> | ||
---- | ||
|
||
At runtime, we only need a few environment variables to establish the connection from {productName} to the external PostgreSQL database: | ||
|
||
* `POSTGRESQL_DATABASE` - the name of the database (that will be called `todos`) | ||
* `POSTGRESQL_SERVICE_HOST` - the host to connect to the database | ||
* `POSTGRESQL_SERVICE_PORT` - The port to connecto to the database | ||
* `POSTGRESQL_USER` & `POSTGRESQL_PASSWORD` - the credentials to connect to the database | ||
* `POSTGRESQL_DATASOURCE` - The name of the datasourcs (as mentioned above, it will be `ToDos`) | ||
|
||
=== Filters for Cross-Origin Resource Sharing (CORS) | ||
|
||
The Web frontend for this quickstart uses JavaScript calls to query the backend's HTTP API. | ||
We must enable Cross-Origin Resource Sharing (CORS) filters in the `undertow` subsystem of {productName}. | ||
|
||
As we use Bootable Jar to build the application, we provide a CLI script that contains all the commands to | ||
create and configure the CORS filters in Undertow. This script is located in the `src/scripts/cors_filters.cli`. | ||
|
||
This script is executed at build time and will provide the following HTTP headers to enabled CORS: | ||
|
||
* `Access-Control-Allow-Origin: *` | ||
* `Access-Control-Allow-Methods: GET, POST, OPTION, PUT, DELETE, PATCH` | ||
* `Access-Control-Allow-Headers: accept, authorization, content-type, x-requested-with` | ||
* `Access-Control-Allow-Credentials: true` | ||
* `Access-Control-Max-Age: 1` | ||
|
||
By default, the backend accepts requests from any origin (`*``). This is only simplicity. It is possible to restrict | ||
the allowed origin using the environment variable `CORS_ORIGIN` at runtime. | ||
|
||
== Package the backend as a Bootable Jar | ||
|
||
The backend is packaged as a Bootable Jar and configured to be deployable on OpenShift with the Maven Profile `bootable-jar-openshift` which is active | ||
by default: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ mvn clean package | ||
---- | ||
|
||
== Run the backend locally | ||
|
||
=== Local PostgreSQL database | ||
|
||
Before running the backend locally, we need to have a local PostgreSQL database that we can connect to. | ||
We use the `postgresql` docker image to create one: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ docker run --name todos-db \ | ||
-e POSTGRES_USER=todos \ | ||
-e POSTGRES_PASSWORD=mysecretpassword \ | ||
-p 5432:5432 \ | ||
postgres | ||
---- | ||
|
||
This will create a database named `todos-db` that we can connect to on `localhost:5432` with the credentials `todos / mysecretpassword`. | ||
|
||
=== Run the backend | ||
|
||
With the PostgreSQL database running, we can start the backend by passing the required environment variables to connect to the database: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ POSTGRESQL_DATABASE=todos \ | ||
POSTGRESQL_SERVICE_HOST=localhost \ | ||
POSTGRESQL_SERVICE_PORT=5432 \ | ||
POSTGRESQL_USER=todos \ | ||
POSTGRESQL_PASSWORD=mysecretpassword \ | ||
POSTGRESQL_DATASOURCE=ToDos \ | ||
java -jar target/todo-backend-bootable.jar | ||
... | ||
14:41:58,111 INFO [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0010: Deployed "todo-backend.war" (runtime-name : "ROOT.war") | ||
... | ||
---- | ||
|
||
The backend is running, and we can use the HTTP API to manage a list of todos: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
# get a list of todos | ||
$ curl http://localhost:8080 | ||
[] | ||
# create a todo with the title "This is my first todo item!" | ||
$ curl -X POST -H "Content-Type: application/json" -d '{"title": "This is my first todo item!"}' http://localhost:8080/ | ||
{"completed":false,"id":1,"order":0,"title":"This is my first todo item!","url":"https://localhost:8080/1"}% | ||
# get a list of todos with the one that was just created | ||
$ curl http://localhost:8080 | ||
[{"completed":false,"id":1,"order":0,"title":"This is my first todo item!","url":"https://localhost:8080/1"} | ||
---- | ||
|
||
== Run the Backend on OpenShift | ||
|
||
=== Prerequisites | ||
|
||
* You must be logged in OpenShift and have an `oc` client to connect to OpenShift | ||
* https://helm.sh[Helm] must be installed to deploy the backend on OpenShift. | ||
|
||
Once you have installed Helm, you need to add the repository that provides Helm Charts for {productName}: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ helm repo add wildfly https://docs.wildfly.org/wildfly-charts/ | ||
"wildfly" has been added to your repositories | ||
$ helm search repo wildfly | ||
NAME CHART VERSION APP VERSION DESCRIPTION | ||
wildfly/wildfly 1.1.0 22.0 Build and Deploy WildFly applications on OpenShift | ||
---- | ||
|
||
=== Deploy a PostgreSQL Database on OpenShift | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ oc new-app postgresql-ephemeral \ | ||
-p DATABASE_SERVICE_NAME=todos-db \ | ||
-p POSTGRESQL_DATABASE=todos | ||
---- | ||
|
||
This will create a PostgreSQL database named `todos` on OpenShift that can be accessed on the port `5432` on the service `todos-db`. | ||
We don't need to copy the credentials to connect to the database as we will retrieve them later using the `todos-db` secret that was created | ||
when the database is deployed. | ||
|
||
=== Build and Deploy the Backend on OpenShift | ||
|
||
The backend will be built and deployed on OpenShift with a Helm Chart for {productName}. | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ helm install todo-backend -f todo-backend.yaml wildfly/wildfly | ||
NAME: todo-backend | ||
... | ||
STATUS: deployed | ||
REVISION: 1 | ||
---- | ||
|
||
The Helm Chart for this quickstart contains all the information to build an image from the source code using Bootable Jar: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
build: | ||
uri: https://github.com/wildfly/quickstart.git | ||
mode: bootable-jar | ||
---- | ||
|
||
The Helm Chart also contains the environment variables required to connect to the PostgreSQL database. | ||
In local deployment the credentials were passed directly as the values of the environment variables. | ||
For OpenShift, we rely on secrets so that the credentials are never copied outside OpenShift: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
deploy: | ||
env: | ||
- name: POSTGRESQL_PASSWORD | ||
valueFrom: | ||
secretKeyRef: | ||
key: database-password | ||
name: todos-db | ||
---- | ||
|
||
When the application is deployed, the value for the `POSTGRESQL_PASSWORD` will be taken from the key `database-password` | ||
in the secrets `todos-db`. | ||
|
||
Let's wait for the application to be built and deployed: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ oc get dc/todo-backend -w | ||
NAME REVISION DESIRED CURRENT TRIGGERED BY | ||
todo-backend 0 3 0 config,image(todo-backend:latest) | ||
... | ||
todo-backend 1 3 3 config,image(todo-backend:latest) | ||
---- | ||
|
||
=== Use the todobackend Web application | ||
|
||
Once the backend is deployed on OpenShift, it can be accessed from the route `todo-backend`. | ||
Let's find the host that we can use to connect to this backend: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ oc get route todo-backend -o jsonpath="{.spec.host}" | ||
todo-backend-jmesnil1-dev.apps.sandbox.x8i5.p1.openshiftapps.com | ||
---- | ||
|
||
This value will be different for every installation of the backend. | ||
|
||
[WARNING] | ||
==== | ||
Make sure to prepend the host with `https://` to be able to connect to the backend from the ToDo Backend Specs or Client | ||
==== | ||
|
||
We can verify that this application is properly working as a ToDo Backend by running its https://todobackend.com/specs/index.html[specs] on it. | ||
|
||
|
||
Once all tests passed, we can use the https://todobackend.com/client/index.html[todobackend client] to have a Web application connected to the backend. | ||
|
||
=== Clean up | ||
|
||
==== Remove the Backend | ||
|
||
The backend can be deleted from OpenShift by running the command: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ helm delete todo-backend | ||
release "todo-backend" uninstalled | ||
---- | ||
|
||
==== Remove the Database | ||
|
||
The PostresSQL database can be deleted from OpenShift by running the commands: | ||
|
||
[source,options="nowrap"] | ||
---- | ||
$ oc delete all -l template=postgresql-ephemeral-template | ||
replicationcontroller "todos-db-1" deleted | ||
service "todos-db" deleted | ||
deploymentconfig.apps.openshift.io "todos-db" deleted | ||
$ oc delete secret todos-db | ||
secret "todos-db" deleted | ||
---- |
Oops, something went wrong.