Ćwiczenie — wdrażanie aplikacji Java EE (Jakarta EE) w usłudze JBoss EAP w usłudze aplikacja systemu Azure
W tym ćwiczeniu wdrożysz aplikację Java EE (Jakarta EE) w aplikacji JBoss EAP w usłudze aplikacja systemu Azure Service. Wtyczka Maven służy do konfigurowania projektu, kompilowania i wdrażania aplikacji oraz konfigurowania źródła danych.
Konfigurowanie aplikacji za pomocą wtyczki Maven dla usługi aplikacja systemu Azure
Skonfigurujmy aplikację, wykonując cel konfiguracji w wtyczki Maven dla usługi aplikacja systemu Azure Service.
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.9.0:config
Ważne
Jeśli zmienisz region serwera MySQL, należy również zmienić go na ten sam region dla serwera aplikacji Java EE, aby zminimalizować opóźnienia.
W poleceniu wybierz pozycję Java 11 dla języka Java w wersji i Stos środowiska uruchomieniowego JBoss EAP 7.
Element wejściowy | Wartość |
---|---|
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 |
Po uruchomieniu polecenia w terminalu będą wyświetlane komunikaty podobne do następujących:
$ ./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] ------------------------------------------------------------------------
$
Po zakończeniu polecenia zobaczysz, że w pliku Maven pom.xml
zostanie dodany następujący wpis.
<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>
Ważne
<region>
Sprawdź element. Jeśli nie jest to ta sama lokalizacja instalacji co MySQL, zmień ją na tę samą lokalizację.
Po dodaniu powyższej konfiguracji do wdrożenia na platformie Azure dodaj następujące wpisy XML, aby wdrożyć plik startowy. Zasób <type>startup</type>
wdraża określony skrypt jako startup.sh
(Linux) lub startup.cmd
(Windows) w systemie /home/site/scripts/
. W poniższym kroku skonfigurujemy skrypt uruchamiania.
<!-- 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 -->
Uwaga
Możesz określić następujący zasób do wdrożenia w pliku XML:
type=<war|jar|ear|lib|startup|static|zip>
type=war
program wdroży plik wojny,/home/site/wwwroot/app.war
jeślipath
nie zostanie określonytype=war&path=webapps/<appname>\
będzie zachowywać się dokładnie tak jak wardeploy przez rozpakowywanie aplikacji do /home/site/wwwroot/webapps/<appname>type=jar
wdroży plik wojny w pliku/home/site/wwwroot/app.jar
.path
Parametr zostanie zignorowanytype=ear
wdroży plik wojny w pliku/home/site/wwwroot/app.ear
.path
Parametr zostanie zignorowanytype=lib
spowoduje wdrożenie pliku jar w folderze /home/site/libs.path
Należy określić parametrtype=static
spowoduje wdrożenie skryptu w pliku/home/site/scripts
.path
parametr musi zostać określonytype=startup
spowoduje wdrożenie skryptu jakostartup.sh
(Linux) lubstartup.cmd
(Windows) w systemie/home/site/scripts/
.path
Parametr zostanie zignorowanytype=zip
rozpakuj plik zip do/home/site/wwwroot
pliku .path
parametr jest opcjonalny.
Teraz sprawdź wartości nazwy grupy zasobów i nazwy aplikacji z powyższego pliku XML. Zanotuj te nazwy lub lepiej przypisz je do zmiennych środowiskowych.
<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>
Jeśli używasz powłoki Bash, skonfiguruj zmienne środowiskowe za pomocą następującego polecenia. Użyjesz tych wartości później.
export RESOURCEGROUP_NAME=jakartaee-app-on-jboss-1625038814881-rg
export WEBAPP_NAME=jakartaee-app-on-jboss-1625038814881
Kompilowanie i kompilowanie aplikacji Java EE
Po skonfigurowaniu ustawień wdrażania usługi aplikacja systemu Azure skompiluj i spakuj kod źródłowy.
./mvnw clean package
Następujące dane wyjściowe są wyświetlane w terminalu:
[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] ------------------------------------------------------------------------
Wdrażanie aplikacji Java EE w aplikacji JBoss EAP w usłudze aplikacja systemu Azure
Po skompilowaniu i spakowaniu kodu wdróż aplikację:
./mvnw azure-webapp:deploy
W terminalu zostanie wyświetlony następujący komunikat:
[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] ------------------------------------------------------------------------
Zanotuj adres URL wdrożonej aplikacji, szczególnie następujący wiersz w danych wyjściowych narzędzia Maven:
[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net
Konfigurowanie połączenia z bazą danych
Przykładowa aplikacja łączy się z bazą danych MySQL i wyświetla dane.
W konfiguracji projektu Maven w systemie pom.xml
określono sterownik MySQL JDBC w następujący sposób:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
W rezultacie narzędzie JBoss EAP automatycznie instaluje sterownik JDBC do pakietu wdrożeniowego (ROOT.war
). Możesz odwołać się do nazwy sterownika JDBC mySQL w następujący sposób:
ROOT.war_com.mysql.cj.jdbc.Driver_8_0
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ę JNDI w kodzie źródłowym.
Aby utworzyć obiekt MySQL DataSource
w aplikacji JBoss EAP, utworzyliśmy następujący skrypt powłoki uruchamiania. Plik skryptu znajduje się createMySQLDataSource.sh
w /WEB-INF
katalogu .
Uwaga
W skrypcie powiążemy źródło danych MySQL przy użyciu polecenia interfejsu wiersza polecenia JBoss. Parametry połączenia, nazwa użytkownika i hasło używają zmiennych środowiskowych MYSQL_CONNECTION_URL
, MYSQL_USER
i MYSQL_PASSWORD
.
Źródło pliku skryptu jest wyświetlane w następnej kolejności. Ten plik skryptu został już przekazany do usługi App Service, ale nie został jeszcze skonfigurowany do wywołania.
#!/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
Teraz skonfiguruj wystąpienie usługi App Service w celu wywołania skryptu uruchamiania:
az webapp config set --startup-file '/home/site/scripts/startup.sh' \
-n ${WEBAPP_NAME} \
-g ${RESOURCEGROUP_NAME}
Po uruchomieniu skryptu będzie on wywoływany za każdym razem, gdy serwer aplikacji zostanie ponownie uruchomiony.
Uwaga
Jeśli artefakt wdrożenia nie ROOT.war
jest , musisz również zmienić --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_8_0
wartość.
Konfigurowanie zmiennych środowiskowych na potrzeby nawiązywania połączenia z bazą danych MySQL
Po skonfigurowaniu skryptu uruchamiania skonfiguruj usługę App Service tak, aby korzystała z określonych zmiennych środowiskowych:
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
Napiwek
Wartości MYSQL_CONNECTION_URL
i MYSQL_USER
MYSQL_PASSWORD
zostały ustawione z poprzedniej lekcji.
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. Zaimplementowaliśmy kod dostępu do bazy danych przy użyciu interfejsu API trwałości języka Java (JPA).
Konfiguracja odwołania DataSource
została dodana w persistence.xml
pliku , który jest plikiem konfiguracji JPA.
Uzyskaj dostęp do następującego pliku:
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── META-INF
│ │ │ └── persistence.xml
Sprawdź, czy nazwa jest zgodna DataSource
z nazwą używaną w konfiguracji. Kod utworzył już nazwę JNDI jako 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>
Następnie możesz uzyskać dostęp do bazy danych MySQL, do której odwołuje się nazwa lekcji w PersistenceContext
następujący sposób:
@Transactional(REQUIRED)
@RequestScoped
public class CityService {
@PersistenceContext(unitName = "JPAWorldDatasourcePU")
EntityManager em;
Uzyskiwanie dostępu do aplikacji
W przykładowej aplikacji zaimplementowaliśmy trzy punkty końcowe REST. Dostęp do aplikacji i weryfikowanie tych punktów końcowych można uzyskać za pomocą przeglądarki internetowej lub curl
polecenia.
Aby uzyskać dostęp do aplikacji, musisz odwołać się do adresu URL aplikacji, który został uzyskany z wcześniejszej sekcji:
[INFO] Successfully deployed the artifact to
https://jakartaee-app-on-jboss-1606464084546.azurewebsites.net
Uruchom następujące polecenie, aby uzyskać wszystkie informacje o kontynencie w formacie JSON.
$ curl https://${WEBAPP_NAME}.azurewebsites.net/area
["North America","Asia","Africa","Europe","South America","Oceania","Antarctica"]$
Jeśli określisz kontynent w adresie URL, możesz pobrać wszystkie kraje/regiony na określonym kontynencie.
$ 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"
}
....
Na koniec, jeśli określisz kod kraju/regionu po /countries
, możesz pobrać wszystkie miasta, które mają populację większą niż 1 milion w kraju/regionie.
$ 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"
Podsumowanie ćwiczeń
Sprawdzono teraz punkty końcowe REST aplikacji i przetestowano, czy aplikacja może pobierać dane z bazy danych MySQL.
W następnej lekcji zapoznasz się z dziennikami serwera.