Упражнение. Развертывание приложения Jakarta EE в JBoss EAP в Службе приложений Azure
В этом уроке вы развернете приложение Jakarta EE в Red Hat JBoss Enterprise Application Platform (JBoss EAP) в Службе приложений Azure. Подключаемый модуль Maven для Службы приложений Azure используется для настройки проекта, компиляции и развертывания приложения и настройки источника данных.
Настройка приложения
Настройте приложение с помощью подключаемого модуля Maven для службы приложений Azure, выполнив следующие действия.
Запустите целевую конфигурацию подключаемого модуля Azure в интерактивном режиме с помощью следующей команды:
./mvnw com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:configВажный
При изменении региона сервера MySQL следует сопоставить этот регион с регионом сервера приложений Jakarta EE, чтобы свести к минимуму задержки.
Используйте значения в следующей таблице, чтобы ответить на интерактивные запросы:
Входной элемент Ценность 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]:YНиже приведены типичные выходные данные:
[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] ------------------------------------------------------------------------После использования команды Maven следующий пример является типичным дополнением к файлу 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>Проверьте
<region>элемент в вашем файле pom.xml. Если его значение не соответствует расположению установки MySQL, измените его на то же расположение.Используйте следующий пример, чтобы изменить значение
webContainerв файле pom.xml наJbosseap 8, для среды JBoss EAP 8 в службе приложений Azure.Совет
По состоянию на февраль 2025 г. последняя доступная версия JBoss EAP — 8.0 с обновлением 4.1.
<runtime> <os>Linux</os> <javaVersion>Java 17</javaVersion> <webContainer>Jbosseap 8</webContainer> <!-- Change this value --> </runtime>Добавьте следующий XML-код в
<resources>элемент файла pom.xml . Эта конфигурация используется для развертывания файла запуска, который вы обновляете позже в этом уроке.<resource> <type>startup</type> <directory>${project.basedir}/src/main/webapp/WEB-INF/</directory> <includes> <include>createMySQLDataSource.sh</include> </includes> </resource>Значение
<type>ресурсаstartupразвертывает указанный скрипт в виде файла startup.sh для Linux или startup.cmd для Windows. Расположение развертывания — /home/site/scripts/.Заметка
Вы можете выбрать вариант развертывания и расположение развертывания, указав
typeодин из следующих способов:-
type=warразвертывает WAR-файл в /home/site/wwwroot/app.war, еслиpathне указан. -
type=war&path=webapps/<appname>развертывает WAR-файл в папке /home/site/wwwroot/webapps/<appname>. -
type=jarразвертывает WAR-файл в /home/site/wwwroot/app.jar. Параметрpathигнорируется. -
type=earразвертывает WAR-файл в папке /home/site/wwwroot/app.ear. Параметрpathигнорируется. -
type=libразвертывает JAR-файл в папке /home/site/libs. Необходимо указатьpathпараметр. -
type=staticразвертывает скрипт в папке /home/site/scripts. Необходимо указать параметрpath. -
type=startupразвертывает скрипт как startup.sh в Linux или startup.cmd в Windows. Скрипт развертывается в /home/site/scripts/. Параметрpathигнорируется. -
type=zipраспакует файл.zip в папку /home/site/wwwroot. Параметрpathявляется необязательным.
-
Проверьте значения элементов
resourceGroupиappNameв вашем pom.xml файле.Присвойте значения
resourceGroupпеременным среды иappNameпеременным среды с помощью следующих команд:export RESOURCE_GROUP_NAME=<resource-group> export WEB_APP_NAME=<app-name>
Компиляция и сборка приложения Jakarta EE
После настройки параметров развертывания Службы приложений Azure скомпилируйте и упаковайте исходный код с помощью следующей команды:
./mvnw clean package
Ниже приведены типичные выходные данные:
[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] ------------------------------------------------------------------------
Разверните приложение Jakarta EE на JBoss EAP в Службе приложений Azure
После компиляции и упаковки кода разверните приложение с помощью следующей команды:
./mvnw azure-webapp:deploy
Вы увидите выходные данные, в том числе сообщение об успешном выполнении и URL-адрес развернутого приложения. Не забудьте сохранить URL-адрес для последующего использования.
Настройка подключения к базе данных
Пример приложения подключается к базе данных MySQL и отображает данные. Конфигурация проекта Maven в файлеpom.xml указывает драйвер JDBC MySQL, как показано в следующем примере:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-jdbc-driver}</version>
</dependency>
В результате JBoss EAP автоматически устанавливает драйвер ROOT.war_com.mysql.cj.jdbc.Driver_9_2 JDBC в пакет развертывания ROOT.war.
Создание объекта DataSource MySQL в JBoss EAP
Чтобы получить доступ к базе данных Azure для MySQL, необходимо настроить DataSource объект в JBoss EAP и указать в исходном коде имя Java Naming and Directory Interface (JNDI). Чтобы создать объект MySQL DataSource в JBoss EAP, используйте стартовый shell-скрипт /WEB-INF/createMySQLDataSource.sh. В следующем примере показана ненастроенная версия скрипта, уже размещенная в Службе приложений 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
Заметка
При создании источника данных не укажите пароль для подключения MySQL. Переменная AZURE_MYSQL_CONNECTIONSTRING среды указана в параметре --connection-url . Эта переменная среды автоматически устанавливается при создании подключения к службе позже.
Значение параметра подключения к службе задано как jdbc:mysql://$MYSQL_SERVER_INSTANCE.mysql.database.azure.com:3306/world?serverTimezone=UTC&sslmode=required&user=aad_jbossapp, при этом используется имя пользователя aad_jbossapp без пароля.
При добавлении &authenticationPlugins=com.azure.identity.extensions.jdbc.mysql.AzureMysqlAuthenticationPlugin к этому URL-адресу для пользователя включена аутентификация Microsoft Entra ID.
Настройте экземпляр службы приложений для вызова скрипта запуска с помощью следующей команды:
az webapp config set \
--resource-group ${RESOURCE_GROUP_NAME} \
--name ${WEB_APP_NAME} \
--startup-file '/home/site/scripts/startup.sh'
После запуска скрипта сервер приложений вызывает его при каждом перезапуске сервера приложений.
Заметка
Если артефакт развертывания не является ROOT.war, измените значение --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_9_2.
Настройка подключения службы для гибкого сервера MySQL
После настройки скрипта запуска настройте службу приложений, чтобы использовать соединитель службы для гибкого подключения сервера MySQL, выполнив следующие действия.
Задайте переменные среды с помощью следующих команд:
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)Переменные среды используются в следующих целях:
-
PASSWORDLESS_USER_NAME_SUFFIX— суффикс для имени пользователя, используемого для подключения к гибкому серверу MySQL. Имя пользователя, созданное, имеет префиксaad_, за которым следует указанный суффикс. -
SOURCE_WEB_APP_ID— это идентификатор экземпляра службы приложений Azure, используемого для подключения к гибкому серверу MySQL. -
MYSQL_ID— это идентификатор гибкого сервера MySQL. -
TARGET_MYSQL_IDуказывает имя базы данных$MYSQL_ID/databases/world, чтобы установить соединение с пользователем, который имеет разрешение на доступ к базе данныхworld. -
MANAGED_ID— это управляемое удостоверение, используемое для подключения к гибкому серверу MySQL.
-
Добавьте расширение для
serviceconnector-passwordlessи создайте подключение к службе с помощью следующих команд: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Заметка
Если вы получаете сообщение об ошибке, например
Resource '********-****-****-****-************' does not exist or one of its queried reference-property objects are not present., повторно выполните команду через несколько секунд.В командной строке SQL проверьте список пользователей, зарегистрированных в MySQL, с помощью следующего запроса:
SELECT user, host, plugin FROM mysql.user;Ниже приведены типичные выходные данные:
+----------------------------------+-----------+-----------------------+ | 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)Вы должны увидеть
aad_jbossappпользователя, который использует плагинaad_auth. С помощью JBoss EAP, развернутого в Azure, можно подключиться к гибкому серверу MySQL с помощьюaad_jbossappимени пользователя без пароля.
Подтвердите ссылку на DataSource в коде
Чтобы получить доступ к базе данных MySQL из приложения, необходимо настроить ссылку на источник данных в проекте приложения.
Код доступа к базе данных реализуется с помощью API сохраняемости Java (JPA). Конфигурация ссылки DataSource находится в файле конфигурации JPA persistence.xml.
Чтобы подтвердить ссылку DataSource , выполните следующие действия.
Откройте файл src/main/resources/META-INF/persistence.xml и проверьте, соответствует ли
DataSourceимя имени, используемому в конфигурации. Скрипт запуска уже создал имя JNDI,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>Получите доступ к базе данных MySQL в
PersistenceContextназвании единицы, как показано в следующем примере:@Transactional(REQUIRED) @RequestScoped public class CityService { @PersistenceContext(unitName = "JPAWorldDatasourcePU") EntityManager em;
Доступ к приложению
Пример приложения реализует три конечные точки REST. Чтобы получить доступ к приложению и получить данные, выполните следующие действия.
Используйте браузер для перехода по URL-адресу приложения, который отображался в выходных данных при развертывании приложения.
Чтобы получить все сведения о континенте в формате JSON, используйте
GETметод в конечной точкеarea.Чтобы получить все страны и регионы на указанном континенте, используйте
GETметод вareaконечной точке и укажитеcontinentпараметр пути.Чтобы получить все города с населением более одного миллиона в указанной стране или регионе, используйте
GETметод вcountriesконечной точке и укажитеcountrycodeпараметр пути.
Сводка упражнений
В этом уроке вы проверили конечные точки REST приложения и подтвердили, что приложение может получать данные из базы данных MySQL. В следующем уроке вы проверяете журналы сервера.