Exercício – Implantar um aplicativo Jakarta EE no JBoss EAP no Serviço de Aplicativo do Azure
Nesta unidade, você implantará um aplicativo Jakarta EE no Red Hat JBoss Enterprise Application Platform (JBoss EAP) no Serviço de Aplicativo do Azure. Use o Plug-in do Maven para o Serviço de Aplicativo do Azure para configurar o projeto, compilar e implantar o aplicativo e configurar uma fonte de dados.
Configurar o aplicativo
Configure o aplicativo com o Plug-in do Maven para o Serviço de Aplicativo do Azure usando as seguintes etapas:
Execute a meta de configuração do plug-in do Azure interativamente usando o seguinte comando:
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:configImportante
Se você alterar a região do servidor MySQL, deverá corresponder essa região à região do servidor de aplicativos Jakarta EE para minimizar os atrasos de latência.
Use os valores na tabela a seguir para responder aos prompts interativos:
Elemento de entrada Valor 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]:YA saída a seguir é típica:
[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] ------------------------------------------------------------------------Depois de usar o comando Maven, o exemplo a seguir é uma adição típica ao seu arquivo Maven pom.xml.
<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>Verifique o
<region>elemento no seu arquivo pom.xml. Se o valor não corresponder ao local de instalação do MySQL, altere-o para o mesmo local.Use o exemplo a seguir para modificar o valor do
webContainerno seu arquivo pom.xml paraJbosseap 8no ambiente JBoss EAP 8 no Serviço de Aplicativo do Azure.Dica
A partir de fevereiro de 2025, a versão mais recente disponível do JBoss EAP é a Atualização 4.1 do 8.0.
<runtime> <os>Linux</os> <javaVersion>Java 17</javaVersion> <webContainer>Jbosseap 8</webContainer> <!-- Change this value --> </runtime>Adicione o XML a seguir ao elemento
<resources>do arquivo pom.xml. Essa configuração é usada para implantar o arquivo de inicialização, que você atualizará posteriormente nesta unidade.<resource> <type>startup</type> <directory>${project.basedir}/src/main/webapp/WEB-INF/</directory> <includes> <include>createMySQLDataSource.sh</include> </includes> </resource>O valor do recurso
<type>destartupimplanta o script especificado como o arquivo startup.sh para Linux ou startup.cmd para Windows. O local da implantação é /home/site/scripts/.Observação
Você pode escolher a opção de implantação e o local de implantação especificando
typeuma das seguintes maneiras:type=warimplanta o arquivo WAR em /home/site/wwwroot/app.war sepathnão for especificado.type=war&path=webapps/<appname>implanta o arquivo WAR em /home/site/wwwroot/webapps/<appname>.type=jarimplanta o arquivo WAR em /home/site/wwwroot/app.jar. O parâmetropathé ignorado.type=earimplanta o arquivo WAR em /home/site/wwwroot/app.ear. O parâmetropathé ignorado.type=libimplanta o JAR em /home/site/libs. Você deve especificar opathparâmetro.type=staticimplanta o script em /home/site/scripts. Você deve especificar opathparâmetro.type=startupimplanta o script como startup.sh no Linux ou startup.cmd no Windows. O script é implantado em /home/site/scripts/. O parâmetropathé ignorado.type=zipdescompacta o arquivo .zip para /home/site/wwwroot. Opathparâmetro é opcional.
Verifique os valores dos elementos
resourceGroupeappNameno arquivo pom.xml.Atribua os valores para
resourceGroupeappNamepara variáveis de ambiente usando os seguintes comandos:export RESOURCE_GROUP_NAME=<resource-group> export WEB_APP_NAME=<app-name>
Compilar e criar o aplicativo Jakarta EE
Depois de definir as configurações de implantação do Serviço de Aplicativo do Azure, compile e empacote o código-fonte usando o seguinte comando:
./mvnw clean package
A saída a seguir é típica:
[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] ------------------------------------------------------------------------
Implantar o aplicativo Jakarta EE no JBoss EAP no Serviço de Aplicativo do Azure
Depois de compilar e empacotar o código, implante o aplicativo usando o seguinte comando:
./mvnw azure-webapp:deploy
Você deverá ver a saída que inclui uma mensagem de êxito e a URL do aplicativo implantado. Certifique-se de salvar a URL para uso posterior.
Configurar uma conexão de banco de dados
O aplicativo de exemplo se conecta ao banco de dados MySQL e exibe dados. A configuração do projeto Maven no arquivo pom.xml especifica o driver JDBC do MySQL, conforme mostrado no exemplo a seguir:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
Como resultado, o JBoss EAP instala automaticamente o driver ROOT.war_com.mysql.cj.jdbc.Driver_9_2 JDBC no pacote de implantação ROOT.war.
Criar o objeto MySQL DataSource no JBoss EAP
Para acessar o Banco de Dados do Azure para MySQL, você precisa configurar o DataSource objeto no JBoss EAP e especificar o nome JNDI (Java Naming and Directory Interface) no código-fonte. Para criar um objeto MySQL DataSource no JBoss EAP, use o script de shell de inicialização /WEB-INF/createMySQLDataSource.sh . O exemplo a seguir mostra uma versão não configurada do script já no Serviço de Aplicativo do Azure:
#!/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
Observação
Ao criar a fonte de dados, você não especifica uma senha para a conexão MySQL. A variável AZURE_MYSQL_CONNECTIONSTRING de ambiente é especificada no --connection-url parâmetro. Essa variável de ambiente é definida automaticamente quando a conexão de serviço é criada posteriormente.
O valor da conexão de serviço é definido como jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp, que usa o aad_jbossapp nome de usuário sem uma senha.
Ao acrescentar &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin a essa URL, a autenticação da ID do Microsoft Entra está habilitada para o aad_jbossapp usuário.
Configure sua instância do Serviço de Aplicativo para invocar o script de inicialização usando o seguinte comando:
az webapp config set \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${WEB_APP_NAME} \
--startup-file '/home/site/scripts/startup.sh'
Depois que o script é executado, o servidor de aplicativos o invoca sempre que o servidor de aplicativos é reiniciado.
Observação
Se o artefato de implantação não estiver ROOT.war, altere o valor --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2 também.
Configurar a conexão de serviço para o servidor flexível do MySQL
Depois de configurar o script de inicialização, configure o Serviço de Aplicativo para usar o Service Connector para a conexão de servidor flexível do MySQL usando as seguintes etapas:
Defina variáveis de ambiente usando os seguintes comandos:
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)As variáveis de ambiente são usadas para as seguintes finalidades:
PASSWORDLESS_USER_NAME_SUFFIXé o sufixo para o nome de usuário usado para se conectar ao servidor flexível MySQL. O nome de usuário criado tem o prefixoaad_seguido pelo sufixo especificado.SOURCE_WEB_APP_IDé a ID da instância do Serviço de Aplicativo do Azure usada para se conectar ao servidor flexível MySQL.MYSQL_IDé a ID do servidor flexível MySQL.TARGET_MYSQL_IDespecifica o nome$MYSQL_ID/databases/worlddo banco de dados para estabelecer uma conexão com um usuário que tenha permissão para acessar oworldbanco de dados.MANAGED_IDé a identidade gerenciada usada para se conectar ao servidor flexível MySQL.
Adicione a extensão para
serviceconnector-passwordlesse crie a conexão de serviço usando os seguintes comandos: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_IDObservação
se você receber uma mensagem de erro como
Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present.executar novamente o comando após alguns segundos.No prompt do SQL, verifique a lista de usuários registrados no MySQL usando a seguinte consulta:
SELECT user, host, plugin FROM mysql.user;A saída a seguir é típica:
+----------------------------------+-----------+-----------------------+ | 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)Você deve ver o usuário
aad_jbossappque usa o pluginaad_auth. No JBoss EAP implantado no Azure, você pode se conectar ao servidor flexível MySQL usando oaad_jbossappnome de usuário sem senha.
Confirmar a referência do DataSource no código
Para acessar o banco de dados MySQL do seu aplicativo, você precisa configurar a referência da fonte de dados em seu projeto de aplicativo.
O código de acesso do banco de dados é implementado usando a JPA (API de Persistência java). A configuração da DataSource referência está no arquivo de configuração JPA persistence.xml.
Use as seguintes etapas para confirmar a DataSource referência:
Abra o arquivo src/main/resources/META-INF/persistence.xml e verifique se o
DataSourcenome corresponde ao nome usado na configuração. O script de inicialização já criou o nome JNDI comojava:jboss/datasources/JPAWorldDataSource, conforme mostrado no exemplo a seguir:<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>Acesse o banco de dados MySQL no nome da
PersistenceContextunidade, conforme mostrado no exemplo a seguir:@Transactional(REQUIRED) @RequestScoped public class CityService { @PersistenceContext(unitName = "JPAWorldDatasourcePU") EntityManager em;
Acessar o aplicativo
O aplicativo de exemplo implementa três endpoints REST. Para acessar o aplicativo e recuperar dados, use as seguintes etapas:
Use o navegador para navegar até a URL do aplicativo, que foi mostrada na saída quando você implantou o aplicativo.
Para obter todas as informações do continente no formato JSON, use o método
GETno endpointarea.Para obter todos os países e regiões em um continente especificado, use o
GETmétodo noareaponto de extremidade e especifique umcontinentparâmetro de caminho.Para obter todas as cidades que têm uma população maior que um milhão dentro do país ou região especificada, use o
GETmétodo nocountriesponto de extremidade e especifique umcountrycodeparâmetro de caminho.
Resumo do exercício
Nesta unidade, você validou os pontos de extremidade REST do aplicativo e confirmou que seu aplicativo pode obter dados do banco de dados MySQL. Na próxima unidade, você examinará os logs do servidor.


