Oefening: Een Jakarta EE-toepassing implementeren in JBoss EAP in Azure App Service

Voltooid

In deze les implementeert u een Jakarta EE-toepassing in Red Hat JBoss Enterprise Application Platform (JBoss EAP) in Azure App Service. U gebruikt de Maven-invoegtoepassing voor Azure App Service om het project te configureren, de toepassing te compileren en te implementeren en een gegevensbron te configureren.

De app configureren

Configureer de app met de Maven-invoegtoepassing voor Azure App Service met behulp van de volgende stappen:

  1. Voer het configuratiedoel van de Azure-invoegtoepassing interactief uit met behulp van de volgende opdracht:

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

    Belangrijk

    Als u de regio van uw MySQL-server wijzigt, moet u deze regio koppelen aan de regio van uw Jakarta EE-toepassingsserver om latentievertragingen te minimaliseren.

  2. Gebruik de waarden in de volgende tabel om de interactieve prompts te beantwoorden:

    Invoerelement Waarde
    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

    De volgende uitvoer is gebruikelijk:

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

    Nadat u de Maven-opdracht hebt gebruikt, is het volgende voorbeeld een typische toevoeging aan uw Maven -pom.xml-bestand :

    <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. Controleer het element in uw <region>pom.xml bestand. Als de waarde niet overeenkomt met de installatielocatie van MySQL, wijzigt u deze in dezelfde locatie.

  4. Gebruik het volgende voorbeeld om de webContainer waarde in uw pom.xml-bestand te wijzigen in Jbosseap 8, voor de JBoss EAP 8-omgeving in Azure App Service:

    Aanbeveling

    Vanaf februari 2025 is de nieuwste beschikbare versie van JBoss EAP 8.0 Update 4.1.

    <runtime>
        <os>Linux</os>
        <javaVersion>Java 17</javaVersion>
        <webContainer>Jbosseap 8</webContainer> <!-- Change this value -->
    </runtime>
    
  5. Voeg de volgende XML toe aan het element van het <resources>pom.xml-bestand . Deze configuratie wordt gebruikt voor het implementeren van het opstartbestand, dat u later in deze les bijwerkt.

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

    Het resource <type> gebruikt startup om het opgegeven script te implementeren als het bestand startup.sh voor Linux of startup.cmd voor Windows. De implementatielocatie is /home/site/scripts/.

    Notitie

    U kunt de implementatieoptie en implementatielocatie kiezen door op een van de volgende manieren op te type geven:

    • type=war implementeert het WAR-bestand op /home/site/wwwroot/app.war als path niet wordt gespecificeerd.
    • type=war&path=webapps/<appname> implementeert het WAR-bestand op /home/site/wwwroot/webapps/<appname>.
    • type=jar implementeert het WAR-bestand op /home/site/wwwroot/app.jar. De path parameter wordt genegeerd.
    • type=ear implementeert het WAR-bestand op /home/site/wwwroot/app.ear. De path parameter wordt genegeerd.
    • type=lib implementeert de JAR in /home/site/libs. U moet de parameter opgeven path .
    • type=static implementeert het script in /home/site/scripts. U moet de path parameter opgeven.
    • type=startup implementeert het script als startup.sh in Linux of startup.cmd in Windows. Het script wordt geïmplementeerd in /home/site/scripts/. De path parameter wordt genegeerd.
    • type=zip Pak het .zip bestand uit naar /home/site/wwwroot. De path-parameter is optioneel.
  6. Controleer de waarden voor de resourceGroup en appName elementen in uw pom.xml bestand.

  7. Wijs de waarden voor resourceGroup en appName aan omgevingsvariabelen toe met behulp van de volgende opdrachten:

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

De Jakarta EE-app compileren en bouwen

Nadat u de azure App Service-implementatie-instellingen hebt geconfigureerd, compileert en verpakt u de broncode met behulp van de volgende opdracht:

./mvnw clean package

De volgende uitvoer is gebruikelijk:

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

De Jakarta EE-app implementeren in JBoss EAP in Azure App Service

Nadat u de code hebt gecompileerd en verpakt, implementeert u de toepassing met behulp van de volgende opdracht:

./mvnw azure-webapp:deploy

U zou uitvoer moeten zien die een succesbericht bevat en de URL van de geïmplementeerde toepassing. Zorg ervoor dat u de URL opslaat voor later gebruik.

Een databaseverbinding configureren

De voorbeeldtoepassing maakt verbinding met uw MySQL-database en geeft gegevens weer. De Maven-projectconfiguratie in het pom.xml-bestand geeft het MySQL JDBC-stuurprogramma op, zoals wordt weergegeven in het volgende voorbeeld:

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

Als gevolg hiervan installeert JBoss EAP het JDBC-stuurprogramma ROOT.war_com.mysql.cj.jdbc.Driver_9_2 automatisch in uw implementatiepakket ROOT.war.

Het MySQL DataSource-object maken in JBoss EAP

Als u toegang wilt krijgen tot Azure Database for MySQL, moet u het DataSource object configureren in JBoss EAP en de JNDI-naam (Java Naming and Directory Interface) opgeven in uw broncode. Als u een MySQL-object DataSource wilt maken in JBoss EAP, gebruikt u het opstartshellscript /WEB-INF/createMySQLDataSource.sh . In het volgende voorbeeld ziet u een niet-geconfigureerde versie van het script dat zich al in Azure App Service voordeed:

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

Notitie

Wanneer u de gegevensbron maakt, geeft u geen wachtwoord op voor de MySQL-verbinding. De omgevingsvariabele AZURE_MYSQL_CONNECTIONSTRING wordt opgegeven in de --connection-url parameter. Deze omgevingsvariabele wordt automatisch ingesteld wanneer de serviceverbinding later wordt gemaakt.

De waarde voor de serviceverbinding is ingesteld op jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp, waarbij de aad_jbossapp gebruikersnaam zonder een wachtwoord wordt gebruikt. Door deze &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin URL toe te voegen, is Microsoft Entra ID-verificatie ingeschakeld voor de aad_jbossapp gebruiker.

Configureer uw App Service-exemplaar om het opstartscript aan te roepen met behulp van de volgende opdracht:

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

Nadat het script is uitgevoerd, roept de toepassingsserver deze telkens aan wanneer de toepassingsserver opnieuw wordt opgestart.

Notitie

Als uw implementatieartefact niet ROOT.war is, wijzigt u ook de --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2 waarde.

De serviceverbinding voor de flexibele MySQL-server configureren

Nadat u het opstartscript hebt geconfigureerd, configureert u App Service voor het gebruik van Service Connector voor de flexibele MySQL-serververbinding met behulp van de volgende stappen:

  1. Stel omgevingsvariabelen in met behulp van de volgende opdrachten:

    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)
    

    De omgevingsvariabelen worden gebruikt voor de volgende doeleinden:

    • PASSWORDLESS_USER_NAME_SUFFIX is het achtervoegsel voor de gebruikersnaam die wordt gebruikt om verbinding te maken met de flexibele MySQL-server. De gemaakte gebruikersnaam heeft het voorvoegsel gevolgd door het opgegeven achtervoegsel aad_ .
    • SOURCE_WEB_APP_ID is de ID van het Azure App Service-exemplaar dat wordt gebruikt om verbinding te maken met de MySQL-flexibele server.
    • MYSQL_ID is de id van de flexibele MySQL-server.
    • TARGET_MYSQL_ID specificeert de databasenaam van $MYSQL_ID/databases/world om een verbinding tot stand te brengen met een gebruiker die toestemming heeft om toegang te krijgen tot de world-database.
    • MANAGED_ID is de beheerde identiteit die wordt gebruikt om verbinding te maken met de flexibele MySQL-server.
  2. Voeg de extensie toe voor serviceconnector-passwordless en maak de serviceverbinding met behulp van de volgende opdrachten:

    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
    

    Notitie

    Als je een foutmelding krijgt zoals Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present., voer dan de opdracht na een paar seconden opnieuw uit.

  3. Controleer bij de SQL-prompt de lijst met gebruikers die zijn geregistreerd in MySQL met behulp van de volgende query:

    SELECT user, host, plugin FROM mysql.user;
    

    De volgende uitvoer is gebruikelijk:

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

    U ziet nu een aad_jbossapp gebruiker die gebruikmaakt van de aad_auth invoegtoepassing. Vanuit JBoss EAP die is geïmplementeerd in Azure, kunt u verbinding maken met de flexibele MySQL-server met behulp van de aad_jbossapp gebruikersnaam zonder wachtwoord.

Bevestig de DataSource-verwijzing in de code

Als u toegang wilt krijgen tot de MySQL-database vanuit uw toepassing, moet u de verwijzing naar de gegevensbron in uw toepassingsproject configureren.

De databasetoegangscode wordt geïmplementeerd met behulp van de Java Persistence-API (JPA). De configuratie voor de DataSource verwijzing bevindt zich in het JPA-configuratiebestand persistence.xml.

Gebruik de volgende stappen om de DataSource verwijzing te bevestigen:

  1. Open het bestand src/main/resources/META-INF/persistence.xml en controleer of de DataSource naam overeenkomt met de naam die in de configuratie wordt gebruikt. Het opstartscript heeft al de JNDI-naam gemaakt, zoals wordt weergegeven in het volgende voorbeeld: 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>
    
  2. Open de MySQL-database in de PersistenceContext eenheidsnaam, zoals wordt weergegeven in het volgende voorbeeld:

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

Toegang tot de toepassing

De voorbeeldtoepassing implementeert drie REST-eindpunten. Gebruik de volgende stappen om toegang te krijgen tot de toepassing en gegevens op te halen:

  1. Gebruik uw browser om naar de toepassings-URL te navigeren, die werd weergegeven in de uitvoer toen u de toepassing implementeerde.

  2. Als u alle continentinformatie in JSON-indeling wilt ophalen, gebruikt u de GET methode op het area eindpunt.

    Schermopname van het gebiedseindpunt.

  3. Als u alle landen en regio's op een opgegeven continent wilt ophalen, gebruikt u de GET methode op het area eindpunt en geeft u een continent padparameter op.

    Schermopname van het gebiedseindpunt met een continentpadparameter.

  4. Als u alle steden wilt ophalen die meer dan één miljoen inwoners hebben binnen het land of de opgegeven regio, gebruikt u de GET methode op het countries eindpunt en geeft u een countrycode padparameter op.

    Schermopname van het eindpunt met landen en de landcode padparameter.

Samenvatting van oefening

In deze les hebt u de REST-eindpunten van de toepassing gevalideerd en bevestigd dat uw toepassing gegevens kan ophalen uit uw MySQL-database. In de volgende les bekijkt u de serverlogboeken.