Exercício - Implantar um aplicativo Java EE (Jakarta EE) no JBoss EAP no Serviço de Aplicativo do Azure
Neste exercício, você implantará um aplicativo Java EE (Jakarta EE) no JBoss EAP no Serviço de Aplicativo do Azure. Use o plug-in Maven para configurar o projeto, compilar e implantar o aplicativo e configurar uma fonte de dados.
Configurar o aplicativo com o plug-in Maven para o Serviço de Aplicativo do Azure
Vamos configurar o aplicativo executando a meta de configuração no plug-in Maven para o Serviço de Aplicativo do Azure.
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
Importante
Se você alterar a região do seu servidor MySQL, você também deverá mudar para a mesma região do seu servidor de aplicativos Java EE para minimizar os atrasos de latência.
No comando, selecione Java 11 para versão Java e JBoss EAP 7 para pilha de tempo de execução.
Elemento de entrada | valor |
---|---|
Available subscriptions: |
Your appropriate subsctioption |
Choose a Web Container Web App [\<create\>]: |
1: <create> |
Define value for OS [Linux]: |
Linux |
Define value for javaVersion [Java 17]: |
2: Java 11 |
Define value for runtimeStack: |
1: Jbosseap 7 |
Define value for pricingTier [P1v3]: |
P1v3 |
Confirm (Y/N) [Y]: |
Y |
Depois de executar o comando, você receberá mensagens como as seguintes no terminal:
$ ./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
[INFO] Scanning for projects...
[INFO]
[INFO] ---------< com.microsoft.azure.samples:jakartaee-app-on-jboss >---------
[INFO] Building jakartaee-app-on-jboss 1.0-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- azure-webapp-maven-plugin:2.5.0:config (default-cli) @ jakartaee-app-on-jboss ---
[WARNING] The POM for com.microsoft.azure.applicationinsights.v2015_05_01:azure-mgmt-insights:jar:1.0.0-beta is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] Auth type: OAUTH2
Username: YOUR_EMAIL_ADDRESS@microsoft.com
Available subscriptions:
[INFO] Subscription: YOUR_SUBSCRIPTION(********-****-****-****-************)
[INFO] It may take a few minutes to load all Java Web Apps, please be patient.
Web Container Web Apps in subscription Microsoft Azure Internal Billing-CDA:
* 1: <create>
2: jakartaee-app-on-jboss-yoshio (linux, jbosseap 7.2-java8)
Please choose a Web Container Web App [<create>]:
Define value for OS [Linux]:
* 1: Linux
2: Windows
3: Docker
Enter your choice:
Define value for javaVersion [Java 8]:
* 1: Java 8
2: Java 11
Enter your choice:
Define value for runtimeStack:
1: Jbosseap 7.2
2: Jbosseap 7
* 3: Tomcat 8.5
4: Tomcat 9.0
Enter your choice: 1
Define value for pricingTier [P1v3]:
1: P3v3
2: P2v3
* 3: P1v3
Enter your choice:
Please confirm webapp properties
Subscription Id : ********-****-****-****-************
AppName : jakartaee-app-on-jboss-1625038814881
ResourceGroup : jakartaee-app-on-jboss-1625038814881-rg
Region : westeurope
PricingTier : P1v3
OS : Linux
Java : Java 8
Web server stack: Jbosseap 7.2
Deploy to slot : false
Confirm (Y/N) [Y]:
[INFO] Saving configuration to pom.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:43 min
[INFO] Finished at: 2021-06-30T16:40:47+09:00
[INFO] ------------------------------------------------------------------------
$
Depois que o comando terminar, você poderá ver que a seguinte entrada é adicionada 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.3.2</version>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.9.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
<pricingTier>P1v3</pricingTier>
<region>centralus</region>
<runtime>
<os>Linux</os>
<javaVersion>Java 11</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>
Importante
Verifique o <region>
elemento. Se não for o mesmo local de instalação do MySQL, altere-o para o mesmo local.
Depois de adicionar a configuração acima para implantação no Azure, adicione as seguintes entradas XML para implantar o arquivo de inicialização. O recurso <type>startup</type>
implanta o script especificado como startup.sh
(Linux) ou startup.cmd
(Windows) no /home/site/scripts/
. Configuramos o script de inicialização na etapa a seguir.
<!-- Please add following lines -->
<resource>
<type>startup</type>
<directory>${project.basedir}/src/main/webapp/WEB-INF/</directory>
<includes>
<include>createMySQLDataSource.sh</include>
</includes>
</resource>
<!-- Please add following lines -->
Nota
Você pode especificar o seguinte recurso para implantar no XML:
type=<war|jar|ear|lib|startup|static|zip>
type=war
implantará o arquivo war em/home/site/wwwroot/app.war
sepath
não for especificadotype=war&path=webapps/<appname>\
se comportará exatamente como o wardeploy, descompactando o aplicativo para /home/site/wwwroot/webapps/<appname>type=jar
implantará o arquivo war no/home/site/wwwroot/app.jar
.path
parâmetro será ignoradotype=ear
implantará o arquivo war no/home/site/wwwroot/app.ear
.path
parâmetro será ignoradotype=lib
implantará o jar em /home/site/libs.path
parâmetro deve ser especificadotype=static
implantará o script no/home/site/scripts
.path
parâmetro deve ser especificadotype=startup
implantará o script comostartup.sh
(Linux) oustartup.cmd
(Windows) no/home/site/scripts/
.path
parâmetro será ignoradotype=zip
descompactará o zip para/home/site/wwwroot
.path
é opcional.
Agora, verifique os valores para o nome do grupo de recursos e o nome do aplicativo no arquivo XML acima. Observe esses nomes ou atribua-os melhor às variáveis de ambiente.
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
Se você estiver usando Bash, configure as variáveis de ambiente com o seguinte comando. Você usará esses valores mais tarde.
export RESOURCEGROUP_NAME=jakartaee-app-on-jboss-1625038814881-rg
export WEBAPP_NAME=jakartaee-app-on-jboss-1625038814881
Compilar e construir o aplicativo Java EE
Depois de definir as configurações de implantação do Serviço de Aplicativo do Azure, compile e empacote o código-fonte.
./mvnw clean package
A seguinte saída aparece no terminal:
[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] Webapp assembled in [369 msecs]
[INFO] Building war: /private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.656 s
[INFO] Finished at: 2023-03-04T12:35:43-05:00
[INFO] ------------------------------------------------------------------------
Implantar o aplicativo Java EE no JBoss EAP no Serviço de Aplicativo do Azure
Depois de compilar e empacotar o código, implante o aplicativo:
./mvnw azure-webapp:deploy
A seguinte mensagem aparece no terminal:
[INFO] Creating resource group jakartaee-app-on-jboss-1625038814881-rg in region westeurope...
[INFO] Successfully created resource group jakartaee-app-on-jboss-1625038814881-rg.
[INFO] Creating app service plan...
[INFO] Successfully created app service plan asp-jakartaee-app-on-jboss-1625038814881.
[INFO] Creating web app jakartaee-app-on-jboss-1625038814881...
[INFO] Successfully created Web App jakartaee-app-on-jboss-1625038814881.
[INFO] Trying to deploy artifact to jakartaee-app-on-jboss-1625038814881...
[INFO] Deploying (/private/tmp/mslearn-jakarta-ee-azure/target/ROOT.war)[war] ...
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 02:11 min
[INFO] Finished at: 2023-03-04T12:38:39-05:00
[INFO] ------------------------------------------------------------------------
Observe a URL do aplicativo implantado, particularmente a seguinte linha na saída do Maven:
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
Configurar uma conexão de banco de dados
O aplicativo de exemplo se conecta ao seu banco de dados MySQL e exibe dados.
Na configuração do projeto Maven no pom.xml
, especificamos o driver JDBC MySQL da seguinte maneira:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
Como resultado, o JBoss EAP instala automaticamente o driver JDBC no seu pacote de implementação (ROOT.war
). Você pode se referir ao nome do driver JDBC MySQL da seguinte maneira:
ROOT.war_com.mysql.cj.jdbc.Driver_8_0
Criar o objeto MySQL DataSource no JBoss EAP
Para acessar o Banco de Dados do Azure para MySQL, você precisa configurar o objeto no JBoss EAP e especificar o DataSource
nome JNDI em seu código-fonte.
Para criar um objeto MySQL DataSource
no JBoss EAP, criamos o seguinte script de shell de inicialização. O arquivo de script está createMySQLDataSource.sh
sob o /WEB-INF
diretório.
Nota
No script, vinculamos o MySQL DataSource usando um comando JBoss CLI. A cadeia de conexão, o nome de usuário e a senha usam as variáveis MYSQL_CONNECTION_URL
de ambiente , MYSQL_USER
e MYSQL_PASSWORD
.
A origem do arquivo de script é mostrada a seguir. Esse arquivo de script já foi carregado no Serviço de Aplicativo, mas ainda não foi configurado para ser invocado.
#!/usr/bin/bash
# In order to use the variables in JBoss 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=${MYSQL_CONNECTION_URL} \
--driver-name=ROOT.war_com.mysql.cj.jdbc.Driver_8_0 \
--user-name=${MYSQL_USER} \
--password=${MYSQL_PASSWORD} \
--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
Agora, configure sua instância do Serviço de Aplicativo para invocar o script de inicialização:
az webapp config set --startup-file '/home/site/scripts/startup.sh' \
-n ${WEBAPP_NAME} \
-g ${RESOURCEGROUP_NAME}
Depois que o script for executado, ele será invocado sempre que o servidor de aplicativos for reiniciado.
Nota
Se o artefato de implantação não ROOT.war
for , você também precisará alterar o --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_8_0
valor.
Configurar as variáveis de ambiente para se conectar ao MySQL
Depois de configurar o script de inicialização, configure o Serviço de Aplicativo para usar determinadas variáveis de ambiente:
az webapp config appsettings set \
--resource-group ${RESOURCEGROUP_NAME} --name ${WEBAPP_NAME} \
--settings \
MYSQL_CONNECTION_URL='jdbc:mysql://mysqlserver-**********.mysql.database.azure.com:3306/world?useSSL=true&requireSSL=false' \
MYSQL_PASSWORD='************' \
MYSQL_USER=azureuser
Gorjeta
Os valores de MYSQL_CONNECTION_URL
, MYSQL_USER
e MYSQL_PASSWORD
foram definidos a partir da unidade anterior.
Confirme a referência DataSource no código
Para acessar o banco de dados MySQL de seu aplicativo, você precisa configurar a referência da fonte de dados em seu projeto de aplicativo. Implementamos o código de acesso ao banco de dados usando Java Persistence API (JPA).
A configuração para a DataSource
referência foi adicionada no persistence.xml
, que é o arquivo de configuração do JPA.
Aceda ao seguinte ficheiro:
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ └── persistence.xml
Verifique se o DataSource
nome corresponde ao nome usado na configuração. O código já criou o nome JNDI como 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>
</persistence>
Em seguida, você pode acessar o banco de dados MySQL referenciado no nome da unidade da PersistenceContext
seguinte maneira:
@Transactional(REQUIRED)
@RequestScoped
public class CityService {
@PersistenceContext(unitName = "JPAWorldDatasourcePU")
EntityManager em;
Aceda à aplicação
No aplicativo de exemplo, implementamos três pontos de extremidade REST. Você pode acessar o aplicativo e validar esses pontos de extremidade usando um navegador da Web ou um curl
comando.
Para acessar o aplicativo, você precisa fazer referência à URL do aplicativo, que você obteve de uma seção anterior:
[INFO] Successfully deployed the artifact to
https://jakartaee-app-on-jboss-1606464084546.azurewebsites.net
Execute o seguinte comando para obter todas as informações do continente no formato JSON.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area
["North America","Asia","Africa","Europe","South America","Oceania","Antarctica"]$
Se especificar o continente no URL, pode obter todos os países/regiões no continente especificado.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area/Asia | jq '.[] | { name: .name, code: .code }'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 16189 100 16189 0 0 65278 0 --:--:-- --:--:-- --:--:-- 65542
{
"name": "Afghanistan",
"code": "AFG"
}
{
"name": "United Arab Emirates",
"code": "ARE"
}
{
"name": "Armenia",
"code": "ARM"
}
{
"name": "Azerbaijan",
"code": "AZE"
}
{
"name": "Bangladesh",
"code": "BGD"
}
....
Finalmente, se você especificar um código de país/região depois /countries
de , você pode obter todas as cidades que têm população superior a 1 milhão dentro do país/região.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/countries/JPN | jq '.[].name'
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 100 788 100 788 0 0 2671 0 --:--:-- --:--:-- --:--:-- 2662
"Tokyo"
"Jokohama [Yokohama]"
"Osaka"
"Nagoya"
"Sapporo"
"Kioto"
"Kobe"
"Fukuoka"
"Kawasaki"
"Hiroshima"
"Kitakyushu"
Resumo do exercício
Agora você validou os endpoints REST do aplicativo e testou que seu aplicativo pode obter dados do seu banco de dados MySQL.
Na próxima unidade, você examinará os logs do servidor.