新しい Cosmos Emulator を Java から使ってみる
新しい Cosmos Emulator がリリースされました。このエミュレータは、Linux ベースのエミュレータは Docker イメージとして提供されてます。
Linux ベースのエミュレータ (プレビュー) - Azure Cosmos DB for NoSQL | Microsoft Learn
現時点でプレビューなのですが、提供されている機能がいままでのエミュレータに比べて少なく、現時点ではすべての機能が使えるわけではありません。
起動方法
Java から使う場合は、 https
が必須なので、デフォルトで起動する http
ではなく、 https
で起動する必要があります。--protocol https
オプションを指定しましょう。
docker run --detach --publish 8081:8081 --publish 1234:1234 mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview --protocol https
起動後、 http://localhost:1234/ にアクセスしていつもの Cosmos Explorer 画面が表示されれば成功です。
docker compose で起動したい場合は、以下のように docker-compose.yml
を作成しましょう。データを永続化したい場合は、data
をローカルにマウントしておけばOKそうです。
version: '3.8'
services:
cosmos:
image: mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:vnext-preview
ports:
- "8081:8081"
- "1234:1234"
environment:
- PROTOCOL=https
volumes:
- ./cosmos-data:/data
証明書の登録
Java の面倒なところは、証明書を登録しないと SDK が動かないところです。以下のコマンドで証明書を登録しましょう。
openssl
と sed
を使う必要があるって面倒なですが、sed
は特定の文字列を抽出するために使っているだけなので、最悪 openssl
の出力を手動で切った張ったすれば問題ないです。
openssl s_client -connect localhost:8081 </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > cosmos.cert
以下が抜き出した物ですが、今のところ不変のようです。コンテナ削除しても同じです。以前のエミュータは毎度生成されなおして難儀した覚えがあります。
-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUAUMCOUUjCpZdDek8wMd51nhBezkwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI1MDEyODA3MTgwNFoXDTM1MDEy
NjA3MTgwNFowFDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEAmH5YJP1fnv1P2EDq5xAQisyWZjfSICA/7sGvaM53T5Ee
YAJ2irYRWVGy6YB8OTUMcFnCKZzr/br5CB64giU/oZb4XCJcNPf6CUR99xYD9dEC
S8lQuy415tp7fn4uf4T5+DHYlXTrnN+m0C7qJ3B4l9OGaTQds4MrA62Sq0/FAZxA
mRSQ00y8rKVLDcRRyFoVpJTK8HIYHcXdP4OainBvrJc1ozFz0Jvq+rqKAsLPXmIK
JIu/34ms6RxHPPvwmz9egrpsqD9RNaVEUVHfBqg2jxsGH2ir4VccEwexYDp9AgKC
fk4yqe/A5XfCLS9C2OKV84+y6FMIt3a86c/UmVwChJippEpOCvn58zzHoswIKJ8S
t+uWeISTBXWRmTgMsInXNhJ7Zc7Z/gWsm1rhfWXdNH0FVPN0wJzWrxwqX9pfDgcr
402X4Seh7s8VBAc0LiVgGmTjtfpoO2J3jdqWX7ahkXMKI/TyWLJ1wE7NR/JzeWN6
AFQnodVTYRznOEeKuiX1b9hRm7PQ4kNKdOkncM91DsCfgyccpS+ci7VVejUwg2Tm
XrMwEUl7ftCzOUz4S9M8JrXlue2BzPLsQCsRpNLqR274ApbC9ye+tbig535tQBvo
JOWBXsY61msDkQL+k3DI6h84CoNN0AP0AtW1Gq3E+6h96q+RzU8M56WydPvUGLsC
AwEAAaNTMFEwHQYDVR0OBBYEFGBG+CdD4YurEzLlDC7koIEhM3qaMB8GA1UdIwQY
MBaAFGBG+CdD4YurEzLlDC7koIEhM3qaMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBAHGS7slctG3lGzA3r/v53a2F+d/R60ttfTVIywwfiIhmhbJE
5BwldBfBHa5bCj3w7VoXIN8rRuDN6XNGLAML4pBfHMKz9lHc7zT2c4zNQMGIgNUK
fjZmdhrAZFySuclc2cjHnBinEhIeCaSBZkOSlQ/AtirHi73ML1u/4X5QsJJbLkJ7
CUVQKJDqLF3WQKnxcAIDTXqB6puahwzYJKXTOYUlw3aqqeduwmtkANdk9P0WtxFJ
6bBJ4ANzrsZci5zbUy5e0FjMFswS62RBlK782vBRQxAsckGLqG9118RnsugDexAB
LyPy5ulbGpq5Il0c5w32vC+qCa6mQjK7PB+VTEWHaZLsiuh/MQHI3AmDGiMls+vj
zvjDIVaW/vNPKt7NzZ2sCqFWcVl6ERMjO+B3f+FVwSA2r3B89oHbtyuFpGir2Nyy
aaDhXdLexB9Z/BMGfCaBcP0WqAYbsc5ewwCD/Ekb8RyK+KxiddZkWc2fDeFZPbaS
fufefuQ4kZRCDHx9SxoP28aSMY1GxMVasVTj5guiYteFveDZ5EEziKLO8qky/jXZ
zqnlNSVUocwnTB7vH/ZBjrv16LVj1f9rHPtptypuT55cNUoEFf2vEh0dATBJsFjV
9svVSl6oY/nHFS3zSkgAQr/bmCvCyte4ZPQZqBCgrWhT7kIZ4DLi0iEAsVfA
-----END CERTIFICATE-----
keytool
で証明書を登録しましょう。キーストアのパスワードは、だいたいデフォルトの changeit
になっているでしょう。場合によっては管理者権限が必要かもしれません。
keytool -cacerts -importcert -alias cosmos_emulator -file cosmos.cert
因みに削除は以下。
keytool -cacerts -delete -alias cosmos_emulator
Java から使う
pom.xml
に SDK の依存を追加しましょう。BOM使うとバージョンが揃って便利です。
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/boms/azure-sdk-bom/README.md -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>1.2.30</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
ざっと以下のようなテストコードを作成して、作成と読み込みができることを確認します。DBとコンテナは手動で作っておきます。
@Test
public void createAndRead() {
CosmosClient client = new CosmosClientBuilder()
.endpoint("https://localhost:8081/")
.key("C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==")
.buildClient();
CosmosContainer container = client.getDatabase("testdb").getContainer("container");
var item = new Person();
item.setId("1");
item.setName("John");
item.setAge(30);
// 作成
container.createItem(item);
// 読み込み
var readItem = container.readItem("1", new PartitionKey("1"), Person.class);
System.out.println(readItem.getItem());
client.close();
}
実行すると、単純な作成と読み込みができませし、未実装ってなんやねん。普通にWindows版のエミュレータでは何の問題もなく動きます。
{
"innerErrorMessage": "System.NotImplementedException: Have not implemented Read on Address. ..."
}
未実装にも程があるやろと、色々調べまわったのですが、結局は ゲートウェイモード にしてなかったというオチでした。クライアントを作成するときに .gatewayMode()
を差し込んでおきましょう。
まとめ
新しい docker ベース の cosmos は起動も速く使い勝ってもよさそうですが、いかんせんサポートされている機能が少なすぎる気がします。もうすこしのアップデートに期待でしょうか。
Issueなどはここを見ればわかります。