Exercice – Déployer une application Java EE (Jakarta EE) dans JBoss EAP sur Azure App Service
Dans cet exercice, vous allez déployer une application Java EE (Jakarta EE) dans JBoss EAP sur Azure App Service. Vous utilisez le plug-in Maven pour configurer le projet, compiler et déployer l’application, et configurer une source de données.
Configurer l’application avec le plug-in Maven pour Azure App Service
Configurons l’application en exécutant l’objectif de configuration dans le plug-in Maven pour Azure App Service.
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
Important
Si vous changez la région de votre serveur MySQL, vous devez passer à cette même région pour votre serveur d’applications Java EE, afin de réduire au maximum les délais de latence.
Dans la commande, sélectionnez Java 11 comme version de Java et JBoss EAP 7 comme pile d’exécution.
Élément d’entrée | Valeur |
---|---|
Available subscriptions: |
Your appropriate subsctioption |
Choose a Web Container Web App [\<create\>]: |
1: <create> |
Define value for OS [Linux]: |
Linux |
Define value for javaVersion [Java 17]: |
2: Java 11 |
Define value for runtimeStack: |
1: Jbosseap 7 |
Define value for pricingTier [P1v3]: |
P1v3 |
Confirm (Y/N) [Y]: |
Y |
Après l’exécution de la commande, vous allez recevoir les messages suivants dans le terminal :
$ ./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
[INFO] Scanning for projects...
[INFO]
[INFO] ---------< com.microsoft.azure.samples:jakartaee-app-on-jboss >---------
[INFO] Building jakartaee-app-on-jboss 1.0-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- azure-webapp-maven-plugin:2.5.0:config (default-cli) @ jakartaee-app-on-jboss ---
[WARNING] The POM for com.microsoft.azure.applicationinsights.v2015_05_01:azure-mgmt-insights:jar:1.0.0-beta is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] Auth type: OAUTH2
Username: YOUR_EMAIL_ADDRESS@microsoft.com
Available subscriptions:
[INFO] Subscription: YOUR_SUBSCRIPTION(********-****-****-****-************)
[INFO] It may take a few minutes to load all Java Web Apps, please be patient.
Web Container Web Apps in subscription Microsoft Azure Internal Billing-CDA:
* 1: <create>
2: jakartaee-app-on-jboss-yoshio (linux, jbosseap 7.2-java8)
Please choose a Web Container Web App [<create>]:
Define value for OS [Linux]:
* 1: Linux
2: Windows
3: Docker
Enter your choice:
Define value for javaVersion [Java 8]:
* 1: Java 8
2: Java 11
Enter your choice:
Define value for runtimeStack:
1: Jbosseap 7.2
2: Jbosseap 7
* 3: Tomcat 8.5
4: Tomcat 9.0
Enter your choice: 1
Define value for pricingTier [P1v3]:
1: P3v3
2: P2v3
* 3: P1v3
Enter your choice:
Please confirm webapp properties
Subscription Id : ********-****-****-****-************
AppName : jakartaee-app-on-jboss-1625038814881
ResourceGroup : jakartaee-app-on-jboss-1625038814881-rg
Region : westeurope
PricingTier : P1v3
OS : Linux
Java : Java 8
Web server stack: Jbosseap 7.2
Deploy to slot : false
Confirm (Y/N) [Y]:
[INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:43 min
[INFO] Finished at: 2021-06-30T16:40:47+09:00
[INFO] ------------------------------------------------------------------------
$
Une fois l’exécution de la commande terminée, vous voyez que l’entrée suivante est ajoutée dans votre fichier Maven pom.xml
.
<build>
<finalName>ROOT</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.9.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
<pricingTier>P1v3</pricingTier>
<region>centralus</region>
<runtime>
<os>Linux</os>
<javaVersion>Java 11</javaVersion>
<webContainer>Jbosseap 7</webContainer>
</runtime>
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.war</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
</plugins>
</build>
Important
Vérifiez l’élément <region>
. S’il ne s’agit pas du même emplacement d’installation que MySQL, remplacez-le par le même emplacement.
Après avoir ajouté la configuration ci-dessus pour le déploiement sur Azure, ajoutez les entrées XML suivantes pour déployer le fichier de démarrage. La ressource <type>startup</type>
déploie le script spécifié sous startup.sh
(Linux) ou startup.cmd
(Windows) sur /home/site/scripts/
. Nous configurons le script de démarrage à l’étape suivante.
<!-- Please add following lines -->
<resource>
<type>startup</type>
<directory>${project.basedir}/src/main/webapp/WEB-INF/</directory>
<includes>
<include>createMySQLDataSource.sh</include>
</includes>
</resource>
<!-- Please add following lines -->
Notes
Vous pouvez spécifier la ressource suivante à déployer dans le fichier XML :
type=<war|jar|ear|lib|startup|static|zip>
type=war
déploie le fichier War sur/home/site/wwwroot/app.war
sipath
n’est pas spécifiétype=war&path=webapps/<appname>\
se comporte exactement comme warDeploy en décompressant l’application vers /home/site/wwwroot/webapps/<appname>type=jar
déploie le fichier War sur/home/site/wwwroot/app.jar
. Le paramètrepath
sera ignorétype=ear
déploie le fichier War sur/home/site/wwwroot/app.ear
. Le paramètrepath
sera ignorétype=lib
déploie le fichier Jar sur /home/site/libs. Le paramètrepath
doit être spécifiétype=static
déploie le script dans/home/site/scripts
. Le paramètrepath
doit être spécifiétype=startup
déploie le script en tant questartup.sh
(Linux) oustartup.cmd
(Windows) sur/home/site/scripts/
. Le paramètrepath
sera ignorétype=zip
décompresse le fichier zip dans/home/site/wwwroot
. Le paramètrepath
est facultatif.
À présent, vérifiez les valeurs du nom du groupe de ressources et celui de l’application dans le fichier XML ci-dessus. Notez ces noms, ou mieux, attribuez-les à des variables d’environnement.
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
Si vous utilisez Bash, configurez les variables d’environnement avec la commande suivante. Vous allez utiliser ces valeurs plus tard.
export RESOURCEGROUP_NAME=jakartaee-app-on-jboss-1625038814881-rg
export WEBAPP_NAME=jakartaee-app-on-jboss-1625038814881
Compiler et générer l’application Java EE
Après avoir configuré les paramètres de déploiement d’Azure App Service, compilez et empaquetez le code source.
./mvnw clean package
La sortie suivante s’affiche dans le terminal :
[INFO] Packaging webapp
[INFO] Assembling webapp [jakartaee-app-on-jboss] in [/private/tmp/mslearn-jakarta-ee-azure/target/ROOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/private/tmp/mslearn-jakarta-ee-azure/src/main/webapp]
[INFO] Webapp assembled in [369 msecs]
[INFO] Building war: /private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.656 s
[INFO] Finished at: 2023-03-04T12:35:43-05:00
[INFO] ------------------------------------------------------------------------
Déployer l’application Java EE dans JBoss EAP sur Azure App Service
Après avoir compilé et empaqueté le code, déployez l’application :
./mvnw azure-webapp:deploy
Le message suivant s’affiche dans le terminal :
[INFO] Creating resource group jakartaee-app-on-jboss-1625038814881-rg in region westeurope...
[INFO] Successfully created resource group jakartaee-app-on-jboss-1625038814881-rg.
[INFO] Creating app service plan...
[INFO] Successfully created app service plan asp-jakartaee-app-on-jboss-1625038814881.
[INFO] Creating web app jakartaee-app-on-jboss-1625038814881...
[INFO] Successfully created Web App jakartaee-app-on-jboss-1625038814881.
[INFO] Trying to deploy artifact to jakartaee-app-on-jboss-1625038814881...
[INFO] Deploying (/private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war)[war] ...
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:11 min
[INFO] Finished at: 2023-03-04T12:38:39-05:00
[INFO] ------------------------------------------------------------------------
Notez l’URL de l’application déployée, en particulier la ligne suivante dans la sortie Maven :
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
Configurer une connexion de base de données
L’exemple d’application se connecte à votre base de données MySQL et affiche les données.
Dans la configuration de projet Maven, dans pom.xml
, nous avons spécifié le pilote JDBC MySQL de la façon suivante :
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
Par conséquent, JBoss EAP installe automatiquement le pilote JDBC dans votre package de déploiement ROOT.war
. Vous pouvez référencer le nom du pilote JDBC MySQL de la façon suivante :
ROOT.war_com.mysql.cj.jdbc.Driver_8_0
Créer l’objet de source de données MySQL dans JBoss EAP
Pour accéder à Azure DB pour MySQL, vous devez configurer l’objet DataSource
dans JBoss EAP, et spécifier le nom JNDI dans votre code source.
Pour créer un objet MySQL DataSource
dans JBoss EAP, nous avons créé le script d’interpréteur de commandes de démarrage qui suit. Il s’agit du fichier de script createMySQLDataSource.sh
, situé dans le répertoire /WEB-INF
.
Notes
Dans le script, nous allons lier la source de données MySQL à l’aide d’une commande de l’interface CLI JBoss. La chaîne de connexion, le nom d’utilisateur et le mot de passe utilisent les variables d’environnement MYSQL_CONNECTION_URL
, MYSQL_USER
et MYSQL_PASSWORD
.
La source du fichier de script est indiquée ci-dessous. Ce fichier de script a déjà été chargé dans App Service, mais il n’a pas encore été configuré pour être appelé.
#!/usr/bin/bash
# In order to use the variables in JBoss CLI scripts
# https://access.redhat.com/solutions/321513
#
sed -i -e "s|.*<resolve-parameter-values.*|<resolve-parameter-values>true</resolve-parameter-values>|g" /opt/eap/bin/jboss-cli.xml
/opt/eap/bin/jboss-cli.sh --connect <<EOF
data-source add --name=JPAWorldDataSourceDS \
--jndi-name=java:jboss/datasources/JPAWorldDataSource \
--connection-url=${MYSQL_CONNECTION_URL} \
--driver-name=ROOT.war_com.mysql.cj.jdbc.Driver_8_0 \
--user-name=${MYSQL_USER} \
--password=${MYSQL_PASSWORD} \
--min-pool-size=5 \
--max-pool-size=20 \
--blocking-timeout-wait-millis=5000 \
--enabled=true \
--driver-class=com.mysql.cj.jdbc.Driver \
--jta=true \
--use-java-context=true \
--valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker \
--exception-sorter-class-name=com.mysql.cj.jdbc.integration.jboss.ExtendedMysqlExceptionSorter
exit
EOF
À présent, configurez l’instance App Service pour appeler le script de démarrage :
az webapp config set --startup-file '/home/site/scripts/startup.sh' \
-n ${WEBAPP_NAME} \
-g ${RESOURCEGROUP_NAME}
Après l’exécution du script, celui-ci sera appelé chaque fois que le serveur d’applications est redémarré.
Notes
Si votre artefact de déploiement n’est pas ROOT.war
, vous devez également modifier la valeur --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_8_0
.
Configurer les variables d’environnement pour la connexion à MySQL
Après avoir configuré le script de démarrage, configurez App Service afin qu’il utilise certaines variables d’environnement :
az webapp config appsettings set \
--resource-group ${RESOURCEGROUP_NAME} --name ${WEBAPP_NAME} \
--settings \
MYSQL_CONNECTION_URL='jdbc:mysql://mysqlserver-**********.mysql.database.azure.com:3306/world?useSSL=true&requireSSL=false' \
MYSQL_PASSWORD='************' \
MYSQL_USER=azureuser
Conseil
Les valeurs de MYSQL_CONNECTION_URL
, MYSQL_USER
et MYSQL_PASSWORD
ont été définies à partir de l’unité précédente.
Confirmer la référence DataSource dans le code
Pour accéder à la base de données MySQL à partir de votre application, vous devez configurer la référence de source de données dans votre projet d’application. Nous avons implémenté le code d’accès à la base de données à l’aide de l’API Java Persistence (JPA).
La configuration pour la référence de l’objet DataSource
a été ajoutée dans persistence.xml
, qui est le fichier de configuration de l’API JPA.
Accédez au fichier suivant :
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ └── persistence.xml
Vérifiez que le nom de DataSource
correspond bien au nom utilisé dans la configuration. Le code a déjà créé le nom JNDI en tant que java:jboss/datasources/JPAWorldDataSource
:
<persistence-unit name="JPAWorldDatasourcePU" transaction-type="JTA">
<jta-data-source>java:jboss/datasources/JPAWorldDataSource</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="hibernate.generate_statistics" value="true" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
Ensuite, vous pouvez accéder à la base de données MySQL référencée dans le nom d’unité PersistenceContext
comme suit :
@Transactional(REQUIRED)
@RequestScoped
public class CityService {
@PersistenceContext(unitName = "JPAWorldDatasourcePU")
EntityManager em;
Accéder à l’application
Dans l’exemple d’application, nous avons implémenté trois points de terminaison REST. Vous pouvez accéder à l’application et valider ces points de terminaison à l’aide d’un navigateur web ou d’une commande curl
.
Pour accéder à l’application, vous devez référencer l’URL de l’application, que vous avez obtenue dans une section précédente :
[INFO] Successfully deployed the artifact to
https://jakartaee-app-on-jboss-1606464084546.azurewebsites.net
Exécutez la commande suivante pour obtenir toutes les informations relatives aux continents au format JSON.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area
["North America","Asia","Africa","Europe","South America","Oceania","Antarctica"]$
Si vous spécifiez le continent dans l’URL, vous pouvez obtenir tous les pays/régions du continent spécifié.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area/Asia | jq '.[] | { name: .name, code: .code }'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 16189 100 16189 0 0 65278 0 --:--:-- --:--:-- --:--:-- 65542
{
"name": "Afghanistan",
"code": "AFG"
}
{
"name": "United Arab Emirates",
"code": "ARE"
}
{
"name": "Armenia",
"code": "ARM"
}
{
"name": "Azerbaijan",
"code": "AZE"
}
{
"name": "Bangladesh",
"code": "BGD"
}
....
Enfin, si vous spécifiez un code pays/région après /countries
, vous pouvez obtenir toutes les villes du pays/de la région en question dont la population dépasse 1 million d’habitants.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/countries/JPN | jq '.[].name'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 788 100 788 0 0 2671 0 --:--:-- --:--:-- --:--:-- 2662
"Tokyo"
"Jokohama [Yokohama]"
"Osaka"
"Nagoya"
"Sapporo"
"Kioto"
"Kobe"
"Fukuoka"
"Kawasaki"
"Hiroshima"
"Kitakyushu"
Résumé de l’exercice
Vous venez de valider les points de terminaison REST de l’application et de tester que votre application peut récupérer les données de votre base de données MySQL.
Dans l’unité suivante, vous allez examiner les journaux du serveur.