Databricks SDK for Java

この記事では、 Databricks SDK for Java を使用して、Databricks アカウント、ワークスペース、および関連リソースでの操作を自動化する方法について説明します。 この記事では、Databricks SDK for Java の READMEAPI リファレンスおよび例を補足します。

この機能はベータ版であり、本番運用で使用しても問題ありません。

ベータ期間中は、コードが依存する Databricks SDK for Java の特定のマイナー バージョンに依存関係をピン留めすることをお勧めします。 たとえば、 pom.xml for Maven などのファイルに依存関係をピン留めできます。 依存関係の固定の詳細については、「 依存関係メカニズムの概要」を参照してください。

始める前に

Java 用 Databricks SDK の使用を開始する前に、開発マシンに次のものが必要です。

  • Databricks 認証 が構成されています。

  • Java 8 以降と互換性のある Java 開発キット (JDK)。 Databricks SDK for Java を使用した継続的インテグレーション (CI) テストは、Java バージョン 8、11、17、および 20 と互換性があります。

  • Java 互換の統合開発環境 (IDE) をお勧めします。 Databricks は IntelliJ IDEA を推奨しています。

Databricks SDK for Java の使用を開始する

  1. プロジェクトの pom.xml ファイルで、Java 用 Databricks SDK に依存するようにビルド システムに指示します。 これを行うには、 pom.xml ファイルの既存の <dependencies> セクションに次の <dependency> を追加します。<dependencies> セクションが pom.xml ファイル内にまだ存在しない場合は、 <dependencies> 親要素を pom.xml ファイルに追加する必要があります。

    たとえば、プロジェクトのpom.xml ファイルを IntelliJ IDEA で開くには、[ツール] ウィンドウ> [プロジェクトの表示] > をクリックし、ダブルクリックして src > pom.xml >プロジェクト名を開きます。

    <dependencies>
      <dependency>
        <groupId>com.databricks</groupId>
        <artifactId>databricks-sdk-java</artifactId>
        <version>0.0.1</version>
      </dependency>
    </dependencies>
    

    必ず 0.0.1 最新バージョンの Databricks SDK for Java に置き換えてください。 最新バージョンは、 Maven の中央リポジトリで見つけることができます。

  2. プロジェクトに、宣言された Databricks SDK for Java への依存関係を取得するように指示します。 たとえば、IntelliJ IDEA のプロジェクトのプロジェクトツール ウィンドウで、プロジェクトのルート ノードを右クリックし、 [プロジェクトの再読み込み]をクリックします。

  3. Databricks SDK for Java をインポートし、 Databricks ワークスペース内のすべてのクラスターを一覧表示するコードを追加します。たとえば、プロジェクトの Main.java ファイルでは、コードは次のようになります。

    import com.databricks.sdk.WorkspaceClient;
    import com.databricks.sdk.service.compute.ClusterInfo;
    import com.databricks.sdk.service.compute.ListClustersRequest;
    
    public class Main {
      public static void main(String[] args) {
        WorkspaceClient w = new WorkspaceClient();
    
        for (ClusterInfo c : w.clusters().list(new ListClustersRequest())) {
          System.out.println(c.getClusterName());
        }
      }
    }
    

    前の WorkspaceClient w = new WorkspaceClient()の呼び出しで引数を設定しないことで、Java 用 Databricks SDK は、既定のプロセスを使用して Databricks 認証を実行しようとします。 このデフォルト動作をオーバーライドするには、次の 認証 セクションを参照してください。

  4. プロジェクトをビルドします。 たとえば、IntelliJ IDEAでこれを行うには、メインメニューから[ビルド] >[プロジェクトのビルド]をクリックします。

  5. メインファイルを実行します。 たとえば、IntelliJ IDEAでプロジェクトの Main.java ファイルに対してこれを行うには、メインメニューから[ 実行]>[メイン]の実行をクリックします。

  6. クラスターのリストが表示されます。 たとえば、IntelliJ IDEAでは、これは [実行 ]ツールウィンドウにあります。 このツール ウィンドウを表示するには、メイン メニューから [ ツール ウィンドウの表示] > [実行] >をクリックします。

Databricks アカウントまたはワークスペース を使用して Java 用 Databricks SDK を認証する

Databricks SDK for Java は、認証に対する統合された一貫性のあるアーキテクチャとプログラムによるアプローチである Databricks クライアント統合認証 標準を実装します。 このアプローチにより、Databricks での認証の設定と自動化が一元化され、予測可能になります。 これにより、Databricks 認証を一度構成すると、認証構成をさらに変更することなく、複数の Databricks ツールと SDK でその構成を使用できます。 Java のより完全なコード例など、詳細については、「 Databricks クライアント統合認証」を参照してください。

Java 用 Databricks SDK を使用してデータブリック認証を初期化するために使用できるコーディング パターンには、次のようなものがあります。

  • Databricks のデフォルト認証を使用するには、次のいずれかを実行します。

    • ターゲットの Databricks 認証の種類に必要なフィールドを使用して、カスタム Databricks 構成プロファイル を作成または識別します。 次に、 DATABRICKS_CONFIG_PROFILE 環境変数をカスタム構成プロファイルの名前に設定します。

    • ターゲットの Databricks 認証の種類に必要な環境変数を設定します。

    次に、たとえば、次のように Databricks デフォルト認証を使用して WorkspaceClient オブジェクトをインスタンス化します。

    import com.databricks.sdk.WorkspaceClient;
    // ...
    WorkspaceClient w = new WorkspaceClient();
    // ...
    
  • 必須フィールドのハードコーディングはサポートされていますが、Databricks personal アクセストークンなどの機密情報がコード内で公開されるリスクがあるため、お勧めしません。 次の例では、Databricks トークン認証のために Databricks ホストとアクセストークンの値をハードコーディングします。

    import com.databricks.sdk.WorkspaceClient;
    import com.databricks.sdk.core.DatabricksConfig;
    // ...
    DatabricksConfig cfg = new DatabricksConfig()
      .setHost("https://...")
      .setToken("...");
    WorkspaceClient w = new WorkspaceClient(cfg);
    // ...
    

Databricks SDK for Java README の 「認証 」も参照してください。

Databricks ユーティリティと Java を Databricks SDK for Java と共に使用する

Databricks ユーティリティ には、オブジェクト ストレージの効率的な操作、ノートブックのチェーンとパラメーター化、シークレットの操作を容易にするいくつかのヘルパー関数が用意されています。 Databricks には、Java コードで呼び出すことができる Scala ライブラリ用の Databricks ユーティリティが用意されており、プログラムで Databricks ユーティリティ にアクセスできます。

Java コードを使用して Scala 用 Databricks ユーティリティを呼び出すには、次の手順を実行します。

  1. Java プロジェクトで、前のセクションで説明したように、Java 用 Databricks SDK への依存関係を宣言します。

  2. Scala ライブラリ用の Databricks ユーティリティへの依存関係を宣言します。 これを行うには、pom.xml ファイルの既存の <dependencies> セクションに次の<dependency>を追加します。

    <dependency>
      <groupId>com.databricks</groupId>
      <artifactId>databricks-dbutils-scala_2.12</artifactId>
      <version>0.1.4</version>
    </dependency>
    

    0.1.4 を最新バージョンの Databricks ユーティリティ for Scala ライブラリに置き換えてください。最新バージョンは、 Maven の中央リポジトリで見つけることができます。

  3. 宣言された依存関係を Scala 用 Databricks ユーティリティに使用するようにプロジェクトに指示します。 たとえば、IntelliJ IDEA のプロジェクトの [ プロジェクト ] ツール ウィンドウで、プロジェクトのルート ノードをクリックし、[ Maven] > [プロジェクトの再読み込み] をクリックします。

  4. インポートするコードを追加し、Scala の Databricks ユーティリティを呼び出します。 たとえば、次のコードは Unity Catalog ボリュームを自動化します。 この例では、ワークスペース内のボリュームのパスに zzz_hello.txt という名前のファイルを作成し、ファイルからデータを読み取り、ファイルを削除します。

    import com.databricks.sdk.core.DatabricksConfig;
    import com.databricks.sdk.scala.dbutils.DBUtils;
    
    public class Main {
      public static void main(String[] args) {
        String filePath = "/Volumes/main/default/my-volume/zzz_hello.txt";
        String fileData = "Hello, Databricks!";
        DBUtils dbutils = DBUtils.getDBUtils(new DatabricksConfig().setProfile("DEFAULT"));
    
        dbutils.fs().put(filePath, fileData, true);
    
        System.out.println(dbutils.fs().head(filePath, 18));
    
        dbutils.fs().rm(filePath, false);
      }
    }
    
  5. プロジェクトをビルドし、メインファイルを実行します。

コード例

次のコード例は、Databricks SDK for Java を使用して、クラスターの作成と削除、ジョブの作成、アカウント レベルのグループの一覧表示を行う方法を示しています。 これらのコード例では、 Databricks SDK for Java のデフォルト Databricks 認証 プロセスを使用します。

その他のコード例については、GitHub の Databricks SDK for Java リポジトリにある サンプル フォルダーを参照してください。

クラスターを作成する

このコード例では、指定した Databricks Runtime バージョンとクラスター ノードの種類でクラスターを作成します。 このクラスターにはワーカーが 1 つあり、クラスターは 15 分のアイドル時間が経過すると自動的に終了します。

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Main {
  public static void main(String[] args) {
    WorkspaceClient w = new WorkspaceClient();

    CreateClusterResponse c = w.clusters().create(
      new CreateCluster()
        .setClusterName("my-cluster")
        .setSparkVersion("12.2.x-scala2.12")
        .setNodeTypeId("i3.xlarge")
        .setAutoterminationMinutes(15L)
        .setNumWorkers(1L)
    ).getResponse();

    System.out.println("View the cluster at " +
      w.config().getHost() +
      "#setting/clusters/" +
      c.getClusterId() +
      "/configuration\n");
  }
}

JDK 17 を使用するクラスターを作成する

JDK 8 は完全にサポートされています。 JDK 17 は、 Databricks Runtime バージョン 13.1 以降のパブリック プレビュー段階です。

このセクションでは、Java 開発キット (JDK) を使用してクラスターを作成するためのガイドを提供します。 JDK 17 でクラスターを作成し、ノートブックとジョブで Java を使用する方法について説明します。

クラスターを作成するときに、次の環境変数を [詳細オプション] > [Spark > 環境変数] に追加して、ドライバーとエグゼキューターの両方に JDK 17 を使用するように指定します。

JNAME=zulu17-ca-amd64

ARM ベースのクラスター (AWS Graviton インスタンスなど) を使用している場合は、代わりに次の環境変数を使用します。

JNAME=zulu17-ca-arm64

クラスターを完全に削除する

このコード例では、指定したクラスター ID を持つクラスターをワークスペースから完全に削除します。

import com.databricks.sdk.WorkspaceClient;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    System.out.println("ID of cluster to delete (for example, 1234-567890-ab123cd4):");

    Scanner in = new Scanner(System.in);
    String c_id = in.nextLine();
    WorkspaceClient w = new WorkspaceClient();

    w.clusters().permanentDelete(c_id);
  }
}

ジョブの作成

このコード例では、指定したクラスターで指定したノートブックを実行するために使用できる Databricks ジョブを作成します。 このコードを実行すると、ターミナルのユーザーから既存のノートブックのパス、既存のクラスター ID、および関連するジョブ設定が取得されます。

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.jobs.JobTaskSettings;
import com.databricks.sdk.service.jobs.NotebookTask;
import com.databricks.sdk.service.jobs.NotebookTaskSource;
import com.databricks.sdk.service.jobs.CreateResponse;
import com.databricks.sdk.service.jobs.CreateJob;

import java.util.Scanner;
import java.util.Map;
import java.util.Collection;
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    System.out.println("Some short name for the job (for example, my-job):");
    Scanner in = new Scanner(System.in);
    String jobName = in.nextLine();

    System.out.println("Some short description for the job (for example, My job):");
    String description = in.nextLine();

    System.out.println("ID of the existing cluster in the workspace to run the job on (for example, 1234-567890-ab123cd4):");
    String existingClusterId = in.nextLine();

    System.out.println("Workspace path of the notebook to run (for example, /Users/someone@example.com/my-notebook):");
    String notebookPath = in.nextLine();

    System.out.println("Some key to apply to the job's tasks (for example, my-key): ");
    String taskKey = in.nextLine();

    System.out.println("Attempting to create the job. Please wait...");

    WorkspaceClient w = new WorkspaceClient();

    Map<String, String> map = Map.of("", "");

    Collection<JobTaskSettings> tasks = Arrays.asList(new JobTaskSettings()
      .setDescription(description)
      .setExistingClusterId(existingClusterId)
      .setNotebookTask(new NotebookTask()
        .setBaseParameters(map)
        .setNotebookPath(notebookPath)
        .setSource(NotebookTaskSource.WORKSPACE))
      .setTaskKey(taskKey)
    );

    CreateResponse j = w.jobs().create(new CreateJob()
      .setName(jobName)
      .setTasks(tasks)
    );

    System.out.println("View  the job at " +
      w.config().getHost() +
      "/#job/" +
      j.getJobId()
    );
  }
}

アカウントレベルのグループを一覧表示する

このコード例では、Databricks アカウント内の使用可能なすべてのグループの表示名を一覧表示します。

import com.databricks.sdk.AccountClient;
import com.databricks.sdk.core.DatabricksConfig;
import com.databricks.sdk.service.iam.Group;
import com.databricks.sdk.service.iam.ListAccountGroupsRequest;

public class Main {
  public static void main(String[] args) {
    AccountClient a = new AccountClient();

    for (Group g : a.groups().list((new ListAccountGroupsRequest()))) {
      System.out.println(g.getDisplayName());
    }
  }
}

Databricks SDK for Java で Scala を使用する

Scala プロジェクトは Databricks SDK for Java で使用できます。 開始する前に、開発マシンに次のものが必要です。

  • Databricks 認証 が構成されています。

  • Scala 互換の統合開発環境 (IDE) が推奨されます。 Databricks は 、Scala プラグイン を備えた IntelliJ IDEA を推奨します。これらの手順は、IntelliJ IDEA Community Edition 2023.3.6 でテストされています。 IntelliJ IDEA の異なるバージョンまたはエディションを使用する場合、次の手順は異なる場合があります。

  • Java 8 以上と互換性のある Java 開発キット (JDK)。 Databricks クラスターでアプリケーションを実行したり、ライブラリを使用したりする場合は、クラスター上の JDK バージョンと一致するバージョンの JDK を使用することをお勧めします。 特定の Databricks Runtimeに含まれている JDK バージョンを見つけるには、「 Databricks Runtime リリースノートのバージョンと互換性」を参照してください。 IntelliJ IDEAを使用する場合は、既存のローカルJDKインストールを選択するか、Scalaプロジェクトの作成時に新しいJDKをローカルにインストールできます。

  • Scala ビルドツール。 Databricks では sbtを推奨しています。 IntelliJ IDEAを使用している場合は、Scalaプロジェクトの作成時に使用する sbt バージョンを選択できます。

  • Scala。 Databricks クラスターでアプリケーションを実行したり、ライブラリを使用したりする場合は、クラスター上の Scala バージョンと一致するバージョンの Scala を使用することをお勧めします。 特定の Databricks Runtimeに含まれている Scala のバージョンを確認するには、「 Databricks Runtime リリースノートのバージョンと互換性」を参照してください。 IntelliJ IDEA を使用する場合は、Scala プロジェクトの作成時に使用する Scala のバージョンを選択できます。

Scala プロジェクトを構成、ビルド、実行するには:

  1. プロジェクトの build.sbt ファイルで、ファイルの末尾に次の行を追加して Databricks SDK for Java ライブラリに依存し、ファイルを保存します。

    libraryDependencies += "com.databricks" % "databricks-sdk-java" % "0.2.0"
    

    必ず 0.2.0 最新バージョンの Databricks SDK for Java ライブラリに置き換えてください。 最新バージョンは、 Maven の中央リポジトリで見つけることができます。

  2. 宣言された依存関係を Java 用 Databricks SDK に取得するようにプロジェクトに指示します。 例えば、IntelliJ IDEA では Load sbt 変更 通知アイコン をクリックする。

  3. Databricks SDK for Java をインポートし、 Databricks ワークスペース内のすべてのクラスターを一覧表示するコードを追加します。たとえば、プロジェクトの Main.scala ファイルでは、コードは次のようになります。

    import com.databricks.sdk.WorkspaceClient
    import com.databricks.sdk.service.compute.ListClustersRequest
    
    object Main {
      def main(args: Array[String]): Unit = {
        val w = new WorkspaceClient()
    
        w.clusters().list(new ListClustersRequest()).forEach{
          elem => println(elem.getClusterName)
        }
      }
    }
    

    前の val w = new WorkspaceClient()の呼び出しで引数を設定しないことで、Java 用 Databricks SDK は、既定のプロセスを使用して Databricks 認証を実行しようとします。 このデフォルト動作をオーバーライドするには、次の 認証 セクションを参照してください。

  4. プロジェクトをビルドします。 たとえば、IntelliJ IDEAでこれを行うには、メインメニューから[ビルド] >[プロジェクトのビルド]をクリックします。

  5. メインファイルを実行します。 たとえば、IntelliJ IDEAでプロジェクトの ファイルに対してこれを行うには、メインメニューから[Main.scala 実行]>[メイン ]の実行Scala をクリックします。

  6. クラスターのリストが表示されます。 たとえば、IntelliJ IDEAでは、これは [実行 ]ツールウィンドウにあります。 このツール ウィンドウを表示するには、メイン メニューから [ ツール ウィンドウの表示] > [実行] >をクリックします。

Databricks ユーティリティと Scala を Databricks SDK for Java で使用する

Databricks ユーティリティ には、オブジェクト ストレージの効率的な操作、ノートブックのチェーンとパラメーター化、シークレットの操作を容易にするいくつかのヘルパー関数が用意されています。 Databricks には、Scala ライブラリ用の Databricks ユーティリティが用意されており、 Scala を使用してプログラムで Databricks ユーティリティ にアクセスできます。

Scala の Databricks ユーティリティを呼び出すには、次の手順を実行します。

  1. Scala プロジェクトで、前のセクションで説明したように、Java 用 Databricks SDK への依存関係を宣言します。

  2. Scala ライブラリ用の Databricks ユーティリティへの依存関係を宣言します。 たとえば、プロジェクトの build.sbt ファイルで、ファイルの末尾に次の行を追加し、ファイルを保存します。

    libraryDependencies += "com.databricks" % "databricks-dbutils-scala_2.12" % "0.1.4"
    

    0.1.4 を最新バージョンの Databricks ユーティリティ for Scala ライブラリに置き換えてください。最新バージョンは、 Maven の中央リポジトリで見つけることができます。

  3. 宣言された依存関係を Scala 用 Databricks ユーティリティに使用するようにプロジェクトに指示します。 例えば、IntelliJ IDEAでは、 sbt の変更をロード する通知アイコンをクリックする。

  4. インポートするコードを追加し、Scala の Databricks ユーティリティを呼び出します。 たとえば、次のコードは Unity Catalog ボリュームを自動化します。 この例では、ワークスペース内のボリュームのパスに zzz_hello.txt という名前のファイルを作成し、ファイルからデータを読み取り、ファイルを削除します。

    import com.databricks.sdk.scala.dbutils.DBUtils
    
    object Main {
      def main(args: Array[String]): Unit = {
        val filePath = "/Volumes/main/default/my-volume/zzz_hello.txt"
        val fileData = "Hello, Databricks!"
        val dbutils = DBUtils.getDBUtils()
    
        dbutils.fs.put(
          file = filePath,
          contents = fileData,
          overwrite = true
        )
    
        println(dbutils.fs.head(filePath))
    
        dbutils.fs.rm(filePath)
      }
    }
    

    前の val dbutils = DBUtils.getDBUtils()の呼び出しで引数を設定しないことで、Scala 用 Databricks ユーティリティは、Databricks 認証の実行を試みるために既定のプロセスを使用します。

    このデフォルトの動作をオーバーライドするには、インスタンス化された DatabricksCfg オブジェクトを引数として getDBUtilsに渡します。 詳細については、前の 「認証 」セクションを参照してください。

    ただし、コードが Databricks Runtimeの内部で実行されている場合、このDatabricksCfgオブジェクトは無視されます。 これは、Scala 用 Databricks ユーティリティが、 Databricks Runtime内で実行しているときに組み込みの Databricks ユーティリティに委任するためです。

  5. プロジェクトをビルドし、メインファイルを実行します。

テスティング

コードをテストするには、 JUnitなどの Java テスト フレームワークを使用します。 Databricks REST API エンドポイントを呼び出さずに、または Databricks アカウントやワークスペースの状態を変更せずに、シミュレートされた条件下でコードをテストするには、 Mockitoなどの Java モック ライブラリを使用します。

たとえば、新しいクラスターに関する情報を返すcreateCluster関数を含むHelpers.javaという名前の次のファイルがあるとします。

// Helpers.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Helpers {
  static CreateClusterResponse createCluster(
    WorkspaceClient w,
    CreateCluster   createCluster,
    String          clusterName,
    String          sparkVersion,
    String          nodeTypeId,
    Long            autoTerminationMinutes,
    Long            numWorkers
  ) {
    return w.clusters().create(
      createCluster
        .setClusterName(clusterName)
        .setSparkVersion(sparkVersion)
        .setNodeTypeId(nodeTypeId)
        .setAutoterminationMinutes(autoTerminationMinutes)
        .setNumWorkers(numWorkers)
    ).getResponse();
  }
}

そして、createCluster関数を呼び出すMain.javaという名前の次のファイルがあるとします。

// Main.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Main {
  public static void main(String[] args) {
    WorkspaceClient w = new WorkspaceClient();
    // Replace <spark-version> with the target Spark version string.
    // Replace <node-type-id> with the target node type string.
    CreateClusterResponse c = Helpers.createCluster(
      w,
      new CreateCluster(),
      "My Test Cluster",
      "<spark-version>",
      "<node-type-id>",
      15L,
      1L
    );
    System.out.println(c.getClusterId());
  }
}

次の HelpersTest.java という名前のファイルは、 createCluster 関数が予期される応答を返すかどうかをテストします。 このテストでは、ターゲット ワークスペースにクラスターを作成するのではなく、 WorkspaceClientオブジェクトをモックし、モック オブジェクトの設定を定義して、モック オブジェクトをcreateCluster関数に渡します。 次に、テストでは、関数が新しいモック クラスターの予想される ID を返すかどうかを確認します。

// HelpersTest.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.mixin.ClustersExt;
import com.databricks.sdk.service.compute.ClusterDetails;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.support.Wait;
import com.databricks.sdk.service.compute.CreateClusterResponse;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class HelpersTest {
  @Test
  public void testCreateCluster() {
    WorkspaceClient mockWorkspaceClient = Mockito.mock(WorkspaceClient.class);
    ClustersExt mockClustersExt = Mockito.mock(ClustersExt.class);
    CreateCluster mockCreateCluster = new CreateCluster();
    Wait<ClusterDetails, CreateClusterResponse> mockWait = Mockito.mock(Wait.class);
    CreateClusterResponse mockResponse = Mockito.mock(CreateClusterResponse.class);

    Mockito.when(mockWorkspaceClient.clusters()).thenReturn(mockClustersExt);
    Mockito.when(mockClustersExt.create(Mockito.any(CreateCluster.class))).thenReturn(mockWait);
    Mockito.when(mockWait.getResponse()).thenReturn(mockResponse);

    // Replace <spark-version> with the target Spark version string.
    // Replace <node-type-id> with the target node type string.
    CreateClusterResponse response = Helpers.createCluster(
      mockWorkspaceClient,
      mockCreateCluster,
      "My Test Cluster",
      "<spark-version>",
      "<node-type-id>",
      15L,
      1L
    );
    assertEquals(mockResponse, response);
  }
}

関連リソース

詳細については、以下を参照してください。