couchbase+sync gateway
https://blog.couchbase.com/get-set-to-the-edge-with-sync-gateway/
couchbase-document
https://docs.couchbase.com/home/index.html
SyncGateway+CouchBase整体架构
安装CouchBase
安装SyncGateway
1、安装SyncGateway参考:
https://docs.couchbase.com/sync-gateway/current/start/gs-sgw-install.html
默认安装windows service,service启动命令如下:
D:\programs\CouchBase\SyncGateway-community-2.8.0\sg-windows.exe start
"D:\programs\CouchBase\SyncGateway-community-2.8.0\sync_gateway.exe"
"D:\programs\CouchBase\SyncGateway-community-2.8.0\serviceconfig.json"
"D:\programs\CouchBase\SyncGateway-community-2.8.0\var\lib\couchbase\logs\sync_gateway_error.log"
2、需要先在Couchbase中为SyncGateway配置bucket和RBAC,
参考:https://docs.couchbase.com/sync-gateway/current/start/gs-sgw-prereqs.html
例如创建
bucket: getting-started-bucket
user: sync-gateway
3、关于配置文件,参考:
https://docs.couchbase.com/sync-gateway/current/refer/config-properties.html
{
"adminInterface": "127.0.0.1:4985",
"interface": "0.0.0.0:4984",
"databases": {
"db": {
"server": "couchbase://localhost",
"username": "sync_gateway",
"password": "password",
"bucket": "getting-started-bucket",
"users": {
"GUEST": {
"disabled": false, "admin_channels": ["*"] } },
"allow_conflicts": false,
"revs_limit": 20,
"num_index_replicas": 0
}
}
}
4、亦可以通过command启动,参考:
https://docs.couchbase.com/sync-gateway/current/command-line-options.html
sync_gateway [command-line options]
sync_gateway ~/path/to/sync-gateway-config.json
Data Modelling
属性命名
用户属性名不能已下划线_开头(_开头属性为系统保留关键字,如id, _rev)
文档结构
Key - 默认UUID或用户指定(无空格)UTF-8字符串、唯一、<=250 bytes、不可改变
Value - 文档JSON、二进制对象(blob或附件)
文档属性
id - 文档ID
rev - A current revision ID (which changes every time the document is updated)
history rev IDs - A history of past revision IDs (usually linear, but will form a branching tree if the document has or has had conflicts)
body - A body in the form of a JSON object, i.e. a set of key/value pairs
binary - Zero or more named binary attachments
概念
用户
支持restfulApi添加用户、配置文件硬编码、OpenId认证、三方认证
注:
SyncGw中user和role与Couchbase中的RBAC (Role-base Access Control) users没有关系,二者相互独立。
restfulApi添加用户
# 其中mydatabase为配置文件中的database name
curl -vX POST "http://localhost:4985/mydatabase/_user/"
-H "accept: application/json"
-H "Content-Type: application/json"
-d '{"name": "john", "password": "pass"}'
配置文件硬编码
{
"databases": {
"mydatabase": {
"users": {
"GUEST": {
"disabled": true},
"john": {
"password": "pass"}
}
}
}
}
角色 - 命名的channels集合
访问角色respApi :/{db}/_role/{name}
角色属性:name, admin_channels, all_channels.
restfulApi通过admin_roles array属性给用户添加角色
curl -vX POST "http://localhost:4985/mydatabase/_user/"
-H "accept: application/json"
-H "Content-Type: application/json"
-d '{"name": "john", "password": "pass", "admin_roles": ["foo"]}'
配置文件给用户添加角色
{
"databases": {
"mydatabase": {
"users": {
"GUEST": {
"disabled": true},
"john": {
"password": "pass", "admin_roles": ["foo"]}
}
}
}
}
channels
Channels are the intermediaries between documents and users.
Every document in the database belongs to a set of channels,
and every user is allowed to access a set of channels.
channels作为document和user的中介者,document需要属于一组channels,且每个用户都被允许访问一组channels。
You typically will use channels to(典型应用场景):
Partition the data set - 划分数据集
Authorize users to access documents - 用于user和document的访问控制(鉴权)
Minimize the amount of data synced down to devices - 根据channel范围最小化同步到设备的数据量
public channel - !
广播channel,添加到该! channel上的文档对所有用户均可见
star channel - *
一个包含当前database下所有文档的channel
Tombstones
墓碑 - 被删除的item被持久化为墓碑
SyncGateway创建tombstones,用于确保所有同步的设备间可以识别出之前存在的记录已被删除,适用于无法连续在线、无法准确定期同步的情况
tombstone文档组成:
the (deleted) document ID
a revision ID
a key value pair deleted:true.
{
"_deleted": true,
"_id": "foobar",
"_rev": "3-db962c6d93c3f1720cc7d3b6e50ac9df"
}
Security
1、Anonymous Access
$ curl -X PUT localhost:4985/$DB/_user/GUEST
--data '{"disabled":false, "admin_channels":["*"]}'
2、Basic Authentication
根据username、password鉴权,
需要先通过admin api向syncGw添加用户(需要将用户同步到syncGw)
Java代码示例(根据username、password鉴权)
URLEndpoint target = new URLEndpoint(new URI("ws://localhost:4984/mydatabase"));
ReplicatorConfiguration config = new ReplicatorConfiguration(database, target);
config.setAuthenticator(new BasicAuthenticator("username", "password"));
// Create replicator (be sure to hold a reference somewhere that will prevent the Replicator from being GCed)
replicator = new Replicator(config);
replicator.start();
3、Auth Providers
Sync Gateway provides a turn-key solution to authenticate with Facebook or Google
4、Custom Authentication
Java代码示例(根据sessionId鉴权)
URLEndpoint target = new URLEndpoint(new URI("ws://localhost:4984/mydatabase"));
ReplicatorConfiguration config = new ReplicatorConfiguration(database, target);
config.setAuthenticator(new SessionAuthenticator("904ac010862f37c8dd99015a33ab5a3565fd8447"));
// Create replicator (be sure to hold a reference somewhere that will prevent the Replicator from being GCed)
replicator = new Replicator(config);
replicator.start();
5、OpenID Connect
参考:https://docs.couchbase.com/tutorials/openid-connect-implicit-flow/index.htm
syncgateway配置
{
"interface":":4984",
"log": ["*"],
"logging": {
...
},
"databases": {
"french_cuisine": {
"bucket_op_timeout_ms": 5000,
"server": "http://cb-server:8091",
"bucket": "french_cuisine",
"username": "SG_Account",
"password": "password",
"enable_shared_bucket_access": true,
"import_docs": true,
"num_index_replicas": 0,
"roles": {
"Bretagne_region_role": {
"admin_channels": [ "Bretagne_region" ]
},
"Alsace_region_role": {
"admin_channels": [ "Alsace_region" ]
},
"PACA_region_role": {
"admin_channels": [ "PACA_region" ]
},
"France_role": {
"admin_channels": [ "Bretagne_region", "Alsace_region", "PACA_region" ]
}
},
"users":{
"admin": {
"password": "password", "admin_channels": ["*"]}
},
"allow_conflicts": true,
"revs_limit": 20,
"oidc": {
"providers": {
"keycloakimplicit": {
//The OpenID Connect Service Provider issuer (Keycloak URL endpoint).
"issuer":"http://keycloak:8080/auth/realms/couchbase",
//在之前keyclock中定义的client_id
"client_id":"SyncGatewayFrenchCuisine",
//Allow any successful logged-in user in KC to automatically create the equivalent user inside Sync Gateway.
//Note: define users inside the Sync Gateway does not automatically grant access to any channel
"register": true
}
}
},
"sync": `function (doc, oldDoc) {
console.log("ENTERING sync function...");
if (doc.channels) {
console.log("doc.channels = " + doc.channels);
channel(doc.channels);
}
console.log("QUITING sync function.");
}`
}
}
}