LoginSignup
2
0

More than 3 years have passed since last update.

【2019年11月版】Quarkus + Panache で CosmosDB as MongoDB に入門

Last updated at Posted at 2019-11-28

Quarkus の Panache-Mongo で簡単 CosmosDB 入門

今回は Azure の分散マルチモデルDBの CosmosDB をDBとして、いつもの Quarkus + Panache で簡単 REST API を構築してみたいとおもいます。
CosmosDB は"マルチモデル"なので様々なインタフェースを経由してアクセスが可能です。(インスタンス作成時にどのモデルを使用するか選択があり、作成後はそのモデルでのアクセスとなるので、一つのインスタンスに対して同時に複数のモデルのAPIからアクセスできるわけではないです)。
これまでやってこなかったPanacheのMongoDB対応の機能を使ってみましょう。

1. CosmosDB のインスタンス作成

まずは Azure のポータルからCosmosDBのリソースを作成しましょう。
リストの中から "CosmosDB" を選択します。なければ cosmos などで検索です。
新規リソース - Microsoft Azure.png
見つからなければ"検索" というのがどうも、ねぇ。。。

続いて CosmosDB のリソース作成時にAPIを"MongoDB"にするのを忘れないでください。

Azure Cosmos DB アカウントの作成 - Microsoft Azure.png

インスタンス作成後、接続文字列をコピーして控えておきます。
CosmosDB 接続文字列 - Microsoft Azure.png

2. Quarkus プロジェクトの作成

まずは以下の公式ガイドを参考に、MongoDB+Panache のQuarkusプロジェクトを作成いたします。

以下の maven コマンドを叩きます。

$ mvn io.quarkus:quarkus-maven-plugin:1.0.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=mongodb-panache-quickstart \
    -DclassName="org.acme.mongodb.panache.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-jsonb,mongodb-panache"
...
$ cd mongodb-panache-quickstart

いつもの通り・・・って!!! quarkus-maven-plugin:1.0.0.Final ですよ!ついに正式版きましたー!!!(今、githubのリポジトリ確認したら 1.0.1.Final出てましたが・・・)

続いて MongoDB の接続先として先ほど控えておいた CosmosDB の接続文字列を application.properties に追記します。

mongodb-panache-quickstart/src/main/resources/application.properties
# configure the MongoDB client for a replica set of two nodes
quarkus.mongodb.connection-string = mongodb://.............
# mandatory if you don't specify the name of the database using @MongoEntity
quarkus.mongodb.database = person

3. Entityクラスの作成

いつものように Person エンティティを作成します。今回は PanacheMongoEntity をベースクラスにします。
またクラスのアノテーションで保存先のコレクションを"ThePerson"としています。

src/main/java/org/acme/mongodb/panache/model/Person.java
package org.acme.mongodb.panache.model;

import java.time.LocalDate;

import org.bson.codecs.pojo.annotations.BsonProperty;

import io.quarkus.mongodb.panache.MongoEntity;
import io.quarkus.mongodb.panache.PanacheMongoEntity;

@MongoEntity(collection="ThePerson")
public class Person extends PanacheMongoEntity {
    public enum Status {
        Alive, DECEASED
    }
    public String name;

    // will be persisted as a 'birth' field in MongoDB
    @BsonProperty("birth")
    public LocalDate birthDate;

    public Status status;
}

@BsonPropertyアノテーションによりbirthDateフィールドのBSONでのキーをbirthとしています。
続いて REST API の実装に参りましょう。

4. REST API の実装

以下のようにシンプルに POSTGETだけのAPIを作成いたします。

src/main/java/org/acme/mongodb/panache/PersonResource.java
package org.acme.mongodb.panache;

import javax.transaction.Transactional;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.acme.mongodb.panache.model.Person;
import org.bson.types.ObjectId;

@Path("/person")
@Produces(MediaType.APPLICATION_JSON)
public class PersonResource {

    @POST
    public Person create(Person person) {
        person.persist();
        return person;
    }

    @GET
    @Path("/{id}")
    public Person get(@PathParam("id") ObjectId id) {
        return Person.findById(id);
    }
}

ほとんどHibernateの時と同じですが、一点だけ注意があります。PanacheMongoEntityはIDをorg.bson.types.ObjectId 型としています。
よって findByIdに渡すObjectもObjectIdとしてください。
あとはRest EasyとPanacheが宜しくやってくれます。
ちなみに、現時点での mongodb-panache プラグインはトランザクションは未サポートの模様です。

5. 開発サーバーでの確認

実装が完了したところで一旦、開発サーバーで動作確認をしてみましょう。
以下のコマンドで開発サーバーを起動します。

$ mvn quarkus:dev

起動が完了したところで、まずはターミナルからcurlコマンドにてJSONデータをPOSTしてみます。

$ curl -H 'Content-Type:application/json' -d '{"name":"Alice","birth":"2010-10-11","status":"Alive"}' http://localhost:8080/person
{"id":"5ddfb90c682fc42ef21e666f","name":"Alice","status":"Alive"}

はい、idにランダム?な文字列が入ったレコードが返ってきました。これはちゃんと登録されていそうですね。
Azureポータルの管理画面、データエクスプローラーを開いてみましょう。
CosmosDB - データ エクスプローラー.png
無事に5ddfb90c682fc42ef21e666fObjectId のデータが確認できました!ちゃんと入っているようです!

ブラウザからも http://localhost:8080/person/5ddfb90c682fc42ef21e666fを叩いてみましょう!

localhost 8080 person 5ddfb90c682fc42ef21e666f.png

はい、JSONなので飾り気なしですが、5ddfb90c682fc42ef21e666f、取れましたね!

6. ネイティブ化

ネイティブ化にも挑戦してみます!

CosmosDB への接続には SSL が必須ですので以下のページを参考に、SSL対応版ネイティブビルドを行います。

と言っても Dockerfile を以下のようにするだけです。

Dockerfile
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/centos-quarkus-maven:19.2.1 AS build
RUN mkdir -p /tmp/ssl-libs/lib \
  && cp /opt/graalvm/jre/lib/security/cacerts /tmp/ssl-libs \
  && cp /opt/graalvm/jre/lib/amd64/libsunec.so /tmp/ssl-libs/lib/
COPY mongodb-panache-quickstart/src /usr/src/app/src
COPY mongodb-panache-quickstart/pom.xml /usr/src/app
USER root
RUN chown -R quarkus /usr/src/app
USER quarkus
RUN mvn -f /usr/src/app/pom.xml -Pnative -Dmaven.test.skip=true clean package

## Stage 2 : create the docker final image
FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY --from=build /usr/src/app/target/*-runner /work/application
COPY --from=build /tmp/ssl-libs/ /work/
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0", "-Djava.library.path=/work/lib", "-Djavax.net.ssl.trustStore=/work/cacerts"]

ページのサンプルそのままですが /tmp/ssl-libsgraalvm から cacertssunecのスタティックライブラリをコピーして、実行用イメージにてそれらを参照するように追加を行いました。

続いて、これを参照する docker-compose.ymlを作成します。

docker-compose.yml
version : "3"
services:
  quarkus:
    build:
      context: .
    ports:
      - 8080:8080

で、ビルドを行います。

$ docker-compose build

7. ネイティブの動作確認

早速、起動してみましょう。

$ docker-compose up -d

で、いつもの通りcurl でPOST します。

$ $ curl -H 'Content-Type:application/json' -d '{"name":"Alice","birth":"2010-10-11","status":"Alive"}' http://localhost:8080/person
{"id":"5ddfc8c96b679d01d9bc40c0","name":"Alice","status":"Alive"}

先ほどと違うIDでちゃんと返ってきました!

ブラウザで http://localhost:8080/person/5ddfc8c96b679d01d9bc40c0 を叩いてみます。

localhost 8080 person 5ddfc8c96b679d01d9bc40c0.png
はい、ちゃんと動いてますね。

CosmosDBのデータエクスプローラーからも確認してみます。

Cosmos- データ エクスプローラー2.png

2つ目のドキュメントが生成されていることが確認できましたね!
お疲れ様でした!

まとめ

駆け足でしたが Panache から MongoDB Clientを経由して CosmosDB にデータの読み書きができることが確認できました。
また、ネイティブビルドしたバイナリからでもちゃんと CosmosDB にSSL接続できることが確認できました!
早々にAzureContainerでもデプロイしてみたいですが本日はここまでといたします。

今回の成果物は以下のリポジトリにあげました。ご参考にどうぞ。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0