Övning – Distribuera ett Jakarta EE-program till JBoss EAP i Azure App Service

Slutförd

I den här lektionen distribuerar du ett Jakarta EE-program till Red Hat JBoss Enterprise Application Platform (JBoss EAP) i Azure App Service. Du använder Plugin-programmet Maven för Azure App Service för att konfigurera projektet, kompilera och distribuera programmet och konfigurera en datakälla.

Konfigurera appen

Konfigurera appen med Plugin-programmet Maven för Azure App Service med hjälp av följande steg:

  1. Kör konfigurationsmålet för Azure-plugin-programmet interaktivt med hjälp av följande kommando:

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

    Viktig

    Om du ändrar regionen för din MySQL-server bör du matcha den regionen med regionen för jakarta EE-programservern för att minimera fördröjningar i svarstiden.

  2. Använd värdena i följande tabell för att besvara interaktiva frågor:

    Inmatningselement Värde
    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

    Följande utdata är typiska:

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

    När du har använt Maven-kommandot är följande exempel ett typiskt tillägg till maven -pom.xml-filen :

    <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. Kontrollera ditt element <region> i pom.xml-filen . Om dess värde inte matchar installationsplatsen för MySQL ändrar du det till samma plats.

  4. Använd följande exempel för att ändra webContainer värdet i dinpom.xml-fil till Jbosseap 8för JBoss EAP 8-miljön i Azure App Service:

    Tips

    Från och med februari 2025 är den senaste tillgängliga versionen av JBoss EAP 8.0 Update 4.1.

    <runtime>
        <os>Linux</os>
        <javaVersion>Java 17</javaVersion>
        <webContainer>Jbosseap 8</webContainer> <!-- Change this value -->
    </runtime>
    
  5. Lägg till följande XML i <resources>-elementet av din pom.xml-fil. Den här konfigurationen används för att distribuera startfilen, som du uppdaterar senare i den här lektionen.

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

    Resursen <type> värde startup implementerar det angivna skriptet som startup.sh för Linux eller startup.cmd för Windows. Distributionsplatsen är /home/site/scripts/.

    Notera

    Du kan välja distributionsalternativet och distributionsplatsen genom att type ange på något av följande sätt:

    • type=war distribuerar WAR-filen till /home/site/wwwroot/app.war om inte path har angetts.
    • type=war&path=webapps/<appname> distribuerar WAR-filen till /home/site/wwwroot/webapps/<appname>.
    • type=jar distribuerar WAR-filen till /home/site/wwwroot/app.jar. Parametern path ignoreras.
    • type=ear distribuerar WAR-filen till /home/site/wwwroot/app.ear. Parametern path ignoreras.
    • type=lib distribuerar JAR till /home/site/libs. Du måste ange path parameter.
    • type=static distribuerar skriptet till /home/site/scripts. Du måste ange parametern path .
    • type=startup distribuerar skriptet som startup.sh i Linux eller startup.cmd i Windows. Skriptet distribueras till /home/site/scripts/. Parametern path ignoreras.
    • type=zip packa upp .zip-filen till /home/site/wwwroot. Parametern path är valfri.
  6. Kontrollera värdena för elementen resourceGroup och appName i filenpom.xml .

  7. Tilldela värdena för resourceGroup och appName till miljövariabler med hjälp av följande kommandon:

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

Kompilera och skapa Jakarta EE-appen

När du har konfigurerat distributionsinställningarna för Azure App Service kompilerar och paketerar du källkoden med hjälp av följande kommando:

./mvnw clean package

Följande utdata är typiska:

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

Distribuera Jakarta EE-appen till JBoss EAP på Azure App Service

När du har kompilerats och paketerats med koden distribuerar du programmet med hjälp av följande kommando:

./mvnw azure-webapp:deploy

Du bör se utdata som innehåller ett meddelande om att det har lyckats och URL:en för det distribuerade programmet. Se till att spara url:en åt sidan för senare användning.

Konfigurera en databasanslutning

Exempelprogrammet ansluter till din MySQL-databas och visar data. Maven-projektkonfigurationen i filenpom.xml anger MySQL JDBC-drivrutinen enligt följande exempel:

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

Därför installerar JBoss EAP automatiskt JDBC-drivrutinen ROOT.war_com.mysql.cj.jdbc.Driver_9_2 i distributionspaketet ROOT.war.

Skapa MySQL DataSource-objektet i JBoss EAP

För att få åtkomst till Azure Database for MySQL måste du konfigurera DataSource objektet i JBoss EAP och ange JNDI-namnet (Java Naming and Directory Interface) i källkoden. Om du vill skapa ett MySQL-objekt DataSource i JBoss EAP använder du skriptet /WEB-INF/createMySQLDataSource.sh startup shell. I följande exempel visas en okonfigurerad version av skriptet som redan finns i 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

Notera

När du skapar datakällan anger du inget lösenord för MySQL-anslutningen. Miljövariabeln AZURE_MYSQL_CONNECTIONSTRING anges i parametern --connection-url . Den här miljövariabeln anges automatiskt när tjänstanslutningen skapas senare.

Värdet för tjänstanslutningen är inställt på jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp, som använder användarnamnet aad_jbossapp utan lösenord. Genom att lägga &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin till den här URL:en aktiveras Microsoft Entra ID-autentisering för aad_jbossapp användaren.

Konfigurera App Service-instansen för att anropa startskriptet med hjälp av följande kommando:

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

När skriptet har körts anropar programservern det varje gång programservern startas om.

Notera

Om distributionsartefakten inte är ROOT.war ändrar du även värdet --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2 .

Konfigurera tjänstanslutningen för flexibel MySQL-server

När du har konfigurerat startskriptet konfigurerar du App Service för att använda Service Connector för mySQL-anslutningen för flexibel server med hjälp av följande steg:

  1. Ange miljövariabler med hjälp av följande kommandon:

    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)
    

    Miljövariablerna används för följande ändamål:

    • PASSWORDLESS_USER_NAME_SUFFIX är suffixet för användarnamnet som används för att ansluta till den flexibla MySQL-servern. Användarnamnet som skapades har prefixet aad_ följt av det angivna suffixet.
    • SOURCE_WEB_APP_ID är ID:t för Azure App Service-instansen som används för att ansluta till den flexibla MySQL-servern.
    • MYSQL_ID är ID:t för den flexibla MySQL-servern.
    • TARGET_MYSQL_ID anger databasnamnet $MYSQL_ID/databases/world för att upprätta en anslutning till en användare som har behörighet att komma åt world-databasen.
    • MANAGED_ID är den hanterade identitet som används för att ansluta till den flexibla MySQL-servern.
  2. Lägg till tillägget för serviceconnector-passwordless och skapa tjänstanslutningen med hjälp av följande kommandon:

    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
    

    Notera

    Om du får ett felmeddelande som Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present.kör du kommandot igen efter några sekunder.

  3. I SQL-prompten kontrollerar du listan över användare som är registrerade i MySQL med hjälp av följande fråga:

    SELECT user, host, plugin FROM mysql.user;
    

    Följande utdata är typiska:

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

    Du bör se en aad_jbossapp användare som använder plugin-programmet aad_auth . Från JBoss EAP som distribuerats i Azure kan du ansluta till den flexibla MySQL-servern med användarnamnet aad_jbossapp utan lösenord.

Bekräfta DataSource-referensen i koden

För att få åtkomst till MySQL-databasen från ditt program måste du konfigurera datakällreferensen i ditt programprojekt.

Databasens åtkomstkod implementeras med hjälp av Java Persistence API (JPA). Konfigurationen för referensen DataSource finns i JPA-konfigurationsfilen persistence.xml.

Använd följande steg för att bekräfta referensen DataSource :

  1. Öppna filen src/main/resources/META-INF/persistence.xml och kontrollera om DataSource namnet matchar namnet som användes i konfigurationen. Startskriptet skapade redan JNDI-namnet som java:jboss/datasources/JPAWorldDataSource, enligt följande exempel:

    <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. Få åtkomst till MySQL-databasen i PersistenceContext enhetsnamnet enligt följande exempel:

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

Få åtkomst till programmet

Exempelprogrammet implementerar tre REST-slutpunkter. Använd följande steg för att komma åt programmet och hämta data:

  1. Använd webbläsaren för att navigera till programmets URL, som visades i utdata när du distribuerade programmet.

  2. Om du vill hämta all information om kontinenten i JSON-format använder du GET metoden på area slutpunkten.

    Skärmbild av områdesslutpunkten.

  3. Om du vill hämta alla länder och regioner på en angiven kontinent använder du GET metoden på area slutpunkten och anger en continent sökvägsparameter.

    Skärmbild av områdesslutpunkten med en parameter för kontinentsökväg.

  4. Om du vill hämta alla städer som har en befolkning som är större än en miljon inom det angivna landet eller regionen använder du GET metoden på countries slutpunkten och anger en countrycode sökvägsparameter.

    Skärmbild av ländernas slutpunkt med parametern countrycode path.

Övningssammanfattning

I den här lektionen verifierade du programmets REST-slutpunkter och bekräftade att ditt program kan hämta data från mySQL-databasen. I nästa lektion undersöker du serverloggarna.