Övning – Distribuera ett Java EE-program (Jakarta EE) till JBoss EAP i Azure App Service

Slutförd

I den här övningen distribuerar du ett Java EE-program (Jakarta EE) till JBoss EAP i Azure App Service. Du använder Plugin-programmet Maven för att konfigurera projektet, kompilera och distribuera programmet och konfigurera en datakälla.

Konfigurera appen med Maven-pluginprogrammet för Azure App Service

Nu ska vi konfigurera programmet genom att köra konfigurationsmålet i Maven-pluginprogrammet för Azure App Service.

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

Viktig

Om du ändrar regionen för MySQL-servern bör du också ändra till samma region för Java EE-programservern för att minimera fördröjningar i svarstiden.
I kommandot väljer du Java 11 för Java-version och JBoss EAP 7 för körningsstack.

Inmatningselement Värde
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

När du har kört kommandot får du meddelanden som följande i terminalen:

$ ./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] ------------------------------------------------------------------------
$ 

När kommandot har slutförts kan du se att följande post läggs till i maven-pom.xml-filen.

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

Viktig

Kontrollera elementet <region>. Om det inte är samma installationsplats som MySQL ändrar du den till samma plats.

När du har lagt till ovanstående konfiguration för distribution till Azure lägger du till följande XML-poster för att distribuera startfilen. Resursen <type>startup</type> distribuerar det angivna skriptet som startup.sh (Linux) eller startup.cmd (Windows) till /home/site/scripts/. Vi konfigurerar startskriptet i följande steg.

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

Notera

Du kan ange följande resurs som ska distribueras i XML:

  • type=<war|jar|ear|lib|startup|static|zip>

    • type=war distribuerar WAR-filen till /home/site/wwwroot/app.war om pathinte specificerad
    • type=war&path=webapps/<appname>\ beter sig exakt som wardeploy genom att packa upp appen till /home/site/wwwroot/webapps/<appname>
    • type=jar distribuerar krigsfilen till /home/site/wwwroot/app.jar. Parametern path kommer att ignoreras
    • type=ear kommer att distribuera WAR-filen till /home/site/wwwroot/app.ear. path parametern ignoreras
    • type=lib distribuerar jar-filen till /home/site/libs. path parameter måste anges
    • type=static distribuerar skriptet till /home/site/scripts. path parameter måste anges
    • type=startup kommer att implementera skriptet som startup.sh (Linux) eller startup.cmd (Windows) till /home/site/scripts/. path-parametern kommer att ignoreras
    • type=zip kommer att packa upp zip-filen till /home/site/wwwroot. path parametern är valfri.

Kontrollera nu värdena för resursgruppens namn och programnamn från XML-filen ovan. Observera dessa namn eller tilldela dem bättre till miljövariabler.

<resourceGroup>jakartaee-app-on-jboss-1625038814881-rg</resourceGroup>
<appName>jakartaee-app-on-jboss-1625038814881</appName>

Om du använder Bash konfigurerar du miljövariablerna med följande kommando. Du använder dessa värden senare.

export RESOURCEGROUP_NAME=jakartaee-app-on-jboss-1625038814881-rg
export WEBAPP_NAME=jakartaee-app-on-jboss-1625038814881

Kompilera och skapa Java EE-appen

När du har konfigurerat distributionsinställningarna för Azure App Service kompilerar och paketerar du källkoden.

./mvnw clean package

Följande utdata visas i terminalen:

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

Distribuera Java EE-appen till JBoss EAP i Azure App Service

Efter att du har kompilerat och paketerat koden, distribuera programmet.

./mvnw azure-webapp:deploy

Följande meddelande visas i terminalen:

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

Observera URL:en för det distribuerade programmet, särskilt följande rad i Maven-utdata:

[INFO] Successfully deployed the artifact to https://jakartaee-app-on-jboss-1625038814881.azurewebsites.net

Konfigurera en databasanslutning

Exempelprogrammet ansluter till din MySQL-databas och visar data.

I Maven-projektkonfigurationen i pom.xmlangav vi MySQL JDBC-drivrutinen enligt följande:

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

Därför installerar JBoss EAP automatiskt JDBC-drivrutinen i distributionspaketet (ROOT.war). Du kan referera till namnet på MySQL JDBC-drivrutinen enligt följande:

ROOT.war_com.mysql.cj.jdbc.Driver_8_0

Skapa MySQL DataSource-objektet i JBoss EAP

För att få åtkomst till Azure Database for MySQL måste du konfigurera DataSource-objektet i JBoss EAP och ange JNDI-namnet i källkoden.

För att skapa ett MySQL-DataSource objekt i JBoss EAP skapade vi följande startgränssnittsskript. Skriptfilen createMySQLDataSource.sh i katalogen /WEB-INF.

Anteckning

I skriptet binder vi MySQL DataSource med hjälp av ett JBoss CLI-kommando. Anslutningssträngen, användarnamnet och lösenordet använder miljövariablerna MYSQL_CONNECTION_URL, MYSQL_USERoch MYSQL_PASSWORD.

Källan till skriptfilen visas härnäst. Den här skriptfilen har redan laddats upp till App Service, men den har ännu inte konfigurerats för att anropas.

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

Konfigurera nu App Service-instansen så att den anropar startskriptet:

az webapp config set --startup-file '/home/site/scripts/startup.sh' \
-n ${WEBAPP_NAME} \
-g ${RESOURCEGROUP_NAME}

När skriptet har körts anropas det varje gång programservern startas om.

Not

Om distributionsartefakten inte är ROOT.warmåste du också ändra värdet för --driver-name=YOUR_ARTIFACT.war_com.mysql.cj.jdbc.Driver_8_0.

Konfigurera miljövariablerna för att ansluta till MySQL

När du har konfigurerat startskriptet konfigurerar du App Service för att använda vissa miljövariabler:

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

Tips

Värdena för MYSQL_CONNECTION_URL, MYSQL_USER och MYSQL_PASSWORD angavs från föregående enhet.

Bekräfta DataSource-referensen i koden

För att få åtkomst till MySQL-databasen från ditt program måste du konfigurera datakällreferensen i ditt programprojekt. Vi implementerade databasens åtkomstkod med hjälp av Java Persistence API (JPA).

Konfigurationen för referensen för DataSource har lagts till i persistence.xml, som är konfigurationsfilen för JPA.

Få åtkomst till följande fil:

├── src
│   ├── main
│   │   ├── resources
│   │   │   └── META-INF
│   │   │       └── persistence.xml

Kontrollera om namnet på DataSource matchar namnet som används i konfigurationen. Koden har redan skapat JNDI-namnet som 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>

Sedan kan du komma åt MySQL-databasen som refereras i PersistenceContext enhetsnamn på följande sätt:

@Transactional(REQUIRED)
@RequestScoped
public class CityService {

    @PersistenceContext(unitName = "JPAWorldDatasourcePU")
    EntityManager em;

Få åtkomst till programmet

I exempelprogrammet implementerade vi tre REST-slutpunkter. Du kan komma åt programmet och verifiera dessa slutpunkter med hjälp av en webbläsare eller ett curl kommando.

För att få åtkomst till programmet måste du referera till programmets URL, som du fick från ett tidigare avsnitt:

[INFO] Successfully deployed the artifact to  
https://jakartaee-app-on-jboss-1606464084546.azurewebsites.net

Kör följande kommando för att hämta all kontinentinformation i JSON-format.

Skärmbild som visar området som REST-slutpunkt.

$ curl https://${WEBAPP_NAME}.azurewebsites.net/area
["North America","Asia","Africa","Europe","South America","Oceania","Antarctica"]$ 

Om du anger kontinenten i URL:en kan du hämta alla länder/regioner på den angivna kontinenten.

Skärmbild som visar kontinenten som REST-slutpunkt.

$ 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"
}
....

Om du slutligen anger en lands-/regionkod efter /countrieskan du hämta alla städer som har en befolkning som är större än 1 miljon inom landet/regionen.

Skärmbild som visar städer som REST-slutpunkt.

$ 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"

Övningssammanfattning

Nu har du verifierat programmets REST-slutpunkter och testat att programmet kan hämta data från MySQL-databasen.

I nästa lektion ska du undersöka serverloggarna.