couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject [1/2] couchdb-nmo git commit: Replication
Date Mon, 16 Nov 2015 12:06:53 GMT
Repository: couchdb-nmo
Updated Branches:
  refs/heads/replicate [created] 89c18c069


Replication

This adds `replicate-from` and `replicate-to`. Replication to and from a
cluster to another CouchDB instance.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/commit/034554b8
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/tree/034554b8
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/diff/034554b8

Branch: refs/heads/replicate
Commit: 034554b824c56fb29f24d3bec3d304271aec9f1d
Parents: f29ee61
Author: Garren Smith <garren.smith@gmail.com>
Authored: Mon Oct 26 16:03:43 2015 +0200
Committer: Garren Smith <garren.smith@gmail.com>
Committed: Mon Nov 16 14:06:06 2015 +0200

----------------------------------------------------------------------
 doc/api/nmo-replicate-from.md | 11 +++++
 doc/api/replicate-to.md       | 11 +++++
 doc/cli/nmo-replicate-from.md | 24 ++++++++++
 doc/cli/replicate-to.md       | 24 ++++++++++
 src/nmo.js                    |  4 +-
 src/replicate-from.js         | 49 ++++++++++++++++++++
 src/replicate-to.js           | 49 ++++++++++++++++++++
 src/replicate.js              | 21 +++++++++
 test/replicate-from.js        | 91 ++++++++++++++++++++++++++++++++++++++
 test/replicate-to.js          | 91 ++++++++++++++++++++++++++++++++++++++
 test/replicate.js             | 74 +++++++++++++++++++++++++++++++
 11 files changed, 448 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/doc/api/nmo-replicate-from.md
----------------------------------------------------------------------
diff --git a/doc/api/nmo-replicate-from.md b/doc/api/nmo-replicate-from.md
new file mode 100644
index 0000000..f4fc7eb
--- /dev/null
+++ b/doc/api/nmo-replicate-from.md
@@ -0,0 +1,11 @@
+nmo-replicateFrom(3) -- replicate-from
+==============================
+
+## SYNOPSIS
+
+    nmo.commands.replicateFrom([<clusterurl> || <cluster>], database, url)
+
+
+## DESCRIPTION
+
+Replicate the database from the supplied cluster or cluster url to the given url.

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/doc/api/replicate-to.md
----------------------------------------------------------------------
diff --git a/doc/api/replicate-to.md b/doc/api/replicate-to.md
new file mode 100644
index 0000000..248ad14
--- /dev/null
+++ b/doc/api/replicate-to.md
@@ -0,0 +1,11 @@
+nmo-replicateTo(3) -- replicate-to
+==============================
+
+## SYNOPSIS
+
+    nmo.commands.replicateTo([<clusterurl> || <cluster>], database, url)
+
+
+## DESCRIPTION
+
+Replicate the database at `url` to the supplied cluster or cluster url and database.

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/doc/cli/nmo-replicate-from.md
----------------------------------------------------------------------
diff --git a/doc/cli/nmo-replicate-from.md b/doc/cli/nmo-replicate-from.md
new file mode 100644
index 0000000..f5707b5
--- /dev/null
+++ b/doc/cli/nmo-replicate-from.md
@@ -0,0 +1,24 @@
+nmo-replicate-from(1) -- replicate a database from the cluster to another CouchDB database
url
+===========================================
+
+## SYNOPSIS
+
+    nmo replicate-from <cluster> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]
+    nmo replicate-from <url> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]
+
+
+## DESCRIPTION
+
+Replicate a database from the `cluster` to the supplied CouchDB instance url and database.
Or it will replicate from a CouchDB url and database to the supplied CouchDB instance url
and database.
+
+
+Example:
+
+This will replicate the database `hello-database` from the cluster `mycluster` to the supplied
url
+    nmo replicate-from mycluster hello-database http://192.0.0.1/hello-database-replicated
+
+This will replicate the database `hello-database` from the cluster `mycluster` to the supplied
url and create the target and make it a continuous replication
+    nmo replicate-from mycluster hello-database http://192.0.0.1/hello-database-replicated
--create-target --continuous
+
+This will replicate the database `hello-database` from the url `http://my-couchdb-cluster.com`
to the supplied url
+    nmo replicate-from http://my-couchdb-cluster hello-database http://192.0.0.1/hello-database-replicated

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/doc/cli/replicate-to.md
----------------------------------------------------------------------
diff --git a/doc/cli/replicate-to.md b/doc/cli/replicate-to.md
new file mode 100644
index 0000000..7dcaa3f
--- /dev/null
+++ b/doc/cli/replicate-to.md
@@ -0,0 +1,24 @@
+nmo-replicate-to(1) -- replicate a database to the cluster from another CouchDB database
url
+===========================================
+
+## SYNOPSIS
+
+    nmo replicate-to <cluster> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]
+    nmo replicate-to <url> <databasename> <url/dbname> [--continuous] [--create-target]
[--json]
+
+
+## DESCRIPTION
+
+Replicate a database to the `cluster` from the supplied CouchDB instance url and database.
Or it will replicate from a CouchDB url and database to the supplied CouchDB instance url
and database.
+
+
+Example:
+
+This will replicate the database `hello-database` from the url to database `hlloe-database-replicated`
in cluster `mycluster`.
+    nmo replicate-to mycluster hello-database-replicated http://192.0.0.1/hello-database
+
+This will replicate the database `hello-database` to the cluster `mycluster` and create the
database and make it a continuous replication
+    nmo replicate-to mycluster hello-database-replicated http://192.0.0.1/hello-database
--create-target --continuous
+
+This will replicate the database `hello-database` to the url `http://my-couchdb-cluster.com`
from the supplied url
+    nmo replicate-from http://my-couchdb-cluster hello-database-replicated http://192.0.0.1/hello-database

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/src/nmo.js
----------------------------------------------------------------------
diff --git a/src/nmo.js b/src/nmo.js
index 6b76095..978f236 100644
--- a/src/nmo.js
+++ b/src/nmo.js
@@ -15,7 +15,9 @@ const commands = [
   'import-csv',
   'couch-config',
   'activetasks',
-  'savetofile'
+  'savetofile',
+  'replicate-from',
+  'replicate-to'
 ];
 
 const nmo = {

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/src/replicate-from.js
----------------------------------------------------------------------
diff --git a/src/replicate-from.js b/src/replicate-from.js
new file mode 100644
index 0000000..2420df2
--- /dev/null
+++ b/src/replicate-from.js
@@ -0,0 +1,49 @@
+import nmo from './nmo.js';
+import Promise from 'bluebird';
+import { getUrlFromCluster } from './utils';
+import {replicate, createReplicatorDoc } from './replicate';
+
+
+export function cli (cluster, dbname, url) {
+  return new Promise((resolve, reject) => {
+    if (!cluster) {
+      const msg = [
+        'Usage:',
+        '',
+        'nmo replicate-from <cluster> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]',
+        'nmo replicate-from <url> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]',
+      ].join('\n');
+
+      const err = new Error(msg);
+      err.type = 'EUSAGE';
+      return reject(err);
+    }
+
+    replicateFrom(cluster, dbname, url)
+    .then(resp => {
+      console.log('Replication started.');
+      resolve(resp);
+    })
+    .catch(err => {
+      err.type = 'EUSAGE';
+      reject(err);
+    });
+  });
+}
+
+export default function replicateFrom(cluster, dbname, url) {
+  return new Promise((resolve, reject) => {
+    const clusterUrl = getUrlFromCluster(cluster);
+    const replicatorUrl = clusterUrl + '/_replicator';
+    const dbUrl = clusterUrl + '/' + dbname;
+
+    const replicator = createReplicatorDoc(dbUrl, url, {
+      continuous: !!nmo.config.get('continuous'),
+      create_target: !!nmo.config.get('create-target')
+    });
+
+    replicate(replicatorUrl, replicator)
+    .then(resolve)
+    .catch(reject);
+  });
+}

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/src/replicate-to.js
----------------------------------------------------------------------
diff --git a/src/replicate-to.js b/src/replicate-to.js
new file mode 100644
index 0000000..3841c0d
--- /dev/null
+++ b/src/replicate-to.js
@@ -0,0 +1,49 @@
+import nmo from './nmo.js';
+import Promise from 'bluebird';
+import { getUrlFromCluster } from './utils';
+import {replicate, createReplicatorDoc } from './replicate';
+
+
+export function cli (cluster, dbname, url) {
+  return new Promise((resolve, reject) => {
+    if (!cluster) {
+      const msg = [
+        'Usage:',
+        '',
+        'nmo replicate-to <cluster> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]',
+        'nmo replicate-to <url> <databasename> <url/dbname> [--continuous]
[--create-target] [--json]',
+      ].join('\n');
+
+      const err = new Error(msg);
+      err.type = 'EUSAGE';
+      return reject(err);
+    }
+
+    replicateTo(cluster, dbname, url)
+    .then(resp => {
+      console.log('Replication started.');
+      resolve(resp);
+    })
+    .catch(err => {
+      err.type = 'EUSAGE';
+      reject(err);
+    });
+  });
+}
+
+export default function replicateTo(cluster, dbname, url) {
+  return new Promise((resolve, reject) => {
+    const clusterUrl = getUrlFromCluster(cluster);
+    const replicatorUrl = clusterUrl + '/_replicator';
+    const dbUrl = clusterUrl + '/' + dbname;
+
+    const replicator = createReplicatorDoc(url, dbUrl, {
+      continuous: !!nmo.config.get('continuous'),
+      "create_target": !!nmo.config.get('create-target')
+    });
+
+    replicate(replicatorUrl, replicator)
+    .then(resolve)
+    .catch(reject);
+  });
+}

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/src/replicate.js
----------------------------------------------------------------------
diff --git a/src/replicate.js b/src/replicate.js
new file mode 100644
index 0000000..97b9089
--- /dev/null
+++ b/src/replicate.js
@@ -0,0 +1,21 @@
+import { sendJsonToNode } from './utils';
+
+
+export function createReplicatorDoc (source, target, options) {
+  return {
+    source: {
+      url: source
+    },
+
+    target: {
+      url: target
+    },
+
+    continuous: options.continuous,
+    "create_target": options.create_target
+  };
+}
+
+export function replicate (replicatorUrl, doc) {
+  return sendJsonToNode(replicatorUrl, doc);
+}

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/test/replicate-from.js
----------------------------------------------------------------------
diff --git a/test/replicate-from.js b/test/replicate-from.js
new file mode 100644
index 0000000..2f33a0e
--- /dev/null
+++ b/test/replicate-from.js
@@ -0,0 +1,91 @@
+import assert from 'assert';
+import Lab from 'lab';
+
+import replicateFrom, {cli } from '../src/replicate-from.js';
+
+import * as common from './common.js';
+import nmo from '../src/nmo.js';
+
+import nock from 'nock';
+
+export let lab = Lab.script();
+const oldConsole = console.log;
+const nmoconf = {nmoconf: __dirname + '/fixtures/randomini'};
+
+common.createConfigFile();
+
+lab.experiment('replicate-from', () => {
+
+  lab.experiment('cli', () => {
+    lab.beforeEach((done) => {
+      nmo
+        .load(nmoconf)
+        .then(() => done())
+        .catch(() => done());
+
+    });
+
+    lab.afterEach((done) => {
+      console.log = oldConsole;
+      done();
+    });
+
+    lab.test('returns error on no value provided', done => {
+      cli()
+        .catch((err) => {
+          assert.ok(err instanceof Error);
+          done();
+        });
+    });
+
+    lab.test('replicates db given cluster details', done => {
+      const doc = {
+        "source":{
+          "url":"http://127.0.0.1/mydb"
+        },
+        "target":{
+          "url":"https://target-repl.com/new-db"
+        },
+        "continuous":false,
+        "create_target":false
+      };
+
+      nock('http://127.0.0.1')
+        .post('/_replicator', doc)
+        .reply(200, {ok: true, id: '123', rev: '123'});
+
+      cli('clusterone', 'mydb', 'https://target-repl.com/new-db')
+      .then(resp => {
+        assert.ok(resp.ok);
+        done();
+      });
+    });
+
+    lab.test('replicates db given cluster details with continuous and create_target', done
=> {
+      nmo
+        .load({nmoconf: __dirname + '/fixtures/randomini', "create-target": true, continuous:
true})
+        .then(() => {
+          const doc = {
+            "source":{
+              "url":"http://127.0.0.1/mydb"
+            },
+            "target":{
+              "url":"https://target-repl.com/new-db"
+            },
+            "continuous":true,
+            "create_target":true
+          };
+
+          nock('http://127.0.0.1')
+            .post('/_replicator', doc)
+            .reply(200, {ok: true, id: '123', rev: '123'});
+
+          cli('clusterone', 'mydb', 'https://target-repl.com/new-db')
+          .then(resp => {
+            assert.ok(resp.ok);
+            done();
+          });
+        });
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/test/replicate-to.js
----------------------------------------------------------------------
diff --git a/test/replicate-to.js b/test/replicate-to.js
new file mode 100644
index 0000000..aac29d3
--- /dev/null
+++ b/test/replicate-to.js
@@ -0,0 +1,91 @@
+import assert from 'assert';
+import Lab from 'lab';
+
+import replicateTo, {cli } from '../src/replicate-to.js';
+
+import * as common from './common.js';
+import nmo from '../src/nmo.js';
+
+import nock from 'nock';
+
+export let lab = Lab.script();
+const oldConsole = console.log;
+const nmoconf = {nmoconf: __dirname + '/fixtures/randomini'};
+
+common.createConfigFile();
+
+lab.experiment('replicate-from', () => {
+
+  lab.experiment('cli', () => {
+    lab.beforeEach((done) => {
+      nmo
+        .load(nmoconf)
+        .then(() => done())
+        .catch(() => done());
+
+    });
+
+    lab.afterEach((done) => {
+      console.log = oldConsole;
+      done();
+    });
+
+    lab.test('returns error on no value provided', done => {
+      cli()
+        .catch((err) => {
+          assert.ok(err instanceof Error);
+          done();
+        });
+    });
+
+    lab.test('replicates db given cluster details', done => {
+      const doc = {
+        "target":{
+          "url":"http://127.0.0.1/mydb"
+        },
+        "source":{
+          "url":"https://target-repl.com/new-db"
+        },
+        "continuous":false,
+        "create_target":false
+      };
+
+      nock('http://127.0.0.1')
+        .post('/_replicator', doc)
+        .reply(200, {ok: true, id: '123', rev: '123'});
+
+      cli('clusterone', 'mydb', 'https://target-repl.com/new-db')
+      .then(resp => {
+        assert.ok(resp.ok);
+        done();
+      });
+    });
+
+    lab.test('replicates db given cluster details with continuous and create_target', done
=> {
+      nmo
+        .load({nmoconf: __dirname + '/fixtures/randomini', "create-target": true, continuous:
true})
+        .then(() => {
+          const doc = {
+            "target":{
+              "url":"http://127.0.0.1/mydb"
+            },
+            "source":{
+              "url":"https://target-repl.com/new-db"
+            },
+            "continuous":true,
+            "create_target":true
+          };
+
+          nock('http://127.0.0.1')
+            .post('/_replicator', doc)
+            .reply(200, {ok: true, id: '123', rev: '123'});
+
+          cli('clusterone', 'mydb', 'https://target-repl.com/new-db')
+          .then(resp => {
+            assert.ok(resp.ok);
+            done();
+          });
+        });
+    });
+  });
+});

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/034554b8/test/replicate.js
----------------------------------------------------------------------
diff --git a/test/replicate.js b/test/replicate.js
new file mode 100644
index 0000000..19cfd99
--- /dev/null
+++ b/test/replicate.js
@@ -0,0 +1,74 @@
+import assert from 'assert';
+import Lab from 'lab';
+import nock from 'nock';
+
+import {createReplicatorDoc, replicate} from '../src/replicate.js';
+export let lab = Lab.script();
+
+
+lab.experiment('replicate', () => {
+
+  lab.experiment('createReplicatorDoc', () => {
+    lab.test('creates correctly defined doc', (done) => {
+      var doc = createReplicatorDoc('source-url', 'target-url', {continuous: true, "create_target":
true});
+
+      assert.deepEqual({
+        source: {
+          url: 'source-url'
+        },
+
+        target: {
+          url: 'target-url'
+        },
+        continuous: true,
+        "create_target": true
+      }, doc);
+
+      done();
+    });
+  });
+
+  lab.experiment('replicate', () => {
+
+    lab.it('returns json response', done => {
+      var data = {ok: true};
+      var payload = {
+        source: {
+          url: 'source-url'
+        },
+
+        target: {
+          url: 'target-url'
+        },
+        continuous: true,
+        "create_target": true
+      };
+
+      nock('http://127.0.0.1')
+        .post('/_replicator')
+        .reply(200, data);
+
+      replicate('http://127.0.0.1/_replicator', payload)
+      .then(resp => {
+        assert.deepEqual(resp, data);
+        done();
+      });
+
+
+    });
+
+    lab.it('returns error on failed replication', done => {
+      nock('http://127.0.0.1')
+        .post('/_replicator')
+        .reply(500, {reason: 'ERROR'});
+
+      replicate('http://127.0.0.1/_replicator', {})
+      .catch(err => {
+        assert.deepEqual(err.type, 'EUSAGE');
+        done();
+      });
+
+    });
+
+  });
+});


Mime
View raw message