vayacondios-server 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ # WARNING! THIS DOCUMENT IS OUTDATED AND MAY NOT REFLECT ACTUAL CODE! GO READ THE SPECS FOR BEHAVIORS!
2
+
1
3
  # Vaya con Dios
2
4
 
3
5
  > "Data goes in. The right thing happens."
data/app/http_shim.rb CHANGED
@@ -12,34 +12,31 @@ class HttpShim < Goliath::API
12
12
  use Goliath::Rack::Render, 'json' # auto-negotiate response format
13
13
 
14
14
  def response(env)
15
+ # Validate path_params
15
16
  path_params = parse_path(env[Goliath::Request::REQUEST_PATH])
17
+ return [400, {}, {error: "Bad Request"}] if !path_params.present?
18
+
19
+ # Look up handler using inflection
20
+ klass = ('vayacondios/' + path_params[:type] + '_handler').camelize.constantize
16
21
 
17
- if path_params.present?
18
- klass = ('vayacondios/' + path_params[:type] + '_handler').camelize.constantize
19
-
20
- if method_name == :get && !path_params[:topic].present?
21
- return [400, {}, {error: "Bad Request"}]
22
- end
23
- begin
22
+ begin
24
23
  if method_name == :update
25
24
  record = klass.new(mongo).update(env.params, path_params)
26
25
  elsif method_name == :get
27
26
  record = klass.find(mongo, path_params)
28
27
  end
28
+ rescue Vayacondios::Error::BadRequest => ex
29
+ return [400, {}, {error: "Bad Request"}]
30
+ rescue Exception => ex
31
+ puts ex
32
+ ex.backtrace.each{|l| puts l}
33
+ end
29
34
 
30
- rescue Exception => ex
31
- puts ex
32
- ex.backtrace.each{|l| puts l}
33
- end
34
-
35
- if record.present?
36
- [200, {}, record]
37
- else
38
- [404, {}, {error: "Not Found"}]
39
- end
40
- else
41
- [400, {}, {error: "Bad Request"}]
35
+ if !record.present?
36
+ [404, {}, {error: "Not Found"}]
42
37
  end
38
+
39
+ [200, {}, record]
43
40
  end
44
41
 
45
42
  private
@@ -0,0 +1,6 @@
1
+ class Vayacondios
2
+ module Error
3
+ class BadRequest < Exception
4
+ end
5
+ end
6
+ end
@@ -12,6 +12,9 @@ class Vayacondios
12
12
  end
13
13
 
14
14
  def update(document, options={})
15
+ raise Error::BadRequest.new unless options[:topic] && options[:id]
16
+ raise Error::BadRequest.new if /\W/ =~ options[:id]
17
+
15
18
  existing_document = ConfigDocument.find(@mongo, options)
16
19
  if existing_document
17
20
  existing_document.update(document)
@@ -21,6 +24,7 @@ class Vayacondios
21
24
 
22
25
  {
23
26
  topic: existing_document.topic,
27
+ id: existing_document.id,
24
28
  cargo: existing_document.body,
25
29
  status: :success
26
30
  }
@@ -12,6 +12,9 @@ class Vayacondios
12
12
  end
13
13
 
14
14
  def update(document, options={})
15
+ raise Error::BadRequest.new unless options[:topic]
16
+ raise Error::BadRequest.new if options[:id] && /\W/ =~ options[:id]
17
+
15
18
  existing_document = EventDocument.find(@mongo, options)
16
19
  if existing_document
17
20
  existing_document.update(document)
@@ -10,12 +10,13 @@ require 'vayacondios/server/model/document'
10
10
  # work while Goliath is in a streaming context.
11
11
 
12
12
  class Vayacondios::ConfigDocument < Vayacondios::Document
13
- attr_reader :organization, :topic, :body
13
+ attr_reader :organization, :topic, :body, :id
14
14
 
15
15
  def initialize(mongodb, options = {})
16
16
  super options
17
17
  @mongo = mongodb
18
18
  options = sanitize_options(options)
19
+ @id = options[:id]
19
20
 
20
21
  @body = nil
21
22
  @field = options[:field] ||= options[:id]
@@ -34,10 +35,8 @@ class Vayacondios::ConfigDocument < Vayacondios::Document
34
35
  end
35
36
 
36
37
  def find
37
- fields = {}
38
- fields[@field] = 1 if @field
38
+ result = @collection.find_one({_id: @topic})
39
39
 
40
- result = @collection.find_one({_id: @topic}, {fields: @fields})
41
40
  if result.present?
42
41
  result.delete("_id")
43
42
  @body = result
@@ -49,11 +48,7 @@ class Vayacondios::ConfigDocument < Vayacondios::Document
49
48
  end
50
49
 
51
50
  def update(document)
52
- # MongoDB always wants a Hash. If we POST to /org/topic/users/jim/username
53
- # with "jimmy", we transform the document to {username: "jimmy"}
54
- if !document.is_a?(Hash)
55
- document = {@field.split(/\W/).last.to_sym => document}
56
- end
51
+ raise Error::BadRequest.new if !document.is_a?(Hash)
57
52
 
58
53
  # Merge ourselves
59
54
  document = body.deep_merge(document) if body
@@ -1,3 +1,3 @@
1
1
  class Vayacondios
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -11,6 +11,8 @@ require 'gorillib/string/constantize'
11
11
  require 'gorillib/string/inflections'
12
12
  require 'multi_json'
13
13
 
14
+ require 'vayacondios/server/errors/bad_request'
15
+
14
16
  require 'vayacondios/server/model/config_document'
15
17
  require 'vayacondios/server/model/event_document'
16
18
 
@@ -7,9 +7,31 @@ require File.join(File.dirname(__FILE__), '../../', 'app/http_shim')
7
7
  describe HttpShim do
8
8
  include Goliath::TestHelper
9
9
 
10
- let(:err) { Proc.new{ |c| fail "HTTP Request Failed #{c.response}" } }
10
+ let(:err) { Proc.new{ |c| fail "HTTP Request Failed #{c.error}" } }
11
11
 
12
12
  context 'Configuration management' do
13
+ it 'requires a topic' do
14
+ with_api(HttpShim) do |api|
15
+ post_request({
16
+ :path => '/v1/infochimps/config/',
17
+ :body => {:level=>"awesome"}
18
+ }, err) do |c|
19
+ c.response_header.status.should == 400
20
+ end
21
+ end
22
+ end
23
+
24
+ it 'requires an id' do
25
+ with_api(HttpShim) do |api|
26
+ post_request({
27
+ :path => '/v1/infochimps/config/power',
28
+ :body => {:level=>"awesome"}
29
+ }, err) do |c|
30
+ c.response_header.status.should == 400
31
+ end
32
+ end
33
+ end
34
+
13
35
  it 'stores configuration' do
14
36
  with_api(HttpShim) do |api|
15
37
  post_request({
@@ -19,15 +41,35 @@ describe HttpShim do
19
41
  c.response_header.status.should == 200
20
42
  MultiJson.load(c.response).should eql ({
21
43
  "topic" => "power",
44
+ "id" => "level",
22
45
  "status" => "success",
23
46
  "cargo" => {
24
47
  "level" => "awesome"
25
48
  }
26
49
  })
27
50
  end
51
+
52
+ get_mongo_db do |db|
53
+ db.collection("infochimps.config").find_one({:_id => "power"}).should eql({"_id" => "power", "level" => "awesome"})
54
+ end
28
55
  end
29
56
  end
30
-
57
+
58
+ it 'rejects deep IDs' do
59
+ with_api(HttpShim) do |api|
60
+ post_request({
61
+ :path => '/v1/infochimps/config/power/level/is/invalid',
62
+ :body => {:level=>"awesome"}
63
+ }, err) do |c|
64
+ c.response_header.status.should == 400
65
+ end
66
+
67
+ get_mongo_db do |db|
68
+ db.collection("infochimps.config").find_one({:_id => "power"}).should be_nil
69
+ end
70
+ end
71
+ end
72
+
31
73
  it 'retrieves configuration' do
32
74
  with_api(HttpShim) do |api|
33
75
  post_request({
@@ -37,7 +79,7 @@ describe HttpShim do
37
79
  end
38
80
  with_api(HttpShim) do |api|
39
81
  get_request({:path => '/v1/infochimps/config/power/level'}, err) do |c|
40
- c.response_header.status.should == 200
82
+ c.response_header.status.should == 200
41
83
  MultiJson.load(c.response).should eql({"level" => "awesome"})
42
84
  end
43
85
  end
@@ -46,18 +88,18 @@ describe HttpShim do
46
88
  it 'merge deep configuration' do
47
89
  with_api(HttpShim) do |api|
48
90
  post_request({
49
- :path => '/v1/infochimps/config/mergetest',
91
+ :path => '/v1/infochimps/config/merge/test',
50
92
  :body => { :foo => { :bar => 3 } }
51
93
  }, err)
52
94
  end
53
95
  with_api(HttpShim) do |api|
54
96
  post_request({
55
- :path => '/v1/infochimps/config/mergetest',
97
+ :path => '/v1/infochimps/config/merge/test',
56
98
  :body => { :foo => { :baz => 7 } }
57
99
  }, err)
58
100
  end
59
101
  with_api(HttpShim) do |api|
60
- get_request({:path => '/v1/infochimps/config/mergetest'}, err) do |c|
102
+ get_request({:path => '/v1/infochimps/config/merge/test'}, err) do |c|
61
103
  c.response_header.status.should == 200
62
104
  MultiJson.load(c.response).should eql({
63
105
  "foo" => {
@@ -10,6 +10,54 @@ describe HttpShim do
10
10
  let(:err) { Proc.new{ |c| fail "HTTP Request Failed #{c.response}" } }
11
11
 
12
12
  context 'Event tracking' do
13
+ it 'requires a topic' do
14
+ with_api(HttpShim) do |api|
15
+ post_request({
16
+ :path => '/v1/infochimps/event/',
17
+ :body => {:level=>"awesome"}
18
+ }, err) do |c|
19
+ c.response_header.status.should == 400
20
+ end
21
+ end
22
+ end
23
+
24
+ it 'does not require an id' do
25
+ with_api(HttpShim) do |api|
26
+ post_request({
27
+ :path => '/v1/infochimps/event/power',
28
+ :body => {:level=>"awesome"}
29
+ }, err) do |c|
30
+ c.response_header.status.should == 200
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'will accept an id' do
36
+ with_api(HttpShim) do |api|
37
+ post_request({
38
+ :path => '/v1/infochimps/event/power/level',
39
+ :body => {:level=>"awesome"}
40
+ }, err) do |c|
41
+ c.response_header.status.should == 200
42
+ end
43
+ end
44
+ end
45
+
46
+ it 'rejects deep IDs' do
47
+ with_api(HttpShim) do |api|
48
+ post_request({
49
+ :path => '/v1/infochimps/event/power/level/is/invalid',
50
+ :body => {:level=>"awesome"}
51
+ }, err) do |c|
52
+ c.response_header.status.should == 400
53
+ end
54
+
55
+ get_mongo_db do |db|
56
+ db.collection("infochimps.config").find_one({:_id => "power"}).should be_nil
57
+ end
58
+ end
59
+ end
60
+
13
61
  it 'stores events' do
14
62
  with_api(HttpShim) do |api|
15
63
  post_request({
@@ -19,6 +67,13 @@ describe HttpShim do
19
67
  c.response_header.status.should == 200
20
68
  MultiJson.load(c.response).should eql ({"level" => "awesome"})
21
69
  end
70
+
71
+ get_mongo_db do |db|
72
+ doc = db.collection("infochimps.power.events").find_one({:_id => "level"})
73
+ doc["_id"].should eql "level"
74
+ doc["d"].should eql ({"level" => "awesome"})
75
+ doc["t"].should be_within(1).of Time.now
76
+ end
22
77
  end
23
78
  end
24
79
 
@@ -8,13 +8,19 @@ Settings.define 'mongo.port', :default => '27017', :description => 'Mongo
8
8
  Settings.read(File.join File.dirname(__FILE__), '..', '..', 'config', 'vayacondios.yaml')
9
9
  Settings.resolve!
10
10
 
11
- def clean_mongo
11
+ def get_mongo_db &block
12
+ fail unless block
12
13
  conn = Mongo::Connection.new(Settings[:mongo][:host],Settings[:mongo][:port])
13
- mongo = conn.db(Settings[:mongo][:database])
14
- mongo.collections.select {|c| c.name !~ /system/ }.each { |c| c.drop }
14
+ yield conn.db(Settings[:mongo][:database])
15
15
  conn.close
16
16
  end
17
17
 
18
+ def clean_mongo
19
+ get_mongo_db do |db|
20
+ db.collections.select {|c| c.name !~ /system/ }.each { |c| c.drop }
21
+ end
22
+ end
23
+
18
24
  RSpec.configure do |config|
19
25
  config.before :each do
20
26
  clean_mongo
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vayacondios-server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2012-09-06 00:00:00.000000000 Z
15
+ date: 2012-09-07 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: configliere
@@ -204,6 +204,7 @@ files:
204
204
  - lib/vayacondios/client/configliere.rb
205
205
  - lib/vayacondios/client/http_client.rb
206
206
  - lib/vayacondios/client/notifier.rb
207
+ - lib/vayacondios/server/errors/bad_request.rb
207
208
  - lib/vayacondios/server/handlers/config_handler.rb
208
209
  - lib/vayacondios/server/handlers/event_handler.rb
209
210
  - lib/vayacondios/server/model/config_document.rb
@@ -240,7 +241,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
241
  version: '0'
241
242
  segments:
242
243
  - 0
243
- hash: 3434748867277747031
244
+ hash: -662112230859084251
244
245
  required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  none: false
246
247
  requirements:
@@ -249,7 +250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
250
  version: '0'
250
251
  segments:
251
252
  - 0
252
- hash: 3434748867277747031
253
+ hash: -662112230859084251
253
254
  requirements: []
254
255
  rubyforge_project:
255
256
  rubygems_version: 1.8.23