Skip to content

Add examples with sgw and server #25

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ Cargo.lock

# MacOS directory conf
.DS_Store

*.cblite2/
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ tempdir = "*"
lazy_static = "1.4.0"
regex = "1.10.4"

[dev-dependencies]
serde_json = "1"

[dev-dependencies.reqwest]
version = "0.12.15"
default-features = false
features = ["blocking", "json"]

[dev-dependencies.cargo-husky]
version = "1"
default-features = false # Disable features which are enabled by default
Expand Down
59 changes: 59 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Running examples with Couchbase Sync Gateway & Server

Couchbase Lite is often used with replication to a central server, so it can be useful to test the full stack.
The examples in this directory aim at covering these use cases.

## Setup the Couchbase Sync Gateway & Server

This process is handled through docker images, with as an entry point the file `docker-conf/docker-compose.yml`.

The configuration files that might interest you are:
- `docker-conf/couchbase-server-dev/configure-server.sh` -> sets up the cluster, bucket and SG user
- `docker-conf/db-config.json` -> contains the database configuration
- `docker-conf/sync-function.js` -> contains the sync function used by the Sync Gateway

To start both the Sync Gatewawy and Couchbase Server, move to `docker-conf` through a terminal and use:

```shell
$ docker-compose up
```

It's very long the first time...

You can then access the Couchbase Server web ui through [http://localhost:8091](http://localhost:8091) (Chrome might not work, Firefox has better support).
Make sure to not have another instance running.

## Update the config after startup

You can change a few things through the `curl` command.

#### Sync function

Update the file `docker-conf/sync-function.js` and run
```shell
$ curl -XPUT -v "http://localhost:4985/my-db/_config/sync" -H 'Content-Type: application/javascript' --data-binary @docker-conf/sync-function.js
```

#### Database config

Update the file `docker-conf/db-config.json` and run

```shell
$ curl -XPUT -v "http://localhost:4985/my-db/" -H 'Content-Type: application/json' --data-binary @docker-conf/db-config.json
```

## Running an example

As of now, there is only one example: `sgw_1_cblite`.

It can be run with the following command:
```shell
$ cargo run --features=enterprise --example sgw_1_cblite
```

What it does:
- Create a cblite database `test1`
- Add a user `great_name` to the Sync Gateway
- Retrieve a session token for the user `great_name` from the Sync Gateway
- Start a continuous push & pull replicator
- Create a document, then wait for 5 seconds for the replication to finish
5 changes: 5 additions & 0 deletions examples/docker-conf/couchbase-server-dev/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# hadolint ignore=DL3007
FROM couchbase/server:enterprise
COPY configure-server.sh /configure-server.sh

ENTRYPOINT ["/configure-server.sh"]
121 changes: 121 additions & 0 deletions examples/docker-conf/couchbase-server-dev/configure-server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env bash

export COUCHBASE_ADMINISTRATOR_USERNAME="cb_admin"
export COUCHBASE_ADMINISTRATOR_PASSWORD="cb_admin_pwd"

export COUCHBASE_BUCKET="my-bucket"

export COUCHBASE_SG_USERNAME="syncgw"
export COUCHBASE_SG_PASSWORD="syncgw-pwd"
export COUCHBASE_SG_NAME="sg-service-user"

function retry() {
for i in $(seq 1 10); do
$1
if [[ $? == 0 ]]; then
return 0
fi
sleep 1
done
return 1
}

function clusterInit() {
couchbase-cli cluster-init \
-c 127.0.0.1:8091 \
--cluster-username $COUCHBASE_ADMINISTRATOR_USERNAME \
--cluster-password $COUCHBASE_ADMINISTRATOR_PASSWORD \
--services data,index,query \
--cluster-ramsize 256 \
--cluster-index-ramsize 256 \
--index-storage-setting default
if [[ $? != 0 ]]; then
return 1
fi
}

function bucketCreate() {
couchbase-cli bucket-create \
-c 127.0.0.1:8091 \
--username $COUCHBASE_ADMINISTRATOR_USERNAME \
--password $COUCHBASE_ADMINISTRATOR_PASSWORD \
--bucket-type=couchbase \
--bucket-ramsize=100 \
--bucket-replica=0 \
--bucket $COUCHBASE_BUCKET \
--wait
if [[ $? != 0 ]]; then
return 1
fi
}

function userSgCreate() {
couchbase-cli user-manage \
-c 127.0.0.1:8091 \
--username $COUCHBASE_ADMINISTRATOR_USERNAME \
--password $COUCHBASE_ADMINISTRATOR_PASSWORD \
--set \
--rbac-username $COUCHBASE_SG_USERNAME \
--rbac-password $COUCHBASE_SG_PASSWORD \
--rbac-name $COUCHBASE_SG_NAME \
--roles bucket_full_access[*],bucket_admin[*] \
--auth-domain local
if [[ $? != 0 ]]; then
return 1
fi
}

function main() {
/entrypoint.sh couchbase-server &
if [[ $? != 0 ]]; then
echo "Couchbase startup failed. Exiting." >&2
exit 1
fi

# wait for service to come up
until $(curl --output /dev/null --silent --head --fail http://localhost:8091); do
sleep 5
done

if couchbase-cli server-list -c 127.0.0.1:8091 --username $COUCHBASE_ADMINISTRATOR_USERNAME --password $COUCHBASE_ADMINISTRATOR_PASSWORD ; then
echo "Couchbase already initialized, skipping initialization"
else
echo "Couchbase is not configured."
echo

echo "Initializing the cluster...."
retry clusterInit
if [[ $? != 0 ]]; then
echo "Cluster init failed. Exiting." >&2
exit 1
fi
echo "Initializing the cluster [OK]"
echo

echo "Creating the bucket...."
retry bucketCreate
if [[ $? != 0 ]]; then
echo "Bucket create failed. Exiting." >&2
exit 1
fi
echo "Creating the bucket [OK]"
echo

echo "Creating Sync Gateway user...."
retry userSgCreate
if [[ $? != 0 ]]; then
echo "User create failed. Exiting." >&2
exit 1
fi
echo "Creating Sync Gateway user [OK]"
echo

sleep 10

fi

wait
}

main

8 changes: 8 additions & 0 deletions examples/docker-conf/db-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"import_docs": true,
"enable_shared_bucket_access": true,
"bucket": "my-bucket",
"num_index_replicas": 0,
"revs_limit": 20,
"allow_conflicts": false
}
47 changes: 47 additions & 0 deletions examples/docker-conf/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
services:
cblr-couchbase-server:
ports:
- "8091:8091" # REST(admin), Web console
- "8093:8093" # Query service REST/HTTP traffic
- "11207:11207" # memcached port (TLS)
- "11210:11210" # memcached port
build:
context: ${PWD}/couchbase-server-dev
deploy:
resources:
limits:
memory: 2048M
restart: on-failure
cblr-sync-gateway:
image: couchbase/sync-gateway:enterprise
ports:
- "4984:4984"
- "4985:4985"
deploy:
resources:
limits:
memory: 512M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4985"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- ${PWD}/syncgw-config.json:/etc/sync_gateway/config.json:ro
- ${PWD}/wait-for-couchbase-server.sh:/wait-for-couchbase-server.sh
depends_on:
- cblr-couchbase-server
entrypoint: ["/wait-for-couchbase-server.sh"]
restart: on-failure
cblr-sync-gateway-setup:
image: alpine:3.21.3@sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c
depends_on:
cblr-sync-gateway:
condition: service_healthy
volumes:
- ${PWD}/sync-function.js:/sync-function.js
- ${PWD}/db-config.json:/db-config.json
- ${PWD}/update.sh:/update.sh
links:
- "cblr-sync-gateway:sg"
entrypoint: /update.sh
19 changes: 19 additions & 0 deletions examples/docker-conf/sync-function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function sync(doc, oldDoc, meta) {
console.log("=== New document revision ===");
console.log("New doc:");
console.log(doc);
console.log("Old doc:");
console.log(oldDoc);
console.log("Metadata:");
console.log(meta);

if(doc.channels) {
channel(doc.channels);
}
if(doc.expiry) {
// Format: "2022-06-23T05:00:00+01:00"
expiry(doc.expiry);
}

console.log("=== Document processed ===");
}
43 changes: 43 additions & 0 deletions examples/docker-conf/syncgw-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"bootstrap": {
"server": "couchbase://cblr-couchbase-server",
"username": "syncgw",
"password": "syncgw-pwd"
},
"api": {
"public_interface": ":4984",
"admin_interface": ":4985",
"admin_interface_authentication": false,
"https": {}
},
"logging": {
"console": {
"rotation": {},
"log_level": "debug",
"log_keys": [
"*"
]
},
"error": {
"rotation": {}
},
"warn": {
"rotation": {}
},
"info": {
"rotation": {}
},
"debug": {
"rotation": {}
},
"trace": {
"rotation": {}
},
"stats": {
"rotation": {}
}
},
"auth": {},
"replicator": {},
"unsupported": {}
}
23 changes: 23 additions & 0 deletions examples/docker-conf/update.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/sh -x

apk add curl

export DB_NAME="my-db"

echo 'START SG Update'
echo

#Can I bypass the config if it's already done? This command does not work:
#curl -I "http://localhost:4985/my-db/" -w "%{http_code}"` --output >(cat >&3)

# Setting up database API: https://docs.couchbase.com/sync-gateway/current/rest_api_admin.html#tag/Database-Management/operation/put_db-
echo 'Setting up the database...'
curl -XPUT -v "http://sg:4985/${DB_NAME}/" -H 'Content-Type: application/json' --data-binary @db-config.json
echo

# Updating sync function API: https://docs.couchbase.com/sync-gateway/current/rest_api_admin.html#tag/Database-Configuration/operation/put_keyspace-_config-sync
# Sync function doc: https://docs.couchbase.com/sync-gateway/current/sync-function.html
echo 'Updating sync function...'
curl -XPUT -v "http://sg:4985/${DB_NAME}/_config/sync" -H 'Content-Type: application/javascript' --data-binary @sync-function.js

echo 'END SG Update'
17 changes: 17 additions & 0 deletions examples/docker-conf/wait-for-couchbase-server.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

echo "Launch SG"
SG_CONFIG_PATH=/etc/sync_gateway/config.json

COUCHBASE_SERVER_URL="http://cblr-couchbase-server:8091"
SG_AUTH_ARG="syncgw:syncgw-pwd"

while ! { curl -X GET -u $SG_AUTH_ARG $COUCHBASE_SERVER_URL/pools/default/buckets -H "accept: application/json" -s | grep -q '"status":"healthy"'; }; do
echo "Wait 🕑"
sleep 1
done
echo "CB ready, starting SG"

sleep 5

/entrypoint.sh -bootstrap.use_tls_server=false $SG_CONFIG_PATH
Loading
Loading