couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gar...@apache.org
Subject couchdb-nmo git commit: Replication
Date Mon, 16 Nov 2015 12:16:16 GMT
Repository: couchdb-nmo
Updated Branches:
  refs/heads/master f29ee61d7 -> 532cd6eb1


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/532cd6eb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/tree/532cd6eb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-nmo/diff/532cd6eb

Branch: refs/heads/master
Commit: 532cd6eb11f41f1e9ff6adb8d10ea1d7df2efe65
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:14:44 2015 +0200

----------------------------------------------------------------------
 doc/api/nmo-replicate-from.md | 11 +++++
 doc/api/replicate-to.md       | 11 +++++
 doc/cli/nmo-replicate-from.md | 24 ++++++++++
 doc/cli/nmo-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/532cd6eb/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..126e28a
--- /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/532cd6eb/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..41b3dee
--- /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/532cd6eb/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..57fd903
--- /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.com hello-database http://192.0.0.1/hello-database-replicated

http://git-wip-us.apache.org/repos/asf/couchdb-nmo/blob/532cd6eb/doc/cli/nmo-replicate-to.md
----------------------------------------------------------------------
diff --git a/doc/cli/nmo-replicate-to.md b/doc/cli/nmo-replicate-to.md
new file mode 100644
index 0000000..9549eb3
--- /dev/null
+++ b/doc/cli/nmo-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-to 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/532cd6eb/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/532cd6eb/src/replicate-from.js
----------------------------------------------------------------------
diff --git a/src/replicate-from.js b/src/replicate-from.js
new file mode 100644
index 0000000..704176c
--- /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 || !dbname || !url) {
+      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/532cd6eb/src/replicate-to.js
----------------------------------------------------------------------
diff --git a/src/replicate-to.js b/src/replicate-to.js
new file mode 100644
index 0000000..5cc567c
--- /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 || !dbname || !url) {
+      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/532cd6eb/src/replicate.js
----------------------------------------------------------------------
diff --git a/src/replicate.js b/src/replicate.js
new file mode 100644
index 0000000..b89c8d3
--- /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/532cd6eb/test/replicate-from.js
----------------------------------------------------------------------
diff --git a/test/replicate-from.js b/test/replicate-from.js
new file mode 100644
index 0000000..9504bb8
--- /dev/null
+++ b/test/replicate-from.js
@@ -0,0 +1,91 @@
+import assert from 'assert';
+import Lab from 'lab';
+
+import { 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/532cd6eb/test/replicate-to.js
----------------------------------------------------------------------
diff --git a/test/replicate-to.js b/test/replicate-to.js
new file mode 100644
index 0000000..7872580
--- /dev/null
+++ b/test/replicate-to.js
@@ -0,0 +1,91 @@
+import assert from 'assert';
+import Lab from 'lab';
+
+import { 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-to', () => {
+
+  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/532cd6eb/test/replicate.js
----------------------------------------------------------------------
diff --git a/test/replicate.js b/test/replicate.js
new file mode 100644
index 0000000..013c124
--- /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