I. Préambule et Objectifs▲
Dans l'article précédent, j'avais expliqué comment développer une application web full stack à base d'Angular et Java/Spring Boot. Le code source des deux composants (Front et Back) constituant notre application est consultable sur GitLab :
- Front-end développé en Angular : https://gitlab.com/gkemayo/library-ui
- Back-end développé en Java/Spring Boot : https://gitlab.com/gkemayo/library
Dans ledit article, je montrais comment déployer ces deux composants sur un serveur Tomcat dans un environnement on-premise.
Notre objectif dans le présent article est de reprendre cette application, d'y apporter les modifications nécessaires afin de la déployer en mode Production dans le cloud, notamment dans un environnement d'essai (et donc gratuit) Cloud Foundry du provider SAP Cloud Platform.
L'architecture de l'application peut être caricaturée par le schéma suivant :
Mon choix de la plateforme SAP Cloud est simplement motivé par le fait que son environnement Cloud Foundry d'essai fournit assez d'espace mémoire et de stockage pour pouvoir déployer une application Java Spring Boot qui en demande pas mal. Cependant, il existe beaucoup d'autres providers Cloud Foundry qui offrent des environnements d'essai, mais avec un espace mémoire très petit, à l'instar de IBM Cloud. Enfin, je vous invite à consulter les limitations de la plateforme SAP Cloud Foundry si jamais vous étiez intéressé à y déployer vos applications.
Cependant, bien que la version payante de SAP propose plus de possibilités et d'actions, il convient de préciser que la version d'essai utilisée dans le cadre de cet article dispose aussi d'un certain nombre de limitations qu'il est bon de savoir. Notamment :
- l'impossibilité de créer vos propres nom de domaine pour vos applications (ce service est payant) ;
- la capacité (ou le quota) de stockage est limité pour vos applications : 1GB maximum de mémoire run et 4GB maximum de disque dur ;
- le support uniquement d'applications de type Java et html ;
- pas de service qui informe de la disponibilité ou non et de la santé des services de la marketplace SAP cloud plateform ;
- le compte d'essai n'est disponible que pour 30 jours renouvelables plusieurs fois dans la limite d'un an ;
- les services offerts dans la version d'essai ne sont pas très nombreux, contraitement à la version payante ;
- les applications déployées dans cette version d'essai sont automatiquement arrêtées par le système toutes les 24 heures. Il faut alors les relancer à la main dans votre espace ;
- etc.
L'architecture ci-dessus fait donc observer que nous provisionnerons :
- un sous-domaine, encore appelé une route, ou plus simplement un nom de domaine via lequel l'application Front sera rendue accessible : library-ui.cfapps.eu10.hana.ondemand.com ;
- un sous-domaine via lequel l'application Back sera rendue accessible : library.cfapps.eu10.hana.ondemand.com ;
- un service, consistant en une base de données relationnelle Postgresql à laquelle on l'attachera à l'application Back, pour la persistance des données.
L'application Front communique avec le Back par des appels de Web services REST au travers des services Angular en direction des controller Spring, cf. expression des besoins et architecture de l'application initiale.
Il faut noter que les deux sous-domaines ci-dessus (library-ui.cfapps.eu10.hana.ondemand.com et library.cfapps.eu10.hana.ondemand.com), s'appuient sur le domaine gratuit cfapps.eu10.hana.ondemand.com offert dans la version d'essai de la plateforme SAP Cloud Foundry. Comme je l'ai dit, vous ne pouvez malheureusement pas créer votre propre nom de domaine, mais plutôt créer une route (ou sous-domaine) à partir du domaine offert qui n'est pas très expressif.
Vous pouvez dès à présent et pour la suite, cloner le projet dédié à cet article ici :
Pour le reste, j'ai organisé l'article comme suit : dans les sections II et III, je présenterai et motiverai les modifications/ajouts que j'ai eus besoin d'effectuer sur les composants Front et Back de l'application initiale pour les rendre déployables en mode Production dans le cloud. Les sections IV, V et VI se concentreront sur les actions à effectuer pour atteindre les objectifs du cours, à savoir faire fonctionner l'application dans un environnement Cloud Foundry.
Il existe divers outils permettant d'automatiser l'intégration et le déploiement d'applications dans le cloud et donc dans Cloud Foundry. La plupart de ces outils sont même très souvent intégrés sur la plateforme cloud de leur fournisseur, mais cet article n'est pas tourné vers cela. J'opte pour une démarche manuelle qui nous permettra d'exposer les étapes et être moins abstrait.
II. Le Front-end▲
Pour rappel une fois de plus, le composant Front de notre application initiale est consultable sur ce lien : https://gitlab.com/gkemayo/library-ui.
J'avais présenté ici les étapes à suivre pour livrer ce Front sur un serveur Tomcat. J'étais allé au plus simple, car cette approche est assez limitée : elle considérait que le composant Back soit livré sur le même serveur Tomcat, le domaine d'accès du front étant localhost:8080 et celui du Back étant localhost:8082. Ce qui est trop simpliste et même peu réaliste pour une application qui doit tourner en mode Production.
Si on s'en réfère donc à l'architecture que nous nous sommes définie dans le schéma illustré à la section I, il en ressort que les deux composants (Front et Back) ne sont pas livrés sur le même serveur, et surtout que le Front accessible sur le nom de domaine library-ui.cfapps.eu10.hana.ondemand.com doit faire des appels de Web services REST vers le Back qui écoute lui sur le domaine library.cfapps.eu10.hana.ondemand.com
Pour rendre cela possible, j'ai modifié le code source du Front pour ajouter trois éléments :
- une variable apiBaseUrl dans les fichiers environnement.ts et environnement.prod.ts, dont la valeur vaut https:library.cfapps.eu10.hana.ondemand.com. À noter que SAP Cloud Platform fonctionne en mode HTTPS. Pour bien comprendre cette notion, consulter ce document.
- un service Angular dont le but est d'intercepter toutes les requêtes REST d'URI relatives pour leur adjoindre le préfixe https://library.cfapps.eu10.hana.ondemand.com afin de pouvoir obtenir un chemin absolu vers une ressource sur le Back. Je profite aussi pour ajouter l'entête Access-Control-Allow-Origin permettant de résoudre la restriction CORS (Cross Origin Resource Sharing) due aux échanges entre le Front et le Back situés sur deux domaines différents. La réciproque doit aussi être faite côté Back, nous le montrerons dans sa section.
Exemple : si le Front appel le service REST addBook avec l'URI relative /library/rest/book/api/addBook, alors cette requête sera interceptée et transformée en https://library.cfapps.eu10.hana.ondemand.com/library/rest/book/api/addBook
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
import {
HttpEvent,
HttpHandler,
HttpHeaders,
HttpInterceptor,
HttpRequest }
from '@angular/common/http'
;
import {
Injectable }
from '@angular/core'
;
import {
Observable }
from 'rxjs'
;
import {
environment }
from 'src/environments/environment'
;
@Injectable
({
providedIn
:
'root'
}
)
export class RequestInterceptorService implements HttpInterceptor {
constructor
(
) {
}
intercept
(
req
:
HttpRequest<
any>,
next
:
HttpHandler):
Observable<
HttpEvent<
any>>
{
let baseUrl =
environment.
apiBaseUrl;
if(
baseUrl &&
!(
req.
url.startsWith
(
'http'
) ||
req.
url.startsWith
(
'https'
))){
req =
req.clone
({
url
:
baseUrl +
req.
url}
);
req.
headers.append
(
'Access-Control-Allow-Origin'
,
baseUrl);
return next.handle
(
req);
}
}
}
- l'activation de cet intercepteur, par l'ajout de la ligne suivante dans l'app.module.ts :
{
provide
:
HTTP_INTERCEPTORS,
useClass
:
RequestInterceptorService,
multi
:
true}
III. Le Back-end▲
Le code source de l'application initiale (https://gitlab.com/gkemayo/library) ne change pas fondamentalement non plus, mais nous avons apporté quelques modifications dans le pom.xml, dans l'application.properties, la gestion du CORS et la gestion semi-manuelle du schéma de la base de données. Nous avons donc le résultat suivant :
- pom.xml
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns
=
"http://maven.apache.org/POM/4.0.0"
xmlns
:
xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi
:
schemaLocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0</modelVersion>
<parent>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-starter-parent</artifactId>
<version>
2.2.5.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<groupId>
com.gkemayo</groupId>
<artifactId>
library</artifactId>
<version>
0.0.1-SNAPSHOT</version>
<packaging>
jar</packaging>
<name>
library</name>
<description>
Project for managing books in a library</description>
<properties>
<java.version>
1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>
org.postgresql</groupId>
<artifactId>
postgresql</artifactId>
<version>
42.2.18</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-starter-test</artifactId>
<scope>
test</scope>
</dependency>
<dependency>
<groupId>
org.modelmapper</groupId>
<artifactId>
modelmapper</artifactId>
<version>
2.3.3</version>
</dependency>
<dependency>
<groupId>
io.springfox</groupId>
<artifactId>
springfox-swagger2</artifactId>
<version>
2.9.2</version>
</dependency>
<dependency>
<groupId>
io.springfox</groupId>
<artifactId>
springfox-swagger-ui</artifactId>
<version>
2.9.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>
org.springframework.boot</groupId>
<artifactId>
spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Dans ce pom, j'ai ajouté la dépendance qui injecte le connecteur jdbc postgresql qui permet l'accès à la base de données, et préféré un packaging en mode jar qui est le mode le plus recommandé lors des livraisons dans le cloud, quoique pas obligatoire.
- application.properties
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
server.servlet.context-path
=/library
############# DataSource Config #################
spring.datasource.name
=${vcap.services.postgreslibrary-db.credentials.dbname}
spring.datasource.username
=${vcap.services.postgreslibrary-db.credentials.username}
spring.datasource.password
=${vcap.services.postgreslibrary-db.credentials.password}
spring.datasource.url
=jdbc:postgresql://${vcap.services.postgreslibrary-db.credentials.hostname}
:${vcap.services.postgreslibrary-db.credentials.port}
/${vcap.services.postgreslibrary-db.credentials.dbname}
spring.datasource.driver-class-name
=org.postgresql.Driver
spring.datasource.sql-script-encoding
= UTF-8
spring.datasource.initialization-mode
=always
spring.datasource.schema
=classpath:data/librarydb-schema.sql
spring.datasource.data
=classpath:data/categories.sql
############# Hibernate properties #################
spring.jpa.show-sql
=true
spring.jpa.hibernate.ddl-auto
=create
spring.jpa.database-platform
=org.hibernate.dialect.PostgreSQLDialect
############# Email Config #################
spring.mail.default-encoding
=UTF-8
spring.mail.protocol
=smtp
spring.mail.host
=smtp.gmail.com
spring.mail.username
=noreply.library.test@gmail.com
spring.mail.password
=password1Test
spring.mail.port
= 587
spring.mail.properties.mail.smtp.auth
=true
spring.mail.properties.mail.smtp.starttls.enable
=true
spring.mail.test-connection
=false
#https://www.google.com/settings/security/lesssecureapps
Dans l'application.properties, je demande à Spring Boot de créer la datasource de l'application en s'appuyant sur les valeurs de la variables d'environnement VCAP_SERVICES de Cloud Foundry qui encapsule en runtime les données de connexion à la base de données Postgresql que nous allons provisionner dans le cloud. Nous donnerons le nom postgreslibrary-db à cette base de données. Nous le verrons un peu plus tard dans cet article.
Par ailleurs, j'ai configuré l'application.properties pour que Spring Boot soit capable de créer automatiquement le schéma de notre base de données au démarrage de l'application dans le cloud. Cela est fait aux travers des instructions spring.datasource.initialization-mode=always et spring.datasource.schema=classpath:data/librarydb-schema.sql dont le contenu du fichier librarydb-schema.sql est :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
CREATE
TABLE
IF
NOT
EXISTS
CATEGORY(
CODE
VARCHAR
(
255
)
NOT
NULL
,
LABEL VARCHAR
(
255
)
NOT
NULL
,
PRIMARY
KEY
(
CODE
)
)
;
CREATE
TABLE
IF
NOT
EXISTS
CUSTOMER(
CUSTOMER_ID INTEGER
NOT
NULL
,
ADDRESS VARCHAR
(
255
)
,
CREATION_DATE DATE
NOT
NULL
,
EMAIL VARCHAR
(
255
)
NOT
NULL
,
FIRST_NAME VARCHAR
(
255
)
NOT
NULL
,
JOB VARCHAR
(
255
)
,
LAST_NAME VARCHAR
(
255
)
NOT
NULL
,
PRIMARY
KEY
(
CUSTOMER_ID)
,
CONSTRAINT
UNIQUE_CONSTRAINT_EMAIL UNIQUE
(
EMAIL)
)
;
CREATE
TABLE
IF
NOT
EXISTS
BOOK(
BOOK_ID INTEGER
NOT
NULL
,
AUTHOR VARCHAR
(
255
)
,
ISBN VARCHAR
(
255
)
NOT
NULL
,
REGISTER_DATE DATE
NOT
NULL
,
RELEASE_DATE DATE
NOT
NULL
,
TITLE VARCHAR
(
255
)
NOT
NULL
,
TOTAL_EXAMPLARIES INTEGER
,
CAT_CODE VARCHAR
(
255
)
NOT
NULL
,
PRIMARY
KEY
(
BOOK_ID)
,
CONSTRAINT
UNIQUE_CONSTRAINT_ISBN UNIQUE
(
ISBN)
,
CONSTRAINT
FK_CONSTRAINT_CAT_CODE FOREIGN
KEY
(
CAT_CODE)
REFERENCES
CATEGORY(
CODE
)
)
;
CREATE
TABLE
IF
NOT
EXISTS
LOAN(
CREATION_DATE_TIME TIMESTAMP
NOT
NULL
,
BEGIN_DATE DATE
NOT
NULL
,
END_DATE DATE
NOT
NULL
,
STATUS
VARCHAR
(
255
)
,
CUSTOMER_ID INTEGER
NOT
NULL
,
BOOK_ID INTEGER
NOT
NULL
,
PRIMARY
KEY
(
BOOK_ID, CREATION_DATE_TIME, CUSTOMER_ID)
,
CONSTRAINT
FK_CONSTRAINT_BOOK_ID FOREIGN
KEY
(
BOOK_ID)
REFERENCES
BOOK(
BOOK_ID)
,
CONSTRAINT
FK_CONSTRAINT_CUSTOMER_ID FOREIGN
KEY
(
CUSTOMER_ID)
REFERENCES
CUSTOMER(
CUSTOMER_ID)
)
;
- Enfin, j'ai rajouté l'annotation suivante sur les quatre controllers REST (BookRestController, CustomerRestController, CategoryRestController et LoanRestController) de l'application Back :
@CrossOrigin
(
origins =
"https://library-ui.cfapps.eu10.hana.ondemand.com"
)
Exemple :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
@RestController
@RequestMapping
(
"/rest/book/api"
)
@CrossOrigin
(
origins =
"https://library-ui.cfapps.eu10.hana.ondemand.com"
)
@Api
(
value =
"Book Rest Controller: contains all operations for managing books"
)
public
class
BookRestController {
public
static
final
Logger LOGGER =
LoggerFactory.getLogger
(
BookRestController.class
);
@Autowired
private
BookServiceImpl bookService;
.
.
.
}
En ajoutant cette annotation sur les classes controllers Spring, on permet ainsi à l'application Front accessible sur le domaine https://library-ui.cfapps.eu10.hana.ondemand.com à être autorisée à appeler les Web services REST exposés dans chacune des classes sans être rejetée à cause de la restriction CORS (Cross Origin Resource Sharing).
Maintenant que je vous ai présenté les éléments de configuration fondamentale dans le code source des deux composants Front et Back de l'application, nous allons passer à l'étape suivante qui consiste à les déployer et les intégrer dans un environnement Cloud Foundry.
IV. Installation des outils d'accès à Cloud Foundry▲
Cloud Foundry est un modèle de cloud standard et open source de type PAAS (Platform As A Service) qui offre la possibilité d'y publier plusieurs types d'applications (Java, Go, Angular, Python, etc.), et prend en charge leur déploiement automatique pour les rendre immédiatement disponibles à l'utilisation sur Internet. Techniquement, c'est un concept qui définit des API de services que plusieurs fournisseurs (providers) peuvent adopter et implémenter afin de les rendre effectives sur leurs plateformes cloud. Dans la section I, je citais des exemples de fournisseurs tels que IBM Cloud, SUSE Cloud, Atos Cloud, ou encore PWS/PCF (en cessation de service au moment où nous écrivons cet article), etc., qui intègrent Cloud Foundry. J'utiliserai pour ce cours le fournisseur SAP Cloud Platform.
Comme on peut l'observer sur l'architecture simplifiée schématisée ci-dessous et prise dans la documentation officielle, Cloud Foundry est subdivisée en deux parties : une partie (le rectangle en pointillés de gauche) correspondant à l'environnement qui héberge effectivement les applications qui y sont déployées, et une partie (le rectangle en pointillés de droite) correspondant aux services et ressources mis à disposition par le provider de la plateforme cloud que l'on peut provisionner pour enrichir les besoins des applications :
La question est : comment fait-on depuis sa machine en local pour communiquer et transmettre des données et des instructions à la partie de gauche de cette architecture, pour que notre application puisse être déployée comme on le souhaite ?
Pour ce faire, Cloud Foundry fournit un client CLI (Command Line Interface) qui permet de répondre à cette question. Pour le télécharger, il faut aller sur le lien suivant.
Si vous êtes sur Windows par exemple, il suffit de télécharger le zip, puis le dézipper et double-cliquer sur l'un des fichiers au choix et selon la version que vous souhaiter installer : cf.exe ou cf7.exe. Il ne reste plus qu'à suivre le guide d'installation. Une fois installé, le client Cloud Foundry s'intègre directement dans votre Terminal de commandes Shell (cmd ou même Git Bash (si vous en avez installé un)). Vous êtes donc prêt à commencer à donner des instructions à la plateforme SAP Cloud Foundry. Mais avant d'y arriver, il faut déjà avoir un compte sur cette plateforme, ce qui constitue l'objet de la section suivante. En attendant, vérifiez si l'installation de votre client s'est bien passée en saisissant cette commande cf version dans votre Terminal :
|
V. Créer un compte SAP Cloud Platform▲
La création d'un compte d'essai chez SAP Cloud Platform est très simple. Je ne reviendrai pas dessus dans cet article, car les étapes 1 à 5 du tutoriel de la documentation SAP explique comment le faire de façon claire simple et précise.
Ce qu'il faut retenir c'est qu'une fois son compte d'essai créé, il faut se rendre à l'adresse suivante pour se connecter en saisissant son login et son mot de passe :
Une fois la connexion réussie, les étapes 6 à 8 du même tutoriel, montrent comment arriver sur son espace Cloud Foundry.
VI. Déployez l'application dans SAP Cloud Froundry▲
VI-A. Utilisation du CLI pour se connecter à son compte▲
Pour pouvoir envoyer des instructions depuis son poste local à son compte SAP Cloud Foundry, je l'ai dit, il faut utiliser le client CLI. Pour ce faire, il faut d'abord se connecter à ce compte pour qu'un canal de communication puisse s'établir.
SAP Cloud Foundry, comme tous les autres providers fournissent une url unique appelée API Endpoint à travers laquelle la CLI se connecte. Cet API Endpoint se trouve sur la page d'accueil de votre compte pour le cas de SAP :
Pour se connecter via la CLI, ouvrez votre terminal préféré et saisissez la commande suivante, qui vous demandera ensuite de saisir votre login/mot de passe :
cf login -a
https://
api.cf.eu10.hana.ondemand.com
Si la connexion est réussie on obtient un résultat comme ceci :
|
VI-B. Provisionner le service Postgresql ▲
Maintenant que notre CLI est connectée à la plateforme SAP Cloud Foundry, pour se provisionner le service Postgresql qui est en fait la base de données de l'application, nous avons deux possibilités.
- Réaliser toute la commande depuis la CLI :
pour ce faire, saisir la commande suivante pour voir les offres de services fournies pour notre type de compte :
cf marketplace
Nous pouvons aussi étendre cette commande pour ne filtrer que les lignes contenant le mot clé « postgresql » :
cf marketplace | grep postgresql
Le résultat obtenu nous donnera une ligne au format {SERVICE_NAME} {PLAN} {DESCRIPTION}, ce qui donne pour notre cas : postgresql-db trial PostgreSQL service on SAP Cloud Platform
L'application de la commande au format suivant, nous permettra finalement de créer notre base de données aussi simplement que ça :
cf create-
service <SERVICE_NAME>
<SERVICE_PLAN>
<SERVICE_INSTANCE_NAME>
Ce qui se traduit pour notre cas en :
cf create-
service postgresql-
db trial postgreslibrary-
db
postgreslibrary-db correspond au nom que nous donnons à notre base de données, lui-même ayant pour nom de service postgresql-db dans SAP Cloud Foundry. Le terme trial, correspond lui au plan de service que SAP fournit pour notre type de compte. En gros, il s'agit d'une version gratuite de postgresql offerte par SAP, car nous avons un compte d'essai.
- Réaliser toute la commande en utilisant l'interface graphique SAP :
pour ce faire, allez dans l'onglet Service marketplace de votre compte et recherchez le service par le terme postgresql :
En cliquant sur la zone rectangulaire PostgreSQL, hyperscaler option, vous arrivez sur une nouvelle fenêtre qui propose le bouton Create Instance qui vous guidera aisément dans la création de votre base de données postgresql :
VI-C. Définir le fichier manifest.yml▲
Pour transférer une application depuis son poste local vers une plateforme Cloud Foundry et en indiquant comment la déployer, nous avons le choix, soit de saisir successivement une série de commandes cf, soit de construire l'ensemble de ces commandes dans un fichier Yaml manifest.yml pour les jouer en une commande. En ouvrant un terminal à partir de l'emplacement où se trouve le fichier manifest.yml, on pourra l'exécuter. Dans mon cas, j'ai fait le choix du fichier manifest.yml et je l'ai placé à la racine du projet :
Le contenu de ce fichier est le suivant :
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
---
defaults
:
&defaults
disk_quota
:
1G
instances
:
1
applications
:
-
name
:
library-
ui
<<:
*defaults
memory
:
32M
buildpacks
:
-
https
:
//github.com/cloudfoundry/staticfile-
buildpack.git
path
:
./cloudfoundry-
library-
ui/dist
routes
:
-
route
:
library-
ui.cfapps.eu10.hana.ondemand.com
-
name
:
library
<<:
*defaults
memory
:
1G
buildpacks
:
-
https
:
//github.com/cloudfoundry/java-
buildpack.git
path
:
./cloudfoundry-
library/target/library-
0
.0
.1
-
SNAPSHOT.jar
routes
:
-
route
:
library.cfapps.eu10.hana.ondemand.com
services
:
-
postgreslibrary-
db
env
:
SPRING_PROFILES_ACTIVE
:
cloud
env
:
JBP_CONFIG_SPRING_AUTO_RECONFIGURATION
:
'{enabled: false}'
En résumé, ce manifest indique à Cloud Foundry qu'il doit déployer deux applications library-ui et library respectivement en les packageant à l'aide des buildpacks https://github.com/cloudfoundry/staticfile-buildpack.git et https://github.com/cloudfoundry/java-buildpack.git. Aussi, on indique à Cloud Foundry de provisionner un nom de domaine pour chacune de nos applications (library-ui.cfapps.eu10.hana.ondemand.com et library.cfapps.eu10.hana.ondemand.com) via lesquels elles seront rendues accessibles. Ensuite, en ce qui concerne l'application Back library, nous lui attachons (bind, en anglais) le service postgreslibrary-db que nous avons créé précédemment. Enfin, à travers la variable path, on indique le chemin où se trouve les artefacts des applications à livrer. Cela suppose au paravant que vous ayez buildé les différents projets. Pour rappel :
- pour le Front, il faut se placer à la racine du projet et builder avec la commande Angular/npm :
ng build --
prod --
base-
href /
library-
ui/
- pour le Back, il faut se placer à la racine du projet et builder avec la commande maven
mvn package
Pour approfondir votre compréhension de la configuration d'un fichier manifest.yml, vous pouvez consulter les documentations suivantes : 1 , 2.
VI-D. Publier l'application dans SAP Cloud Foundry▲
Une fois que le fichier manifest.yml est construit et qu'il n'y a pas d'erreur, pour publier l'application dans SAP Cloud Foundry afin de la déployer automatiquement, il suffit d'ouvrir votre Terminal à l'emplacement où se trouve ce fichier et saisir la commande suivante :
cf push
Ce qui donne un résultat comme celui-ci :
VI-E. Vérifier la bonne livraison▲
Lorsque la livraison des applications s'est bien passée suite à la commande cf push, vous pouvez à présent aller sur votre compte SAP Cloud Foundry dans le menu Overview :
Sur cet écran, j'ai encerclé la zone qui présente le nombre d'applications (library-ui et library) que nous venons de livrer et la zone qui présente le nombre de services (postgresql) que nous avons provisionnés. Un clic sur chacun des petits liens 2 et 1 dans ces zones nous amène respectivement vers les écrans suivants où l'on peut observer que tout est fonctionnel et que les applications sont déployées et démarrées.
VI-F. Démo de l'application▲
Compte tenu des configurations faites dans le développement et le packaging de l'application, le composant Front, le Back et le Swagger du Back répondent sur les URLs suivantes :
- https://library-ui.cfapps.eu10.hana.ondemand.com/library-ui/#/
- https://library.cfapps.eu10.hana.ondemand.com/library/
- https://library.cfapps.eu10.hana.ondemand.com/library/swagger-ui.html#/
Et ci-dessous une démo :
VII. Annexe▲
Il existe pas mal de commandes CLI que vous pouvez exécuter pour assurer la construction, la configuration, le suivi et même le provisionnement de services pour vos applications que vous voulez déployer dans Cloud Foundry. Je vous liste ici quelques commandes utiles qui au préalable nécessitent que vous soyez déjà connecté à votre compte au travers de la commande cf login -a {API_ENDPOINT} :
- cf domains : liste les noms de domaine liés à un compte Cloud Foundry. C'est d'ailleurs cette commande qui nous a permis de récupérer le nom de domaine cfapps.eu10.hana.ondemand.com qui nous a permis de créer les sous-domaines library-ui.cfapps.eu10.hana.ondemand.com et library.cfapps.eu10.hana.ondemand.com ;
- cf create-domain {NOM_DOMAINE} : si votre type de compte SAP Cloud Foundry vous le permet (en général les comptes payants), cette commande permet de créer votre propre nom de domaine ;
- cf create-route {NOM_SOUS_DOMAINE} : permet de créer un sous-domaine à partir d'un nom de domaine existant ;
- cf cups {SERVICE_INSTANCE_NAME} -p "host,port,username,password,database" : permet d'associer à un service que vous avez provisionné (ex. : une base de données), la valeur des paramètres listés entre quotes ;
- cf bind-service {APP_NAME} {SERVICE_INSTANCE} : permet d'attacher un service provisionné sur SAP Cloud Foundry à une application qui y est déployée. Exemple, on aurait pu au lieu d'utiliser le fichier manifest.yml, exécuter la commande cf bind-service library postgreslibrary-db pour attacher la base de données Postgresql à l'application Back library ;
- cf services : liste tous les services que vous avez provisionnés dans votre compte SAP Cloud Foundry ;
- cf env {APP_NAME} : retourne toutes les variables d'environnement liées à l'application {APP_NAME}. Cf, la variable VCAP_SERVICES ;
- cf logs {APP_NAME} --recent : permet d'afficher les logs récents d'une application {APP_NAME} déployée dans votre compte SAP Cloud Foundry ;
- cf buildpacks : liste tous les buildpacks existants utilisables pour construire chaque application en fonction de son langage de programmation.
VIII. Conclusion▲
Nous venons de voir dans cet article comment développer une application web Full Stack agrégeant les technologies Angular et Java/Spring Boot, c'est-à-dire disposant d'une partie Front et une partie Back, en y intégrant les éléments lui permettant d'être livrée en environnement de Production et sur des domaines différents. J'ai fait le choix d'illustrer ici comment déployer ce type d'application dans le cloud et plus particulièrement sur l'environnement Cloud Foundry du provider SAP Cloud Plateform. Cela nous a permis non seulement de voir comment on crée un compte chez ce fournisseur, mais aussi à quoi ressemble son interface graphique et comment on peut y provisionner des services. J'ai par ailleurs insisté sur le client CLI de Cloud Foundry et comment user de cela pour transmettre des instructions de déploiement dans le cloud. Enfin, j'ai opté pour l'approche basée sur le fichier de configuration manifest.yml afin de rendre le processus plus simple et réutilisable.
IX. Remerciements▲
Je voudrais dire un merci infini aux messieurs suivants qui ont contribué au perfectionnement de cet article :
- Mickael Baron pour sa relecture technique et pour ses remarques ;
- Claude Leloup pour la relecture orthographique