Ćwiczenie — wdrażanie aplikacji Jakarta EE w aplikacji JBoss EAP w usłudze Azure App Service

Ukończone

W tej lekcji wdrożysz aplikację Jakarta EE w rozwiązaniu Red Hat JBoss Enterprise Application Platform (JBoss EAP) w usłudze Azure App Service. Wtyczka Maven dla usługi Azure App Service służy do konfigurowania projektu, kompilowania i wdrażania aplikacji oraz konfigurowania źródła danych.

Konfigurowanie aplikacji

Skonfiguruj aplikację za pomocą wtyczki Maven dla usługi Azure App Service, wykonując następujące kroki:

  1. Uruchom cel konfiguracyjny wtyczki Azure interaktywnie, używając następującego polecenia:

    ./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
    

    Ważny

    Jeśli zmienisz region serwera MySQL, należy dopasować ten region do regionu serwera aplikacji Jakarta EE, aby zminimalizować opóźnienia.

  2. Użyj wartości z poniższej tabeli, aby odpowiedzieć na interaktywne zapytania.

    Element wejściowy Wartość
    Create new run configuration (Y/N) [Y]: Y
    Define value for OS [Linux]: Linux
    Define value for javaVersion [Java 17]: 1: Java 17
    Define value for runtimeStack: 3: Jbosseap 7
    Define value for pricingTier [P1v3]: P1v3
    Confirm (Y/N) [Y]: Y

    Następujące dane wyjściowe są typowe:

    [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] ------------------------------------------------------------------------
    

    Po użyciu polecenia Maven poniższy przykład jest typowym dodatkiem do pliku pom.xml Maven:

    <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>
    
  3. Sprawdź element <region> w swoim pliku pom.xml. Jeśli jego wartość nie jest zgodna z lokalizacją instalacji programu MySQL, zmień ją na tę samą lokalizację.

  4. Aby zmodyfikować wartość webContainer w pliku pom.xml na Jbosseap 8 w środowisku JBoss EAP 8 w usłudze Azure App Service, użyj poniższego przykładu:

    Napiwek

    Od lutego 2025 r. najnowsza dostępna wersja aplikacji JBoss EAP to 8.0 Update 4.1.

    <runtime>
        <os>Linux</os>
        <javaVersion>Java 17</javaVersion>
        <webContainer>Jbosseap 8</webContainer> <!-- Change this value -->
    </runtime>
    
  5. Dodaj następujący kod XML do <resources> elementu pliku pom.xml . Ta konfiguracja służy do wdrażania pliku uruchamiania, który zostanie zaktualizowany w dalszej części tej lekcji.

    <resource>
      <type>startup</type>
      <directory>${project.basedir}/src/main/webapp/WEB-INF/</directory>
      <includes>
        <include>createMySQLDataSource.sh</include>
      </includes>
    </resource>
    

    Wartość <type> zasobu startup wdraża określony skrypt jako plik startup.sh dla systemu Linux lub startup.cmd dla systemu Windows. Lokalizacja wdrożenia to /home/site/scripts/.

    Notatka

    Możesz wybrać opcję wdrożenia i lokalizację wdrożenia, określając type jedną z następujących metod:

    • type=war wdraża plik WAR w lokalizacji /home/site/wwwroot/app.war , jeśli path nie zostanie określony.
    • type=war&path=webapps/<appname> wdraża plik WAR w folderze /home/site/wwwroot/webapps/<appname>.
    • type=jar wdraża plik WAR w katalogu /home/site/wwwroot/app.jar. Parametr path jest ignorowany.
    • type=ear wdraża plik WAR w folderze /home/site/wwwroot/app.ear. Parametr path jest ignorowany.
    • type=lib wdraża plik JAR w katalogu /home/site/libs. Należy określić path parametr.
    • type=static wdraża skrypt w folderze /home/site/scripts. Należy określić path parametr .
    • type=startup wdraża skrypt jako startup.sh w systemie Linux lub startup.cmd w systemie Windows. Skrypt jest wdrażany w folderze /home/site/scripts/. Parametr path jest ignorowany.
    • type=zip Rozpakowuje plik .zip do folderu /home/site/wwwroot. Parametr path jest opcjonalny.
  6. Sprawdź wartości elementów resourceGroup i appName w pliku pom.xml .

  7. Ustaw wartości resourceGroup i appName jako zmienne środowiskowe, używając następujących poleceń:

    export RESOURCE_GROUP_NAME=<resource-group>
    export WEB_APP_NAME=<app-name>
    

Kompilowanie i budowanie aplikacji Jakarta EE

Po skonfigurowaniu ustawień wdrażania usługi Azure App Service skompiluj i spakuj kod źródłowy przy użyciu następującego polecenia:

./mvnw clean package

Następujące dane wyjściowe są typowe:

[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] ------------------------------------------------------------------------

Wdrażanie aplikacji Jakarta EE w aplikacji JBoss EAP w usłudze Azure App Service

Po skompilowaniu i spakowaniu kodu wdróż aplikację przy użyciu następującego polecenia:

./mvnw azure-webapp:deploy

Powinny zostać wyświetlone dane wyjściowe zawierające komunikat o powodzeniu i adres URL wdrożonej aplikacji. Pamiętaj, aby zapisać adres URL do późniejszego użycia.

Konfigurowanie połączenia z bazą danych

Przykładowa aplikacja łączy się z bazą danych MySQL i wyświetla dane. Konfiguracja projektu Maven w pliku pom.xml określa sterownik JDBC MySQL, jak pokazano w poniższym przykładzie:

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>${mysql-jdbc-driver}</version>
</dependency>

W rezultacie narzędzie JBoss EAP automatycznie instaluje sterownik ROOT.war_com.mysql.cj.jdbc.Driver_9_2 JDBC do pakietu wdrożeniowego ROOT.war.

Tworzenie obiektu MySQL DataSource w aplikacji JBoss EAP

Aby uzyskać dostęp do usługi Azure Database for MySQL, należy skonfigurować DataSource obiekt w aplikacji JBoss EAP i określić nazwę Java Naming and Directory Interface (JNDI) w kodzie źródłowym. Aby utworzyć obiekt MySQL DataSource w aplikacji JBoss EAP, należy użyć skryptu powłoki startowej /WEB-INF/createMySQLDataSource.sh. W poniższym przykładzie pokazano nieskonfigurowaną wersję skryptu już w usłudze Azure App Service:

#!/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

Notatka

Podczas tworzenia źródła danych nie określasz hasła dla połączenia MySQL. Zmienna środowiskowa AZURE_MYSQL_CONNECTIONSTRING jest określona w parametrze --connection-url . Ta zmienna środowiskowa jest ustawiana automatycznie po utworzeniu połączenia z usługą później.

Wartość połączenia z usługą jest ustawiona na jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp, która używa aad_jbossapp nazwy użytkownika bez hasła. Dołączając &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin do tego adresu URL, uwierzytelnianie Microsoft Entra ID jest włączone dla użytkownika aad_jbossapp.

Skonfiguruj wystąpienie usługi App Service w celu wywołania skryptu uruchamiania przy użyciu następującego polecenia:

az webapp config set \
    --resource-group ${RESOURCE_GROUP_NAME} \
    --name ${WEB_APP_NAME} \
    --startup-file '/home/site/scripts/startup.sh'

Po uruchomieniu skryptu serwer aplikacji wywołuje go za każdym razem, gdy serwer aplikacji zostanie ponownie uruchomiony.

Notatka

Jeśli artefakt wdrożenia nie jest ROOT.war, zmień wartość --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2 też.

Konfigurowanie połączenia usługi dla serwera elastycznego MySQL

Po skonfigurowaniu skryptu uruchamiania skonfiguruj usługę App Service tak, aby korzystała z łącznika usługi dla elastycznego połączenia serwera MySQL, wykonując następujące kroki:

  1. Ustaw zmienne środowiskowe przy użyciu następujących poleceń:

    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)
    

    Zmienne środowiskowe są używane w następujących celach:

    • PASSWORDLESS_USER_NAME_SUFFIX jest sufiksem nazwy użytkownika używanej do nawiązywania połączenia z serwerem elastycznym MySQL. Utworzona nazwa użytkownika ma prefiks aad_ , po którym następuje określony sufiks.
    • SOURCE_WEB_APP_ID to identyfikator instancji usługi Azure App Service używanej do połączenia z elastycznym serwerem MySQL.
    • MYSQL_ID to identyfikator serwera elastycznego MySQL.
    • TARGET_MYSQL_ID określa nazwę $MYSQL_ID/databases/world bazy danych w celu nawiązania połączenia z użytkownikiem, który ma uprawnienia dostępu world do bazy danych.
    • MANAGED_ID to tożsamość zarządzana używana do nawiązywania połączenia z serwerem elastycznym MySQL.
  2. Dodaj rozszerzenie dla serviceconnector-passwordless i utwórz połączenie z usługą, używając następujących poleceń:

    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_ID
    

    Notatka

    Jeśli zostanie wyświetlony komunikat o błędzie, taki jak Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present., uruchom ponownie polecenie po kilku sekundach.

  3. W wierszu polecenia SQL sprawdź listę użytkowników zarejestrowanych w programie MySQL przy użyciu następującego zapytania:

    SELECT user, host, plugin FROM mysql.user;
    

    Następujące dane wyjściowe są typowe:

    +----------------------------------+-----------+-----------------------+
    | 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)
    

    Powinien zostać wyświetlony aad_jbossapp użytkownik korzystający z wtyczki aad_auth . Z aplikacji JBoss EAP wdrożonej na platformie Azure możesz nawiązać połączenie z serwerem elastycznym MySQL przy użyciu aad_jbossapp nazwy użytkownika bez hasła.

Potwierdzanie odwołania do źródła danych w kodzie

Aby uzyskać dostęp do bazy danych MySQL z poziomu aplikacji, należy skonfigurować odwołanie do źródła danych w projekcie aplikacji.

Kod dostępu do bazy danych jest implementowany przy użyciu interfejsu API trwałości języka Java (JPA). Konfiguracja odwołania DataSource znajduje się w pliku konfiguracji JPA persistence.xml.

Aby potwierdzić DataSource odwołanie, wykonaj następujące czynności:

  1. Otwórz plik src/main/resources/META-INF/persistence.xml i sprawdź, czy DataSource nazwa jest zgodna z nazwą używaną w konfiguracji. Skrypt uruchamiania utworzył już nazwę JNDI jako java:jboss/datasources/JPAWorldDataSource, jak pokazano w poniższym przykładzie:

    <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>
    
  2. Uzyskaj dostęp do bazy danych MySQL w jednostce PersistenceContext, jak pokazano w poniższym przykładzie:

    @Transactional(REQUIRED)
    @RequestScoped
    public class CityService {
    
        @PersistenceContext(unitName = "JPAWorldDatasourcePU")
        EntityManager em;
    

Uzyskiwanie dostępu do aplikacji

Przykładowa aplikacja implementuje trzy punkty końcowe REST. Aby uzyskać dostęp do aplikacji i pobrać dane, wykonaj następujące kroki:

  1. Użyj przeglądarki, aby przejść do adresu URL aplikacji, który został wyświetlony w danych wyjściowych podczas wdrażania aplikacji.

  2. Aby uzyskać wszystkie informacje o kontynentach w formacie JSON, użyj metody GET na końcówce area.

    Zrzut ekranu przedstawiający punkt końcowy obszaru.

  3. Aby pobrać wszystkie kraje i regiony na określonym kontynencie, skorzystaj z GET metody na area punkcie końcowym i określ continent parametr ścieżki.

    Zrzut ekranu przedstawiający punkt końcowy obszaru z parametrem ścieżki kontynentu.

  4. Aby uzyskać wszystkie miasta, które mają populację większą niż milion w określonym kraju lub regionie, użyj GET metody w countries punkcie końcowym i określ countrycode parametr ścieżki.

    Zrzut ekranu przedstawiający punkt końcowy krajów z parametrem ścieżki kodu kraju.

Podsumowanie ćwiczenia

W tej lekcji sprawdzono punkty końcowe REST aplikacji i potwierdzono, że aplikacja może pobierać dane z bazy danych MySQL. W następnej lekcji przeanalizujesz dzienniki serwera.