Javaガイド
Java連携は、小さなlauncherとJUnit 5 extensionで構成されます。Go製サーバーを子プロセスとして起動し、Docker内にJVMを立てる方式ではありません。テストクラス全体でseed済みbaseを再利用しつつ、各テストメソッドには専用のforkを渡せます。
インストール
Section titled “インストール”テストを実行するマシンに合ったbinary classifierを選びます。以下はCIをLinux amd64とした例です。環境に応じてdarwin-arm64、linux-arm64、windows-amd64、windows-arm64に置き換えてください。公式opensearch-javaクライアントはApache HttpClient 5 transportを使います。
dependencies { testImplementation("io.github.shibukawa.osmem:osmem:0.1.0") testImplementation("io.github.shibukawa.osmem:osmem-server-binaries:0.1.0:linux-amd64") testImplementation("org.opensearch.client:opensearch-java:2.19.0") testImplementation("org.apache.httpcomponents.client5:httpclient5:5.2.1") testImplementation("org.junit.jupiter:junit-jupiter:5.11.4")}dependencies { testImplementation("io.github.shibukawa.osmem:osmem:0.1.0") testImplementation("io.github.shibukawa.osmem:osmem-server-binaries:0.1.0:linux-amd64") testImplementation("org.opensearch.client:opensearch-java:2.19.0") testImplementation("org.apache.httpcomponents.client5:httpclient5:5.2.1") testImplementation("org.junit.jupiter:junit-jupiter:5.11.4")}<dependencies> <dependency> <groupId>io.github.shibukawa.osmem</groupId> <artifactId>osmem</artifactId> <version>0.1.0</version> <scope>test</scope> </dependency> <dependency> <groupId>io.github.shibukawa.osmem</groupId> <artifactId>osmem-server-binaries</artifactId> <version>0.1.0</version> <classifier>linux-amd64</classifier> <scope>test</scope> </dependency> <dependency> <groupId>org.opensearch.client</groupId> <artifactId>opensearch-java</artifactId> <version>2.19.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.11.4</version> <scope>test</scope> </dependency></dependencies>classifierはテスト実行ホストに合わせます。開発機とCIでOSが異なる場合、両方のplatform artifactを依存関係に含めます。ローカルビルドを使うならOSMEM_SERVER_BINまたはosmem.server.bin system propertyでbinaryを指定できます。
例のcoordinatesは0.1.0です。今後のosmem package releaseは1.<OpenSearchメジャー>.<osmemのrelease番号>(現在予定している系列は1.9.y)にする予定です。Maven Centralで実際に公開されているversionを指定してください。これはopensearch-java clientのversionとは独立しています。
例では、このosmemリリースのサーバーAPIに合わせてOpenSearch Java clientを2.19.0に固定しています。client versionを変更する場合は公式Java clientガイドを確認してください。
起動し、schemaとseed dataを登録して検索する
Section titled “起動し、schemaとseed dataを登録して検索する”単発の連携確認やJUnit以外のframeworkでは、serverを直接管理します。準備には通常のREST APIを使い、検索は公式クライアントから送ります。
import org.apache.hc.core5.http.HttpHost;import java.nio.file.Path;import org.opensearch.client.opensearch.OpenSearchClient;import org.opensearch.client.transport.OpenSearchTransport;import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;import io.github.shibukawa.osmem.OsmemServer;
try (OsmemServer server = OsmemServer.builder().japanese(false).start()) { server.request("PUT", "/products", "{\"mappings\":{\"properties\":{\"name\":{\"type\":\"text\",\"fields\":{\"keyword\":{\"type\":\"keyword\"}}}}}}}"); server.request("PUT", "/products/_doc/1", "{\"name\":\"Red Apple\"}");
try (OpenSearchTransport transport = ApacheHttpClient5TransportBuilder .builder(HttpHost.create(server.url())).build()) { OpenSearchClient client = new OpenSearchClient(transport); var result = client.search(s -> s.index("products") .query(q -> q.match(m -> m.field("name").query("apple"))), java.util.Map.class); System.out.println(result.hits().hits()); }}fixtureを繰り返し使う場合、mappingとdocumentは共通のseed directoryに置き、OsmemServer.builder().seed(Path.of("src/test/resources/seed"))に渡せます。
baseを再利用し、書き換えるテストはforkする
Section titled “baseを再利用し、書き換えるテストはforkする”OsmemExtensionはテストクラスの前にserverを1つ起動し、seedを投入してbaseを凍結します。その後、各テストメソッドの前後で専用cloneを作成・破棄します。
@RegisterExtensionstatic OsmemExtension osmem = OsmemExtension.seed(Path.of("src/test/resources/seed"));
@Testvoid addsAProduct(OsmemClone clone) { OpenSearchClient client = clientFor(clone.url()); client.index(i -> i.index("products").id("x").document(Map.of("name", "new"))); assertTrue(client.get(g -> g.index("products").id("x"), Map.class).found());}documentの書き込み、mappingの変更、indexの作成・削除など、indexの状態を変えるテストではOsmemCloneを使います。読み取り専用テストはOsmemServerを受け取り、baseを検索できます。この構成なら初期化はクラス単位で共有しつつ、変更するテストごとにforkを分けられます。cloneは変更していないデータをbaseと共有し、最初のwrite時に対象indexを複製します。cloneを閉じれば変更は破棄されます。
schemaや起動optionが異なる場合に限り、テスト内で新しいOsmemServerを作ります。読み取り専用テストはメソッド引数にOsmemCloneの代わりにOsmemServerを宣言し、baseを検索できます。書き換え可能なcloneをテストメソッド間で共有しないでください。
毎回まったく新しいserverが必要なら、try-with-resourcesでテスト自身が所有します。
@Testvoid isolatedSetup() { try (OsmemServer server = OsmemServer.builder() .seed(Path.of("src/test/resources/seed")).start()) { OpenSearchClient client = clientFor(server.url()); // test専用schemaを登録するか、読み取り処理を検証する }}clientForはclone URLを受け取る通常のOpenSearch client setupです。
static OpenSearchClient clientFor(String url) { var transport = ApacheHttpClient5TransportBuilder.builder(HttpHost.create(url)).build(); return new OpenSearchClient(transport);}不要になったらtransportを閉じてください。JUnit以外でもOsmemServerとOsmemCloneはAutoCloseableとして使えます。
その他のテストframework
Section titled “その他のテストframework”OsmemServerとOsmemCloneはAutoCloseableです。JUnit以外ではtry-with-resourcesで囲み、書き込み用のforkにはserver.clone()を使い、任意のHTTP clientをclone.url()へ接続します。
binaryの取得順
Section titled “binaryの取得順”launcherは、まずosmem.server.bin system property、次にOSMEM_SERVER_BIN、最後にclasspath上の一致するosmem-server-binaries classifierを探します。classifier内のbinaryは初回起動時にtemporary directoryへ展開されます。標準入力が閉じたとき、親JVMが終了したとき、またはclose()時にserver processも終了します。