simperium 0.0.2.1 → 0.0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,2 @@
1
+ simperium-ruby-prviate
2
+ ======================
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2.2
@@ -0,0 +1,16 @@
1
+ module Simperium
2
+ class ChangeProcessor
3
+ def process(change)
4
+ if change['o'] == 'M'
5
+ if change.include?('sv')
6
+ change['v'].each do |key|
7
+ handler = self.send('on_change_#{key}')
8
+ if handler
9
+ handler(change['d'][key])
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module ErrorHandling
2
+ def self.handle_restclient_error(e)
3
+ case e
4
+ when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
5
+ message = "Could not connect to Simperium (auth.simperium.com). Please check your internet connection and try again. If the problem continues, you should check Simperium's service status at https://simperium.com/, or let us know at contact@simperium.com."
6
+ when SocketError
7
+ message = "Unexpected error when trying to connect to Simpierum. HINT: You may be seeing this message because your DNS is not working. To check, try running 'host simperium.com' from the command line."
8
+ else
9
+ message = "Unexpected error communicating with Simperium. If this problem persists, let us know at contact@simperium.com."
10
+ end
11
+ message += "\n\n(Network error: #{e.message})"
12
+ raise StandardError.new(message)
13
+ end
14
+
15
+ def self.handle_api_error(rcode, rbody)
16
+ message = rcode.to_s + ' '+ rbody
17
+ raise StandardError.new(message)
18
+ end
19
+ end
@@ -0,0 +1,153 @@
1
+ Simperium(http://addons.heroku.com/simperium) is an [add-on](http://addons.heroku.com) for circulating your data between mobile, web, and desktop versions of your app.
2
+
3
+ Adding Simpierum to your app makes your code simpler and your users happier:
4
+
5
+ * Data transparently moves across mobile, web, and desktop versions of your app
6
+ * Your users can read and write data even when they're offline
7
+ * Multiple users can collaborate with the same data at the same time
8
+ * You can build unique backend services that read and write data
9
+
10
+ Simperium is accessible via an API and has supported backend libraries for Ruby and Python and client libraries for Javascript and iOS/OS X. This add-on lets you mirror data circulated by Simpierum directly into your datastore.
11
+
12
+ ## Provisioning the add-on
13
+
14
+ Simperium can be attached to a Heroku application via the CLI:
15
+
16
+ <div class="callout" markdown="1">
17
+ A list of all plans available can be found [here](http://addons.heroku.com/simperium).
18
+ </div>
19
+
20
+ :::term
21
+ $ heroku addons:add simperium
22
+ -----> Adding simperium to sharp-mountain-4005... done, v18 (free)
23
+
24
+ Once Simperium has been added a `SIMPERIUM_APP_ID` and `SIMPERIUM_ADMIN_KEY` setting will be available in the app configuration and will contain keys to access the newly provisioned Simperium app instance. This can be confirmed using the `heroku config` command.
25
+
26
+ :::term
27
+ $ heroku config | grep SIMPERIUM_APP_ID
28
+ SIMPERIUM_APP_ID => frogs-criteria-4c4
29
+
30
+ :::term
31
+ $ heroku config | grep SIMPERIUM_ADMIN_KEY
32
+ SIMPERIUM_ADMIN_KEY => cbbae31841ac4d44a93cd82081a5b74f
33
+
34
+ After installing Simpierum your application can begin mirroring data to your datastore.
35
+
36
+ ## Local setup
37
+
38
+ ### Environment setup
39
+
40
+ After provisioning the add-on you'll want to locally replicate the config vars so your development environment can operate against the service.
41
+
42
+ <div class="callout" markdown="1">
43
+ Though less portable it’s also possible to set local environment variables using `export SIMPERIUM_APP_ID=value` and `export SIMPERIUM_APP_KEY=value`.
44
+ </div>
45
+
46
+ Use [Foreman](config-vars#local_setup) to reliably configure and run the process formation specified in your app’s [Procfile](procfile). Foreman reads configuration variables from an .env file. Use the following command to add the SIMPERIUM_APP_ID and SIMPERIUM_ADMIN_KEY values retrieved from heroku config to `.env`.
47
+
48
+ :::term
49
+ $ heroku config -s | grep SIMPERIUM_APP_ID >> .env
50
+ $ heroku config -s | grep SIMPERIUM_ADMIN_KEY >> .env
51
+ $ more .env
52
+
53
+ <p class="warning" markdown="1">
54
+ Credentials and other sensitive configuration values should not be committed to source-control. In Git exclude the .env file with: `echo .env >> .gitignore`.
55
+ </p>
56
+
57
+ ### Mirroring Data from Simperium to MongoHQ
58
+
59
+ In order to begin mirroring data from Simperium to MongoHQ, we need to install the simperium gem.
60
+
61
+ :::term
62
+ sudo gem install simperium
63
+
64
+ Grab a copy of the listner file that handles mirroring between MongoHQ and Simperium:
65
+
66
+ :::term
67
+ $ curl -O https://raw.github.com/Simperium/simperium/master/ruby/lib/simperium/listener-export-mongohq.rb
68
+
69
+ Install the mongo gem:
70
+
71
+ :::term
72
+ $ sudo gem update --system
73
+
74
+ :::term
75
+ sudo gem install mongo
76
+ sudo gem install bson_ext
77
+
78
+ Now, let Heroku know we want to run this new listener:
79
+
80
+ :::term
81
+ $ echo "worker: ruby listener-export-mongohq SIMPERIUM_APP_ID SIMPERIUM_ADMIN_KEY BUCKET_NAME" > Procfile
82
+
83
+ Note, BUCKET_NAME is the name of the bucket you want to mirror.
84
+
85
+ Start up our mongo instance with MongoHQ:
86
+
87
+ :::term
88
+ heroku addons:add mongohq:free
89
+
90
+ Finally, commit and re-push to Heroku:
91
+
92
+ :::term
93
+ $ git add .
94
+ $ git commit -m "realtime export to MongoHQ"
95
+ $ git push heroku master
96
+
97
+ Simperium activity can be observed within the Heroku log-stream by running the following:
98
+
99
+ :::term
100
+ $ heroku logs --tail
101
+
102
+ ## Dashboard
103
+
104
+ <div class="callout" markdown="1">
105
+ For more information on the features available within the Simperium dashboard please see the docs at [simperium.com/docs/reference](http://simperium.com/docs/reference).
106
+ </div>
107
+
108
+ The Simpierum dashboard allows you to delete app data, debug with our data browser, and invite developers to your Simperium app.
109
+
110
+ ![Simperium Dashboard](http://i.imgur.com/FkuUw.png "Simpierum Dashboard")
111
+
112
+ The dashboard can be accessed via the CLI:
113
+
114
+ :::term
115
+ $ heroku addons:open simperium
116
+ Opening simpierum for sharp-mountain-4005…
117
+
118
+ or by visiting the [Heroku apps web interface](http://heroku.com/myapps) and selecting the application in question. Select Simperium from the Add-ons menu.
119
+
120
+ ![Simperium Add-ons Dropdown](http://f.cl.ly/items/1B090n1P0d3W0I0R172r/addons.png "Simperium Add-ons Dropdown")
121
+
122
+
123
+ ## Migrating between plans
124
+
125
+ <div class="note" markdown="1">Application owners should carefully manage the migration timing to ensure proper application function during the migration process.</div>
126
+
127
+ Use the `heroku addons:upgrade` command to migrate to a new plan.
128
+
129
+ :::term
130
+ $ heroku addons:upgrade simperium:pro
131
+ -----> Upgrading simperium:pro to sharp-mountain-4005... done, v18 ($XX/mo)
132
+ Your plan has been updated to: simperium:pro
133
+
134
+ ## Removing the add-on
135
+
136
+ Simperium can be removed via the CLI.
137
+
138
+ <div class="warning" markdown="1">This will destroy all associated data and cannot be undone!</div>
139
+
140
+ :::term
141
+ $ heroku addons:remove simperium
142
+ -----> Removing simperium from sharp-mountain-4005... done, v20 (free)
143
+
144
+ ## Support
145
+
146
+ All Simperium support and runtime issues should be logged with Heroku Support at https://support.heroku.com. Any non-support related issues or product feedback is welcome at help@simperium.com.
147
+
148
+ ## Additional resources
149
+
150
+ Additional resources are available at:
151
+
152
+ * [Site docs](http://simperium.com/docs/reference)
153
+ * [Some screencast](https://simperium.com)
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'simperium'
4
+ require 'uri'
5
+ require 'mongo'
6
+ require 'optparse'
7
+
8
+ MONGOHQ_URL = ENV['MONGOHQ_URL']
9
+
10
+ uri = URI.parse(MONGOHQ_URL)
11
+ conn = Mongo::Connection.from_uri(MONGOHQ_URL)
12
+ $db = conn.db(uri.path.gsub(/^\//, ''))
13
+
14
+ def main(appname, admin_key, bucket)
15
+ _bucket = Bucket.new(appname, admin_key, bucket)
16
+
17
+ begin
18
+ cv = $db['__meta__'].find_one
19
+ cv = cv['cv']
20
+ rescue StandardError => e
21
+ cv = nil
22
+ end
23
+
24
+ begin
25
+ while true do
26
+ changes = _bucket.all(:cv => cv, :data=>true)
27
+ for change in changes
28
+ data = change['d']
29
+ # update mongo with the latest version of the data
30
+ if data
31
+ data['_id'] = change['id']
32
+ # puts data
33
+ $db[bucket].save(data)
34
+ else
35
+ $db[bucket].remove({'_id' => change['id']})
36
+ end
37
+ # persist the cv to mongo, so changes don't need to be
38
+ # re-processed after restart
39
+ $db['__meta__'].save({'_id' => 'cv', 'cv' => change['cv']})
40
+ cv = change['cv']
41
+ end
42
+ end
43
+ rescue StandardError => e
44
+ raise StandardError.new('Mirroring failed')
45
+ end
46
+ end
47
+
48
+ main(ARGV[0], ARGV[1], ARGV[2])
@@ -1,3 +1,3 @@
1
1
  module Simperium
2
- VERSION = '0.0.2.1'
2
+ VERSION = '0.0.2.2'
3
3
  end
@@ -0,0 +1,22 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require 'simperium/version'
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = 'simperium'
7
+ s.version = Simperium::VERSION
8
+ s.summary = 'Ruby bindings for the Simperium API'
9
+ s.description = 'Simperium moves data instantly and automatically everywhere it\'s needed. See https://simperium.com for details.'
10
+ s.authors = ['Ray Ventura']
11
+ s.email = ['ray@simperium.com']
12
+ s.homepage = 'https://simperium.com/docs/reference'
13
+ s.require_paths = %w{lib}
14
+
15
+ s.add_dependency('rest-client', '~> 1.4')
16
+ s.add_dependency('uuid')
17
+ s.add_dependency('json')
18
+ s.add_dependency('mongo')
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.require_paths = ['lib']
22
+ end
@@ -0,0 +1,88 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'uuid'
4
+ require 'simperium'
5
+
6
+ @@api_key = ENV['SIMPERIUM_CLIENT_TEST_APIKEY']
7
+ @@appname = ENV['SIMPERIUM_CLIENT_TEST_APPNAME']
8
+
9
+ # cache user create to cut down on the number of users created by the test suite
10
+ @@_auth_token = nil
11
+ def get_auth_token
12
+ if @@_auth_token.nil?
13
+ auth = Simperium::Auth.new(@@appname, @@api_key)
14
+ uuid = UUID.new
15
+ username = uuid.generate(:compact) + '@foo.com'
16
+ password = uuid.generate(:compact)
17
+ @@_auth_token = auth.create(username, password)
18
+ end
19
+ return @@_auth_token
20
+ end
21
+
22
+ class TestSimperiumRuby < Test::Unit::TestCase
23
+ def test_auth_create
24
+ get_auth_token
25
+ end
26
+
27
+ def test_bucket_get
28
+ uuid = UUID.new
29
+ bucket = Simperium::Bucket.new(@@appname, get_auth_token, uuid.generate(:compact))
30
+ bucket.post('item1', {'x'=> 1})
31
+ assert_equal(bucket.get('item1'), {'x' => 1})
32
+ end
33
+
34
+ def test_bucket_index
35
+ uuid = UUID.new
36
+ bucket = Simperium::Bucket.new(@@appname, get_auth_token, uuid.generate(:compact))
37
+ (0..2).each { |i| bucket.post("item#{i}", {'x' => i}) }
38
+
39
+ got = bucket.index(:data=>false, :mark=>nil, :limit=>2, :since=>nil)
40
+ want = {
41
+ 'current' => got['current'],
42
+ 'mark' => got['mark'],
43
+ 'index' => [
44
+ {'id' => 'item2', 'v' => 1},
45
+ {'id' => 'item1', 'v' => 1}] }
46
+ assert_equal(want, got)
47
+
48
+ got2 = bucket.index(:data=>false, :mark=>got['mark'], :limit=>2, :since=>nil)
49
+ want2 = {
50
+ 'current'=> got['current'],
51
+ 'index' => [
52
+ {'id' => 'item0', 'v' => 1}] }
53
+ end
54
+
55
+ def test_bucket_post
56
+ uuid = UUID.new
57
+ bucket = Simperium::Bucket.new(@@appname, get_auth_token, uuid.generate(:compact))
58
+ bucket.post('item1', {'a'=>1})
59
+ assert_equal(bucket.get('item1'), {'a'=>1})
60
+
61
+ bucket.post('item1', {'b'=>2})
62
+ assert_equal(bucket.get('item1'), {'a'=>1, 'b'=>2})
63
+
64
+ bucket.post('item1', {'c'=>3}, :replace=>true)
65
+ assert_equal(bucket.get('item1'), {'c'=>3})
66
+ end
67
+
68
+ def test_user_get
69
+ user = Simperium::User.new(@@appname, get_auth_token)
70
+ user.post({'x'=> 1})
71
+ assert_equal(user.get, {'x'=> 1})
72
+ end
73
+
74
+ def test_api_getitem
75
+ api = Simperium::Api.new(@@appname, get_auth_token)
76
+ assert_instance_of(Simperium::Bucket, api['bucket'], "api[bucket] should be an instance of Bucket")
77
+ end
78
+
79
+ def test_api_getattr
80
+ api = Simperium::Api.new(@@appname, get_auth_token)
81
+ assert_instance_of(Simperium::Bucket, api.bucket, "api.bucket should be an instance of Bucket")
82
+ end
83
+
84
+ def test_api_user
85
+ api = Simperium::Api.new(@@appname, get_auth_token)
86
+ assert_instance_of(Simperium::User, api.user, "api.user should be an instance of User")
87
+ end
88
+ end
@@ -0,0 +1,12 @@
1
+ require 'test/unit'
2
+ require 'simperium/listener-export-mongohq'
3
+
4
+ @admin_key = ENV['SIMPERIUM_CLIENT_TEST_ADMINKEY']
5
+ @appname = ENV['SIMPERIUM_CLIENT_TEST_APPNAME']
6
+ @bucket = 'todo'
7
+
8
+ class TestMirror < Test::Unit::TestCase
9
+ def test_simperium_mirror
10
+ main(@admin_key, @appname, @bucket)
11
+ end
12
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simperium
3
3
  version: !ruby/object:Gem::Version
4
- hash: 69
4
+ hash: 67
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
9
  - 2
10
- - 1
11
- version: 0.0.2.1
10
+ - 2
11
+ version: 0.0.2.2
12
12
  platform: ruby
13
13
  authors:
14
14
  - Ray Ventura
@@ -85,8 +85,18 @@ extensions: []
85
85
  extra_rdoc_files: []
86
86
 
87
87
  files:
88
+ - Gemfile
89
+ - README.md
90
+ - VERSION
88
91
  - lib/simperium.rb
92
+ - lib/simperium/changes.rb
93
+ - lib/simperium/error_handling.rb
94
+ - lib/simperium/heroku-addon-doc.md
95
+ - lib/simperium/listener-export-mongohq
89
96
  - lib/simperium/version.rb
97
+ - simperium.gemspec
98
+ - test/test_simperium.rb
99
+ - test/test_simperium_mirror.rb
90
100
  homepage: https://simperium.com/docs/reference
91
101
  licenses: []
92
102