Azure App Service で Tomcat、JBoss、または Java SE アプリのデータ ソースを構成する

この記事では、App Service で Java SE、Tomcat、または JBoss アプリでデータ ソースを構成する方法について説明します。

Azure App Service は、次の 3 つのバリアントでフル マネージド サービスで Java Web アプリケーションを実行します。

  • Java SE - 埋め込みサーバー (Spring Boot、Dropwizard、Quarkus、埋め込み Tomcat または Jetty サーバーを含むものなど) を含む JAR パッケージとしてデプロイされたアプリを実行できます。
  • Tomcat - 組み込みの Tomcat サーバーは、WAR パッケージとしてデプロイされたアプリを実行できます。
  • JBoss EAP - Premium v3 および Isolated v2 価格レベルの Linux アプリでのみサポートされます。 組み込みの JBoss EAP サーバーは、WAR または EAR パッケージとしてデプロイされたアプリを実行できます。

Note

Spring アプリケーションの場合は、Azure Spring Apps を使用することをお勧めします。 ただし、Azure App Service は引き続き宛先として使用できます。 アドバイスについてはJava ワークロード宛先ガイダンスに関する記事を参照してください。

データ ソースの構成

Spring Boot アプリケーション内のデータ ソースに接続するには、接続文字列を作成し、それらを application.properties ファイルに挿入することをお勧めします。

  1. App Service ページの [構成] セクションに文字列の名前を設定し、JDBC 接続文字列を値フィールドに貼り付けて、タイプを [カスタム] に設定します。 必要に応じて、この接続文字列をスロット設定として設定することができます。

    この接続文字列は、CUSTOMCONNSTR_<your-string-name> という名前の環境変数としてアプリケーションにアクセスできます。 たとえば、CUSTOMCONNSTR_exampledb のようにします。

  2. application.properties ファイルで、環境変数名を使用してこの接続文字列を参照します。 たとえば、例では次のコードを使用します。

    app.datasource.url=${CUSTOMCONNSTR_exampledb}
    

詳細については、データ アクセス外部化された構成に関する Spring Boot の資料を参照してください。

ヒント

既定では、Linux Tomcat コンテナーは Tomcat サーバーで共有データ ソースを自動的に構成できます。 そのための操作は、有効な JDBC 接続文字列を含むアプリ設定を Oracle、SQL Server、PostgreSQL、または MySQL データベース (接続資格情報を含む) に追加することだけです。App Service は、コンテナーで使用可能な適切なドライバーを使用して、対応する共有データベースを /usr/local/tomcat/conf/context.xml に自動的に追加します。 このアプローチを使用したエンド ツー エンドのシナリオについては、「チュートリアル: Azure App Service on Linux と MySQL を使用して Tomcat Web アプリを構築する」を参照してください。

これらの説明は、すべてのデータベース接続に適用されます。 プレースホルダーを、選択したデータベースのドライバー クラス名と JAR ファイルに置き換える必要があります。 一般的なデータベースのクラス名とドライバーのダウンロードを含む表を次に示します。

データベース ドライバーのクラス名 JDBC ドライバー
PostgreSQL org.postgresql.Driver ダウンロード
MySQL com.mysql.jdbc.Driver ダウンロード ("プラットフォームに依存しない" を選択)
SQL Server com.microsoft.sqlserver.jdbc.SQLServerDriver ダウンロード

Java Database Connectivity (JDBC) または Java Persistence API (JPA) を使用するように Tomcat を構成するには、まず、起動時に Tomcat によって読み込まれる CATALINA_OPTS 環境変数をカスタマイズします。 App Service Maven プラグインのアプリ設定を使用して、次の値を設定します。

<appSettings>
    <property>
        <name>CATALINA_OPTS</name>
        <value>"$CATALINA_OPTS -Ddbuser=${DBUSER} -Ddbpassword=${DBPASSWORD} -DconnURL=${CONNURL}"</value>
    </property>
</appSettings>

または、Azure portal の [構成]>[アプリケーション設定] ページで環境変数を設定します。

次に、データ ソースを Tomcat サーブレットで実行されている 1 つのアプリケーション、またはすべてのアプリケーションのどちらに対して使用可能にする必要があるかを判定します。

アプリケーション レベル データ ソース

  1. プロジェクトの META-INF/ ディレクトリ内に context.xml ファイルを作成します。 META-INF/ ディレクトリが存在しない場合は作成します。

  2. context.xml で、Context 要素を追加してデータ ソースを JNDI アドレスにリンクします。 driverClassName プレースホルダーを、上の表にあるドライバーのクラス名に置き換えます。

    <Context>
        <Resource
            name="jdbc/dbconnection"
            type="javax.sql.DataSource"
            url="${connURL}"
            driverClassName="<insert your driver class name>"
            username="${dbuser}"
            password="${dbpassword}"
        />
    </Context>
    
  3. アプリケーションでこのデータ ソースを使用するよう、アプリケーションの web.xml を更新します。

    <resource-env-ref>
        <resource-env-ref-name>jdbc/dbconnection</resource-env-ref-name>
        <resource-env-ref-type>javax.sql.DataSource</resource-env-ref-type>
    </resource-env-ref>
    

共有のサーバーレベル リソース

サーバーレベルの共有データ ソースを追加するには、Tomcat の server.xml を編集する必要があります。 これを行う最も信頼性の高い方法は次のとおりです。

  1. スタートアップ スクリプトをアップロードし、[構成]>[スタートアップ コマンド] でスクリプトへのパスを設定します。 FTP を使用してスタートアップ スクリプトをアップロードできます。

スタートアップ スクリプトによって、server.xml ファイルへの xsl 変換が作成され、結果の xml ファイルが /usr/local/tomcat/conf/server.xml に出力されます。 スタートアップ スクリプトでは、apk を使用して libxslt をインストールする必要があります。 xsl ファイルとスタートアップ スクリプトは FTP 経由でアップロードできます。 以下にスタートアップ スクリプトの例を示します。

# Install libxslt. Also copy the transform file to /home/tomcat/conf/
apk add --update libxslt

# Usage: xsltproc --output output.xml style.xsl input.xml
xsltproc --output /home/tomcat/conf/server.xml /home/tomcat/conf/transform.xsl /usr/local/tomcat/conf/server.xml

次の XSL ファイルの例では、新しいコネクタ ノードを Tomcat server.xml に追加します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()" name="Copy">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@* | node()" mode="insertConnector">
    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template match="comment()[not(../Connector[@scheme = 'https']) and
                                 contains(., '&lt;Connector') and
                                 (contains(., 'scheme=&quot;https&quot;') or
                                  contains(., &quot;scheme='https'&quot;))]">
    <xsl:value-of select="." disable-output-escaping="yes" />
  </xsl:template>

  <xsl:template match="Service[not(Connector[@scheme = 'https'] or
                                   comment()[contains(., '&lt;Connector') and
                                             (contains(., 'scheme=&quot;https&quot;') or
                                              contains(., &quot;scheme='https'&quot;))]
                                  )]
                      ">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" mode="insertConnector" />
    </xsl:copy>
  </xsl:template>

  <!-- Add the new connector after the last existing Connnector if there's one -->
  <xsl:template match="Connector[last()]" mode="insertConnector">
    <xsl:call-template name="Copy" />

    <xsl:call-template name="AddConnector" />
  </xsl:template>

  <!-- ... or before the first Engine if there's no existing Connector -->
  <xsl:template match="Engine[1][not(preceding-sibling::Connector)]"
                mode="insertConnector">
    <xsl:call-template name="AddConnector" />

    <xsl:call-template name="Copy" />
  </xsl:template>

  <xsl:template name="AddConnector">
    <!-- Add new line -->
    <xsl:text>&#xa;</xsl:text>
    <!-- This is the new connector -->
    <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" 
               maxThreads="150" scheme="https" secure="true" 
               keystoreFile="${{user.home}}/.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS" />
  </xsl:template>

</xsl:stylesheet>

構成を完了する

最後に、ドライバーの JAR を Tomcat クラスパス内に配置し、App Service を再起動します。

  1. JDBC ドライバー ファイルが Tomcat クラスローダーで確実に使用できるように、これらのファイルを /home/site/lib ディレクトリに配置します。 Cloud Shell で、ドライバー JAR ごとに az webapp deploy --type=lib を実行します。
az webapp deploy --resource-group <group-name> --name <app-name> --src-path <jar-name>.jar --type=lib --path <jar-name>.jar

サーバー レベルのデータ ソースを作成した場合は、App Service Linux アプリケーションを再起動します。 Tomcat は CATALINA_BASE/home/tomcat にリセットし、更新された構成を使用します。

JBoss EAP を使用してデータ ソースを登録する場合の 3 つの主要なステップは、JDBC ドライバーのアップロード、モジュールとしての JDBC ドライバーの追加、モジュールの登録です。 App Service はステートレスのホスティング サービスであるため、データ ソース モジュールを追加および登録するための構成コマンドは、スクリプト化して、コンテナーの起動時に適用する必要があります。

  1. データベースの JDBC ドライバーを入手します。

  2. JDBC ドライバー用の XML モジュール定義ファイルを作成します。 PostgreSQL のモジュール定義の例を以下に示します。

    <?xml version="1.0" ?>
    <module xmlns="urn:jboss:module:1.1" name="org.postgres">
        <resources>
        <!-- ***** IMPORTANT : REPLACE THIS PLACEHOLDER *******-->
        <resource-root path="/home/site/deployments/tools/postgresql-42.2.12.jar" />
        </resources>
        <dependencies>
            <module name="javax.api"/>
            <module name="javax.transaction.api"/>
        </dependencies>
    </module>
    
  3. JBoss CLI コマンドが含まれる jboss-cli-commands.cli という名前のファイルを作成します。 JBoss コマンドを使用して、モジュールを追加し、データ ソースとして登録する必要があります。 次の例では、PostgreSQL 用の JBoss CLI コマンドを示します。

    #!/usr/bin/env bash
    module add --name=org.postgres --resources=/home/site/deployments/tools/postgresql-42.2.12.jar --module-xml=/home/site/deployments/tools/postgres-module.xml
    
    /subsystem=datasources/jdbc-driver=postgres:add(driver-name="postgres",driver-module-name="org.postgres",driver-class-name=org.postgresql.Driver,driver-xa-datasource-class-name=org.postgresql.xa.PGXADataSource)
    
    data-source add --name=postgresDS --driver-name=postgres --jndi-name=java:jboss/datasources/postgresDS --connection-url=${POSTGRES_CONNECTION_URL,env.POSTGRES_CONNECTION_URL:jdbc:postgresql://db:5432/postgres} --user-name=${POSTGRES_SERVER_ADMIN_FULL_NAME,env.POSTGRES_SERVER_ADMIN_FULL_NAME:postgres} --password=${POSTGRES_SERVER_ADMIN_PASSWORD,env.POSTGRES_SERVER_ADMIN_PASSWORD:example} --use-ccm=true --max-pool-size=5 --blocking-timeout-wait-millis=5000 --enabled=true --driver-class=org.postgresql.Driver --exception-sorter-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLExceptionSorter --jta=true --use-java-context=true --valid-connection-checker-class-name=org.jboss.jca.adapters.jdbc.extensions.postgres.PostgreSQLValidConnectionChecker
    
  4. JBoss CLI コマンドを呼び出すスタートアップ スクリプト startup_script.sh を作成します。 次の例は、jboss-cli-commands.cli を呼び出す方法を示しています。 後で、コンテナーの起動時にこのスクリプトを実行するように App Service を構成します。

    $JBOSS_HOME/bin/jboss-cli.sh --connect --file=/home/site/deployments/tools/jboss-cli-commands.cli
    
  5. 任意の FTP クライアントを使用して、JDBC ドライバー、jboss-cli-commands.clistartup_script.sh、およびモジュール定義を /site/deployments/tools/ にアップロードします。

  6. コンテナーの起動時に startup_script.sh を実行するようにサイトを構成します。 Azure portal で、 [構成]>[一般設定]>[スタートアップ コマンド] に移動します。 スタートアップ コマンド フィールドを /home/site/deployments/tools/startup_script.sh に設定します。 変更内容を保存します。

データソースが JBoss サーバーに追加されたことを確認するには、webapp に SSH で接続して、$JBOSS_HOME/bin/jboss-cli.sh --connect を実行します。 JBoss に接続したら、/subsystem=datasources:read-resource を実行してデータ ソースの一覧を表示します。

次のステップ

Java 開発者向けの Azure センターにアクセスして、Azure クイック スタート、チュートリアル、および Java リファレンス ドキュメントを入手してください。