【2019 年 11 月版】 使用 Quarkus + Panache 探索将 CosmosDB 作为 MongoDB 的新方法
在Quarkus的Panache-Mongo中,简单入门CosmosDB。
这次我想使用 Azure 的分布式多模型数据库 CosmosDB 作为数据库,结合常用的 Quarkus + Panache 来构建一个简单的 REST API。
由于 CosmosDB 是”多模型”数据库,所以可以通过多种接口进行访问。(在创建实例时可以选择使用哪种模型,并且创建后访问只能在该模型下进行,因此不能同时从多个模型的API访问同一个实例)。
让我们尝试一下之前没有做过的 Panache 的 MongoDB 兼容功能。
创造 CosmosDB 实例
请确保在创建 CosmosDB 资源时将 API 设置为“MongoDB”。
2. 创建Quarkus项目
首先,请参考以下官方指南,创建MongoDB+Panache与Quarkus的项目。
- QUARKUS – SIMPLIFIED MONGODB WITH PANACHE
我将执行以下的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已经发布了但是…)
接下来,将刚刚保存的 CosmosDB 连接字符串作为 MongoDB 的连接地址添加到 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”。
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
我将制作一个只有POST和GET的简单API。
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的对象也设置为ObjectId类型。剩下的由Rest Easy和Panache处理。顺便提一下,目前的mongodb-panache插件似乎不支持事务处理。
在开发服务器上进行确认
让我们在开发服务器上完成实施后,暂时进行操作确认。
使用以下命令启动开发服务器。
$ mvn quarkus:dev
首先,在启动完成后,我们先试着通过终端使用curl命令进行POST JSON数据。
$ 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"}
我们从浏览器也可以尝试访问 http://localhost:8080/person/5ddfb90c682fc42ef21e666f!
是的,虽然这是JSON格式的,没有任何花哨的装饰,但5ddfb90c682fc42ef21e666f已经获取到了!
6. 本地化
我試著挑戰成為母語使用者!
在连接到 CosmosDB 时,由于 SSL 是必需的,因此请参考以下页面进行 SSL 支持的本地构建。
- QUARKUS – USING SSL WITH NATIVE EXECUTABLES # Working with containers
只需将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-libs目录下复制了GraalVM中的cacerts和sunec静态库,并将其添加到可执行镜像中以便引用。
接下来,我们将创建一个参考此文件的 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 。
我們也可以從 CosmosDB 的資料探索器中進行確認。
好耶,我们确认生成了第二份文件!辛苦啦!
总结
虽然有点仓促,但我们通过Panache经MongoDB客户端成功地实现了数据在CosmosDB的读写操作。同时,我们也确认了即使是通过本地构建的二进制文件,也可以正常地通过SSL连接到CosmosDB!虽然我们非常迫不及待地想要尝试在Azure容器上部署,但今天就到这里吧。
我已将本次的成果物上传至以下存储库,请参考。
- quarkus-examples branch panache-mongo-cosmos