mongo_delta 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +141 -0
- data/Rakefile +4 -0
- data/bin/mongo_delta +5 -0
- data/config/mongo_delta.yml +12 -0
- data/lib/mongo_delta/agent.rb +27 -0
- data/lib/mongo_delta/cli.rb +90 -0
- data/lib/mongo_delta/configuration.rb +81 -0
- data/lib/mongo_delta/logging.rb +19 -0
- data/lib/mongo_delta/outlet/base.rb +26 -0
- data/lib/mongo_delta/outlet/replicator.rb +21 -0
- data/lib/mongo_delta/outlet.rb +26 -0
- data/lib/mongo_delta/stream.rb +46 -0
- data/lib/mongo_delta/version.rb +3 -0
- data/lib/mongo_delta.rb +9 -0
- data/mongo_delta.gemspec +23 -0
- metadata +118 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013, Secret Sauce Partners, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
Mongo Delta
|
2
|
+
===========
|
3
|
+
|
4
|
+
### Coordinated transfer between MongoDB clusters
|
5
|
+
|
6
|
+
Mongo Delta is a command line tool that tails a MongoDB replica set's
|
7
|
+
oplog (using [mongoriver](https://github.com/stripe/mongoriver)) and
|
8
|
+
based on a configured set of outlets transfers documents to other
|
9
|
+
MongoDB instances.
|
10
|
+
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
|
14
|
+
Install from Rubygems as:
|
15
|
+
|
16
|
+
$ gem install mongo_delta
|
17
|
+
|
18
|
+
Or build from source by:
|
19
|
+
|
20
|
+
$ gem build mongo_delta.gemspec
|
21
|
+
|
22
|
+
And then install the built gem.
|
23
|
+
|
24
|
+
Configuration
|
25
|
+
-------------
|
26
|
+
|
27
|
+
Mongo Delta requires a configuration where you set up your source,
|
28
|
+
various targets and outlets. This can be stored in a YAML file or in the
|
29
|
+
source database.
|
30
|
+
|
31
|
+
Here's an example:
|
32
|
+
|
33
|
+
``` yaml
|
34
|
+
db: mongo_delta
|
35
|
+
service: mongo_delta
|
36
|
+
|
37
|
+
source: mongodb://mongorsa1:27017,mongorsa2:27017
|
38
|
+
|
39
|
+
targets:
|
40
|
+
archive: mongodb://mongoarch:27017
|
41
|
+
|
42
|
+
outlets:
|
43
|
+
- outlet: Replicator
|
44
|
+
target: archive
|
45
|
+
db: db_name
|
46
|
+
collection: events
|
47
|
+
```
|
48
|
+
|
49
|
+
The `db` and `service` options are optional and do the same as their
|
50
|
+
command line counterparts. The default for both is `'mongo_delta'`. This
|
51
|
+
tells Mongo Delta where to persist the optime which tracks the point of
|
52
|
+
time upto which the oplog has been processed. The `service` option
|
53
|
+
makes it possible to run multiple Mongo Delta processes using the same
|
54
|
+
source.
|
55
|
+
|
56
|
+
The `source` is where Mongo Delta is going to tail the oplog.
|
57
|
+
Under `targets` several target connections can be listed.
|
58
|
+
Use [MongoDB URIs](http://api.mongodb.org/ruby/current/#Environment_variable_MONGODB_URI) for both options.
|
59
|
+
|
60
|
+
Finally, list outlets which will handle the incoming data and send them
|
61
|
+
out another way. Configure each outlet with the following options:
|
62
|
+
|
63
|
+
* `outlet`: name of one of the outlet implementations (see below)
|
64
|
+
* `target`: name of one of the targets
|
65
|
+
* `db` and `collection`: specify the namespace for which the outlet applies
|
66
|
+
* `target_db` and `target_collection`: optional, send data at target to
|
67
|
+
a different db and collection
|
68
|
+
* some outlets can have further options
|
69
|
+
|
70
|
+
### Storing configuration in the source database
|
71
|
+
|
72
|
+
You can store this configuration in the source database. Use the
|
73
|
+
`--source` command line option and Mongo Delta will assume that the
|
74
|
+
configuration is located in the `config` collection of the `mongo_delta`
|
75
|
+
database with `_id: 'mongo_delta'`. The database and the service ID can
|
76
|
+
be overridden with the `--db` and `--service` options respectively.
|
77
|
+
|
78
|
+
Example:
|
79
|
+
|
80
|
+
```
|
81
|
+
$ mongo mongo_delta
|
82
|
+
rs0:PRIMARY> db.config.save({
|
83
|
+
... _id: 'mongo_delta',
|
84
|
+
... outlets: [{
|
85
|
+
... outlet: 'Replicator',
|
86
|
+
... target: 'live',
|
87
|
+
... db: 'sourcedb',
|
88
|
+
... collection: 'events',
|
89
|
+
... target_db: 'archive'
|
90
|
+
... }],
|
91
|
+
... targets: {live: 'mongodb://localhost:27017'}
|
92
|
+
... })
|
93
|
+
$ mongo_delta --source mongodb://localhost:27017
|
94
|
+
2013-06-10 21:24:29 - INFO: Registering Replicator outlet for cartman.events
|
95
|
+
2013-06-10 21:24:29 - INFO: Starting stream
|
96
|
+
```
|
97
|
+
|
98
|
+
Usage
|
99
|
+
-----
|
100
|
+
|
101
|
+
mongo_delta --config path/to/config.yml [options]
|
102
|
+
|
103
|
+
or if the configuration is stored in the source database:
|
104
|
+
|
105
|
+
mongo_delta --source mongodb://mongorsa1:27017,mongorsa2:27017 [options]
|
106
|
+
|
107
|
+
Run `mongo_delta --help` for more options.
|
108
|
+
|
109
|
+
Outlets
|
110
|
+
-------
|
111
|
+
|
112
|
+
### Replicator
|
113
|
+
|
114
|
+
This outlet simply repeats `insert`, `remove` and `update` operations on
|
115
|
+
the configured target. You can use this to keep a remote collection
|
116
|
+
in sync with your main MongoDB cluster. Keep in mind that the
|
117
|
+
replication is one-way.
|
118
|
+
|
119
|
+
Sharded clusters
|
120
|
+
----------------
|
121
|
+
|
122
|
+
Mongo Delta does not have special support for sharded Mongo clusters at
|
123
|
+
this time. It should be possible to run a separate `mongo_delta`
|
124
|
+
instance against each of the individual backend shard replica sets,
|
125
|
+
but otherwise with the same configuration.
|
126
|
+
|
127
|
+
Development
|
128
|
+
-----------
|
129
|
+
|
130
|
+
Patches and contributions are welcome! Please fork the project and
|
131
|
+
open a pull request on [github](https://github.com/sspinc/mongo_delta),
|
132
|
+
or just report issues.
|
133
|
+
|
134
|
+
Mongo Delta assumes the source MongoDB to be a replica set member. You
|
135
|
+
can create a standalone replica set member on your development machine
|
136
|
+
by running `mongod` with the `--replSet rs0` option, and then running
|
137
|
+
the following command in the mongo shell:
|
138
|
+
|
139
|
+
``` javascript
|
140
|
+
rs.initiate({_id: 'rs0', members: [{ _id: 0, host: '127.0.0.1:27017'}]})
|
141
|
+
```
|
data/Rakefile
ADDED
data/bin/mongo_delta
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source: mongodb://localhost:27017
|
2
|
+
|
3
|
+
targets:
|
4
|
+
archive: mongodb://localhost:27017
|
5
|
+
|
6
|
+
outlets:
|
7
|
+
- outlet: Replicator
|
8
|
+
target: archive
|
9
|
+
db: dbname
|
10
|
+
collection: events
|
11
|
+
target_db: archive # optional, defaults to 'db'
|
12
|
+
target_collection: archived_events # optional, defaults to 'collection'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MongoDelta
|
2
|
+
class Agent < Mongoriver::AbstractOutlet
|
3
|
+
|
4
|
+
include MongoDelta::Logging
|
5
|
+
|
6
|
+
attr_reader :outlets
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@outlets = []
|
10
|
+
end
|
11
|
+
|
12
|
+
%w(insert remove update).each do |method|
|
13
|
+
|
14
|
+
define_method(method) do |db, collection, *args|
|
15
|
+
logger.debug "#{method} for #{db}.#{collection}: #{args.map(&:inspect).join(' ')}"
|
16
|
+
|
17
|
+
outlets.each do |outlet|
|
18
|
+
if outlet.handles?(db, collection, method)
|
19
|
+
outlet.send(method, *args)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require 'mongo_delta'
|
4
|
+
|
5
|
+
module MongoDelta
|
6
|
+
module CLI
|
7
|
+
class << self
|
8
|
+
|
9
|
+
include MongoDelta::Logging
|
10
|
+
|
11
|
+
attr_accessor :config_path, :source_uri, :optime, :db, :service
|
12
|
+
|
13
|
+
def start
|
14
|
+
parse_options
|
15
|
+
validate_options!
|
16
|
+
|
17
|
+
config =
|
18
|
+
if config_path
|
19
|
+
Configuration.load_from_file(config_path)
|
20
|
+
else
|
21
|
+
Configuration.load_from_db(source_uri, db, service)
|
22
|
+
end
|
23
|
+
config.db = db
|
24
|
+
config.service = service
|
25
|
+
|
26
|
+
stream = Stream.new(config)
|
27
|
+
stream.run(optime)
|
28
|
+
rescue Mongo::ConnectionFailure, Configuration::Error
|
29
|
+
logger.fatal($!.message)
|
30
|
+
exit(1)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def parse_options
|
36
|
+
logger.level = Logger::INFO
|
37
|
+
|
38
|
+
optparse = OptionParser.new do |opts|
|
39
|
+
opts.banner = "Usage: #{$0} [options]"
|
40
|
+
|
41
|
+
opts.on('-v', '--verbose', 'More verbose output') do
|
42
|
+
logger.level = Logger::DEBUG
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('-q', '--quiet', 'Less verbose output') do
|
46
|
+
logger.level = Logger::WARN
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('--help', 'Display this message') do
|
50
|
+
puts opts
|
51
|
+
exit(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
opts.on('-c FILE', '--config', 'Configuration file') do |path|
|
55
|
+
self.config_path = path
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('-s MONGODB_URI', '--source', 'MongoDB URI for source connection') do |uri|
|
59
|
+
self.source_uri = uri
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on('-d DB', '--db', "DB for storing optime (default: #{Configuration::DEFAULT_DB})") do |db|
|
63
|
+
self.db = db
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on('-n NAME', '--service', "Service name (default: #{Configuration::DEFAULT_SERVICE})") do |service|
|
67
|
+
self.service = service
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on('-o OPTIME', '--optime', 'Starting optime') do |optime|
|
71
|
+
self.optime = Integer(optime)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
optparse.parse!
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_options!
|
78
|
+
unless config_path or source_uri
|
79
|
+
logger.fatal "Missing configuration. Use --config or --source."
|
80
|
+
exit 1
|
81
|
+
end
|
82
|
+
if config_path and source_uri
|
83
|
+
logger.fatal "Options --config and --source are mutually exclusive."
|
84
|
+
exit 1
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'mongo'
|
4
|
+
|
5
|
+
module MongoDelta
|
6
|
+
class Configuration
|
7
|
+
|
8
|
+
class Error < RuntimeError; end
|
9
|
+
|
10
|
+
DEFAULT_DB='mongo_delta'
|
11
|
+
DEFAULT_SERVICE='mongo_delta'
|
12
|
+
|
13
|
+
def self.load_from_file(path)
|
14
|
+
options = YAML.load(ERB.new(File.read(path)).result)
|
15
|
+
new(options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load_from_db(mongodb_uri, db=nil, service=nil)
|
19
|
+
db ||= DEFAULT_DB
|
20
|
+
service ||= DEFAULT_SERVICE
|
21
|
+
|
22
|
+
mongo = connect_to_source(mongodb_uri)
|
23
|
+
collection = mongo.db(db).collection('config')
|
24
|
+
|
25
|
+
unless options = collection.find_one(:_id => service)
|
26
|
+
raise Error, "There was no config in the database at #{mongodb_uri}/#{db} with id '#{service}'"
|
27
|
+
end
|
28
|
+
|
29
|
+
new(options.merge({'source' => mongo, 'db' => db, 'service' => service}))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.connect_to_source(connection_or_uri)
|
33
|
+
if connection_or_uri.is_a? Mongo::MongoClient
|
34
|
+
connection_or_uri
|
35
|
+
else
|
36
|
+
Mongo::MongoClient.from_uri(connection_or_uri)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
attr_reader :source
|
41
|
+
|
42
|
+
def initialize(options={})
|
43
|
+
@options = options
|
44
|
+
@source = self.class.connect_to_source(options['source'])
|
45
|
+
validate!
|
46
|
+
end
|
47
|
+
|
48
|
+
def targets
|
49
|
+
@options['targets']
|
50
|
+
end
|
51
|
+
|
52
|
+
def outlets
|
53
|
+
@options['outlets']
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate!
|
57
|
+
raise Error, "Missing source" unless source
|
58
|
+
raise Error, "Missing outlets" unless outlets and not outlets.empty?
|
59
|
+
outlets.each do |outlet|
|
60
|
+
key = outlet['target']
|
61
|
+
target = (targets || {})[key]
|
62
|
+
raise Error, "Missing target '#{key}'" unless target
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def db
|
67
|
+
@options['db'] || DEFAULT_DB
|
68
|
+
end
|
69
|
+
def db=(db)
|
70
|
+
@options['db'] = db
|
71
|
+
end
|
72
|
+
|
73
|
+
def service
|
74
|
+
@options['service'] || DEFAULT_SERVICE
|
75
|
+
end
|
76
|
+
def service=(service)
|
77
|
+
@options['service'] = service
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module MongoDelta
|
4
|
+
module Logging
|
5
|
+
|
6
|
+
def self.setup_logger
|
7
|
+
Logger.new(STDERR).tap do |logger|
|
8
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
9
|
+
"#{datetime} - #{severity}: #{msg}\n"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def logger
|
15
|
+
@@logger ||= MongoDelta::Logging.setup_logger
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MongoDelta
|
2
|
+
module Outlet
|
3
|
+
class Base
|
4
|
+
|
5
|
+
attr_reader :target, :db, :collection, :options, :target_collection
|
6
|
+
|
7
|
+
def initialize(target, db, collection, options={})
|
8
|
+
@target = target
|
9
|
+
@db = db
|
10
|
+
@collection = collection
|
11
|
+
@options = options
|
12
|
+
|
13
|
+
@target_collection = target.db(options['target_db'] || db).collection(options['target_collection'] || collection)
|
14
|
+
end
|
15
|
+
|
16
|
+
def ns
|
17
|
+
"#{db}.#{collection}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def handles?(db, collection, method)
|
21
|
+
@db == db and @collection == collection and respond_to?(method)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'mongo_delta/outlet/base'
|
2
|
+
|
3
|
+
module MongoDelta
|
4
|
+
module Outlet
|
5
|
+
class Replicator < Base
|
6
|
+
|
7
|
+
def insert(document)
|
8
|
+
target_collection.save(document)
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove(document)
|
12
|
+
target_collection.remove(document)
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(selector, update)
|
16
|
+
target_collection.update(selector, update)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
|
3
|
+
require 'mongo_delta/outlet/base'
|
4
|
+
require 'mongo_delta/outlet/replicator'
|
5
|
+
|
6
|
+
module MongoDelta
|
7
|
+
module Outlet
|
8
|
+
|
9
|
+
def self.from_options(config, options)
|
10
|
+
options = options.dup
|
11
|
+
klass = const_get(options.delete('outlet'))
|
12
|
+
target = fetch_target(config, options.delete('target'))
|
13
|
+
db = options.delete('db')
|
14
|
+
collection = options.delete('collection')
|
15
|
+
klass.new(target, db, collection, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def self.fetch_target(config, key)
|
21
|
+
@targets ||= {}
|
22
|
+
@targets[key] ||= Mongo::MongoClient.from_uri(config.targets[key])
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
|
3
|
+
require 'mongo_delta/agent'
|
4
|
+
require 'mongo_delta/outlet'
|
5
|
+
|
6
|
+
module MongoDelta
|
7
|
+
class Stream
|
8
|
+
|
9
|
+
include MongoDelta::Logging
|
10
|
+
|
11
|
+
def initialize(config)
|
12
|
+
@config = config
|
13
|
+
@tailer = Mongoriver::PersistentTailer.new([@config.source], :existing, @config.service, :db => @config.db)
|
14
|
+
@agent = MongoDelta::Agent.new
|
15
|
+
@stream = Mongoriver::Stream.new(@tailer, @agent)
|
16
|
+
setup_outlets
|
17
|
+
end
|
18
|
+
|
19
|
+
def run(ts=nil)
|
20
|
+
register_signal_handlers
|
21
|
+
logger.info "Starting stream"
|
22
|
+
@stream.run_forever(ts)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def setup_outlets
|
28
|
+
@config.outlets.each do |options|
|
29
|
+
outlet = MongoDelta::Outlet.from_options(@config, options)
|
30
|
+
logger.info "Registering #{options['outlet']} outlet for #{outlet.ns}"
|
31
|
+
@agent.outlets << outlet
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def register_signal_handlers
|
36
|
+
logger.debug "Registering signal handlers"
|
37
|
+
%w[TERM INT USR2].each do |sig|
|
38
|
+
Signal.trap(sig) do
|
39
|
+
logger.info "Got SIG#{sig}. Preparing to exit..."
|
40
|
+
@stream.stop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
data/lib/mongo_delta.rb
ADDED
data/mongo_delta.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$:.unshift(File.expand_path("lib", File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'mongo_delta/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.authors = ["Laszlo Bacsi"]
|
7
|
+
gem.email = ["lackac@lackac.hu"]
|
8
|
+
gem.description = %q{Streaming documents between MongoDB clusters}
|
9
|
+
gem.summary = %q{Replicate mongodb documents between clusters}
|
10
|
+
gem.homepage = "https://github.com/sspinc/mongo_delta"
|
11
|
+
|
12
|
+
gem.files = `git ls-files`.split($\)
|
13
|
+
gem.executables = gem.files.grep(%r{^bin/}).map {|f| File.basename(f)}
|
14
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
15
|
+
gem.name = "mongo_delta"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = MongoDelta::VERSION
|
18
|
+
|
19
|
+
gem.add_runtime_dependency('mongo', '>= 1.7')
|
20
|
+
gem.add_runtime_dependency('mongoriver', '>= 0.3')
|
21
|
+
|
22
|
+
gem.add_development_dependency('rake')
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongo_delta
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Laszlo Bacsi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-10 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
prerelease: false
|
16
|
+
name: mongo
|
17
|
+
type: :runtime
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '1.7'
|
23
|
+
none: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ! '>='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '1.7'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
prerelease: false
|
32
|
+
name: mongoriver
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0.3'
|
39
|
+
none: false
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0.3'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
prerelease: false
|
48
|
+
name: rake
|
49
|
+
type: :development
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
none: false
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
none: false
|
62
|
+
description: Streaming documents between MongoDB clusters
|
63
|
+
email:
|
64
|
+
- lackac@lackac.hu
|
65
|
+
executables:
|
66
|
+
- mongo_delta
|
67
|
+
extensions: []
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- Gemfile
|
72
|
+
- LICENSE
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- bin/mongo_delta
|
76
|
+
- config/mongo_delta.yml
|
77
|
+
- lib/mongo_delta.rb
|
78
|
+
- lib/mongo_delta/agent.rb
|
79
|
+
- lib/mongo_delta/cli.rb
|
80
|
+
- lib/mongo_delta/configuration.rb
|
81
|
+
- lib/mongo_delta/logging.rb
|
82
|
+
- lib/mongo_delta/outlet.rb
|
83
|
+
- lib/mongo_delta/outlet/base.rb
|
84
|
+
- lib/mongo_delta/outlet/replicator.rb
|
85
|
+
- lib/mongo_delta/stream.rb
|
86
|
+
- lib/mongo_delta/version.rb
|
87
|
+
- mongo_delta.gemspec
|
88
|
+
homepage: https://github.com/sspinc/mongo_delta
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
hash: -1239396457491943967
|
101
|
+
version: '0'
|
102
|
+
none: false
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
hash: -1239396457491943967
|
110
|
+
version: '0'
|
111
|
+
none: false
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.23
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: Replicate mongodb documents between clusters
|
118
|
+
test_files: []
|