Übung – Bereitstellen einer Jakarta EE-Anwendung für JBoss EAP auf Azure App Service
In dieser Einheit stellen Sie eine Jakarta EE-Anwendung auf dem Azure App Service auf Red Hat JBoss Enterprise Application Platform (JBoss EAP) bereit. Sie verwenden das Maven-Plug-In für Azure App Service, um das Projekt zu konfigurieren, die Anwendung zu kompilieren und bereitzustellen und eine Datenquelle zu konfigurieren.
Konfigurieren der App
Konfigurieren Sie die App mit dem Maven-Plug-In für Azure App Service mithilfe der folgenden Schritte:
Führen Sie das Konfigurationsziel des Azure-Plug-Ins interaktiv mit dem folgenden Befehl aus:
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:configVon Bedeutung
Wenn Sie die Region Ihres MySQL-Servers ändern, sollten Sie diese Region mit der Region Ihres Jakarta EE-Anwendungsservers abgleichen, um Latenzverzögerungen zu minimieren.
Verwenden Sie die Werte in der folgenden Tabelle, um die interaktiven Eingabeaufforderungen zu beantworten:
Eingabeelement Wert Create new run configuration (Y/N) [Y]:YDefine value for OS [Linux]:LinuxDefine value for javaVersion [Java 17]:1: Java 17Define value for runtimeStack:3: Jbosseap 7Define value for pricingTier [P1v3]:P1v3Confirm (Y/N) [Y]:YDas folgende Ergebnis ist typisch:
[INFO] Saving configuration to pom. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 03:00 min [INFO] Finished at: 2025-02-21T06:24:11+09:00 [INFO] ------------------------------------------------------------------------Nachdem Sie den Befehl Maven verwendet haben, ist das folgende Beispiel eine typische Ergänzung zu Ihrer Maven pom.xml Datei:
<build> <finalName>ROOT</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.4.0</version> </plugin> <plugin> <groupId>com.microsoft.azure</groupId> <artifactId>azure-webapp-maven-plugin</artifactId> <version>2.13.0</version> <configuration> <schemaVersion>v2</schemaVersion> <resourceGroup>jakartaee-app-on-jboss-rg</resourceGroup> <appName>jakartaee-app-on-jboss</appName> <pricingTier>P1v3</pricingTier> <region>centralus</region> <runtime> <os>Linux</os> <javaVersion>Java 17</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>Überprüfen Sie das
<region>Element in Ihrer pom.xml Datei. Wenn der Wert nicht mit dem Installationsspeicherort von MySQL übereinstimmt, ändern Sie ihn an denselben Speicherort.Verwenden Sie das folgende Beispiel, um den
webContainer-Wert in Ihrer pom.xml-Datei aufJbosseap 8zu ändern, für die JBoss EAP 8-Umgebung in Azure App Service.Tipp
Ab Februar 2025 ist die neueste verfügbare Version von JBoss EAP 8.0 Update 4.1.
<runtime> <os>Linux</os> <javaVersion>Java 17</javaVersion> <webContainer>Jbosseap 8</webContainer> <!-- Change this value --> </runtime>Fügen Sie dem Element Ihrer
<resources>den folgenden XML-Code hinzu. Diese Konfiguration wird verwendet, um die Startdatei bereitzustellen, die Sie später in dieser Einheit aktualisieren.<resource> <type>startup</type> <directory>${project.basedir}/src/main/webapp/WEB-INF/</directory> <includes> <include>createMySQLDataSource.sh</include> </includes> </resource>Der
<type>-Wertstartupder Ressource stellt das angegebene Skript als Datei startup.sh für Linux bzw. startup.cmd für Windows bereit. Der Bereitstellungsspeicherort ist /home/site/scripts/.Hinweis
Sie können die Bereitstellungsoption und den Bereitstellungsort auswählen, indem Sie eine der folgenden Möglichkeiten angeben
type:type=warstellt die WAR-Datei auf /home/site/wwwroot/app.war bereit, fallspathnicht angegeben.type=war&path=webapps/<appname>stellt die WAR-Datei auf /home/site/wwwroot/webapps/<appname> bereit.type=jarstellt die WAR-Datei auf /home/site/wwwroot/app.jar bereit. Der Parameterpathwird ignoriert.type=earstellt die WAR-Datei auf /home/site/wwwroot/app.ear bereit. Der Parameterpathwird ignoriert.type=libstellt den JAR auf /home/site/libs bereit. Sie müssen den Parameterpathangeben.type=staticstellt das Skript auf "/home/site/scripts" bereit. Sie müssen denpathParameter angeben.type=startupstellt das Skript als startup.sh unter Linux oder startup.cmd unter Windows bereit . Das Skript wird für /home/site/scripts/bereitgestellt. Der Parameterpathwird ignoriert.type=zipentpackt die .zip Datei auf /home/site/wwwroot. Der Parameterpathist optional.
Überprüfen Sie die Werte für die
resourceGroupundappNameElemente in Ihrer pom.xml Datei.Weisen Sie die Werte für
resourceGroupundappNameUmgebungsvariablen mithilfe der folgenden Befehle zu:export RESOURCE_GROUP_NAME=<resource-group> export WEB_APP_NAME=<app-name>
Kompilieren und Erstellen der Jakarta EE-App
Nachdem Sie die Azure App Service-Bereitstellungseinstellungen konfiguriert haben, kompilieren und verpacken Sie den Quellcode mithilfe des folgenden Befehls:
./mvnw clean package
Das folgende Ergebnis ist typisch:
[INFO] --- war:3.4.0:war (default-war) @ jakartaee-app-on-jboss ---
[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] Building war: /private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.881 s
[INFO] Finished at: 2025-02-21T06:32:30+09:00
[INFO] ------------------------------------------------------------------------
Bereitstellen der Jakarta EE-App für JBoss EAP im Azure App Service
Stellen Sie nach dem Kompilieren und Verpacken des Codes die Anwendung mithilfe des folgenden Befehls bereit:
./mvnw azure-webapp:deploy
Die Ausgabe sollte eine Erfolgsmeldung und die URL der bereitgestellten Anwendung enthalten. Achten Sie darauf, die URL für die spätere Verwendung zu speichern.
Konfigurieren einer Datenbankverbindung
Die Beispielanwendung stellt eine Verbindung mit Ihrer MySQL-Datenbank und zeigt Daten an. Die Maven-Projektkonfiguration in der Dateipom.xml gibt den MySQL-JDBC-Treiber an, wie im folgenden Beispiel veranschaulicht:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
Daher installiert JBoss EAP automatisch den JDBC-Treiber ROOT.war_com.mysql.cj.jdbc.Driver_9_2 zu Ihrem Bereitstellungspaket ROOT.war.
Erstellen des MySQL DataSource-Objekts in JBoss EAP
Um auf Azure Database for MySQL zuzugreifen, müssen Sie das DataSource Objekt in JBoss EAP konfigurieren und den Namen der Java Naming and Directory Interface (JNDI) in Ihrem Quellcode angeben. Zum Erstellen eines MySQL-Objekts DataSource in JBoss EAP verwenden Sie das Startshellskript "/WEB-INF/createMySQLDataSource.sh ". Das folgende Beispiel zeigt eine nicht konfigurierte Version des Skripts, die bereits in Azure App Service enthalten ist:
#!/bin/bash
# In order to use the variables in 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=${AZURE_MYSQL_CONNECTIONSTRING}&characterEncoding=utf8&sslMode=REQUIRED&serverTimezone=UTC&authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin \
--driver-name=ROOT.war_com.mysql.cj.jdbc.Driver_9_2 \
--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
Hinweis
Wenn Sie die Datenquelle erstellen, geben Sie kein Kennwort für die MySQL-Verbindung an. Die Umgebungsvariable AZURE_MYSQL_CONNECTIONSTRING wird im --connection-url Parameter angegeben. Diese Umgebungsvariable wird automatisch festgelegt, wenn die Dienstverbindung später erstellt wird.
Der Dienstverbindungswert ist auf jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp gesetzt, was den aad_jbossapp Benutzernamen ohne Kennwort verwendet.
Durch Anfügen &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin an diese URL ist die Microsoft Entra ID-Authentifizierung für den aad_jbossapp Benutzer aktiviert.
Konfigurieren Sie Ihre App Service-Instanz so, dass das Startskript mithilfe des folgenden Befehls aufgerufen wird:
az webapp config set \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${WEB_APP_NAME} \
--startup-file '/home/site/scripts/startup.sh'
Nachdem das Skript ausgeführt wurde, ruft der Anwendungsserver ihn jedes Mal auf, wenn der Anwendungsserver neu gestartet wird.
Hinweis
Wenn Ihr Bereitstellungsartefakt nicht ROOT.war ist, ändern Sie auch den --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2 Wert.
Konfigurieren der Dienstverbindung für den flexiblen MySQL-Server
Nachdem Sie das Startskript konfiguriert haben, konfigurieren Sie Den App-Dienst so, dass Service Connector für die flexible Serververbindung mySQL verwendet wird, indem Sie die folgenden Schritte ausführen:
Festlegen von Umgebungsvariablen mithilfe der folgenden Befehle:
export PASSWORDLESS_USER_NAME_SUFFIX=jbossapp export SOURCE_WEB_APP_ID=$(az webapp list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv) export MYSQL_ID=$(az mysql flexible-server list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv) export TARGET_MYSQL_ID=$MYSQL_ID/databases/world export MANAGED_ID=$(az identity list \ --resource-group $RESOURCE_GROUP_NAME \ --query "[0].id" \ --output tsv)Die Umgebungsvariablen werden für die folgenden Zwecke verwendet:
PASSWORDLESS_USER_NAME_SUFFIXist das Suffix für den Benutzernamen, der zum Herstellen einer Verbindung mit dem flexiblen MySQL-Server verwendet wird. Der erstellte Benutzername hat das Präfixaad_gefolgt vom angegebenen Suffix.SOURCE_WEB_APP_IDist die ID der Azure App Service-Instanz, die zum Herstellen einer Verbindung mit dem flexiblen MySQL-Server verwendet wird.MYSQL_IDist die ID des flexiblen MySQL-Servers.TARGET_MYSQL_IDgibt den Datenbanknamen$MYSQL_ID/databases/worldan, um eine Verbindung für einen Benutzer herzustellen, der berechtigt ist, auf dieworld-Datenbank zuzugreifen.MANAGED_IDist die verwaltete Identität, die zum Herstellen einer Verbindung mit dem flexiblen MySQL-Server verwendet wird.
Fügen Sie die Erweiterung
serviceconnector-passwordlesshinzu und erstellen Sie die Dienstverbindung mithilfe der folgenden Befehle:az extension add \ --name serviceconnector-passwordless \ --upgrade az webapp connection create mysql-flexible \ --resource-group ${RESOURCE_GROUP_NAME} \ --connection $PASSWORDLESS_USER_NAME_SUFFIX \ --source-id $SOURCE_WEB_APP_ID \ --target-id $TARGET_MYSQL_ID \ --client-type java \ --system-identity mysql-identity-id=$MANAGED_IDHinweis
Wenn Sie eine Fehlermeldung wie
Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present.erhalten, führen Sie den Befehl nach ein paar Sekunden erneut aus.Überprüfen Sie an der SQL-Eingabeaufforderung die Liste der benutzer, die in MySQL registriert sind, indem Sie die folgende Abfrage verwenden:
SELECT user, host, plugin FROM mysql.user;Das folgende Ergebnis ist typisch:
+----------------------------------+-----------+-----------------------+ | user | host | plugin | +----------------------------------+-----------+-----------------------+ | aad_jbossapp | % | aad_auth | | azureuser | % | mysql_native_password | | $CURRENT_AZ_LOGIN_USER_NAME#EXT#@| % | aad_auth | | azure_superuser | 127.0.0.1 | mysql_native_password | | azure_superuser | localhost | mysql_native_password | | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | +----------------------------------+-----------+-----------------------+ 8 rows in set (2.06 sec)Sie sollten einen
aad_jbossappBenutzer sehen, der dasaad_authPlug-In verwendet. Von JBoss EAP, das in Azure bereitgestellt wird, können Sie über denaad_jbossappBenutzernamen ohne Kennwort eine Verbindung mit dem flexiblen MySQL-Server herstellen.
Bestätigen des DataSource-Verweises im Code
Um von Ihrer Anwendung aus auf die MySQL-Datenbank zuzugreifen, müssen Sie den Datenquellenverweis in Ihrem Anwendungsprojekt konfigurieren.
Der Datenbankzugriffscode wird mithilfe der Java-Persistenz-API (JPA) implementiert. Die Konfiguration für den Verweis befindet sich in der DataSource JPA-Konfigurationsdatei persistence.xml.
Führen Sie die folgenden Schritte aus, um den DataSource Verweis zu bestätigen:
Öffnen Sie die Datei "src/main/resources/META-INF/persistence.xml ", und überprüfen Sie, ob der
DataSourceName dem in der Konfiguration verwendeten Namen entspricht. Das Startskript hat den JNDI-Namen bereits alsjava:jboss/datasources/JPAWorldDataSourceerstellt, wie im folgenden Beispiel gezeigt:<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>Greifen Sie auf die MySQL-Datenbank im
PersistenceContext-Einheitennamen zu, wie im folgenden Beispiel gezeigt:@Transactional(REQUIRED) @RequestScoped public class CityService { @PersistenceContext(unitName = "JPAWorldDatasourcePU") EntityManager em;
Zugreifen auf die Anwendung
Die Beispielanwendung implementiert drei REST-Endpunkte. Führen Sie die folgenden Schritte aus, um auf die Anwendung zuzugreifen und Daten abzurufen:
Verwenden Sie Ihren Browser, um zur Anwendungs-URL zu navigieren, die bei der Bereitstellung der Anwendung in der Ausgabe angezeigt wurde.
Um alle Kontinentinformationen im JSON-Format abzurufen, verwenden Sie die
GETMethode auf demareaEndpunkt.Um alle Länder und Regionen auf einem bestimmten Kontinent abzurufen, verwenden Sie die
GETMethode für denareaEndpunkt, und geben Sie einencontinentPfadparameter an.Um alle Städte zu erhalten, die eine Bevölkerung von mehr als einer Million innerhalb des angegebenen Landes oder der angegebenen Region haben, verwenden Sie die
GETMethode auf demcountriesEndpunkt, und geben Sie einencountrycodePfadparameter an.
Zusammenfassung der Übung
In dieser Einheit haben Sie die REST-Endpunkte der Anwendung überprüft und bestätigt, dass Ihre Anwendung Daten aus Ihrer MySQL-Datenbank abrufen kann. In der nächsten Einheit untersuchen Sie die Serverprotokolle.


