vayacondios-server 0.2.11 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/.gitignore +3 -1
  2. data/.travis.yml +2 -0
  3. data/Gemfile +15 -9
  4. data/LICENSE.md +2 -6
  5. data/Procfile +1 -1
  6. data/README.md +656 -111
  7. data/Rakefile +89 -6
  8. data/bin/vcd +10 -0
  9. data/bin/vcd-server +8 -0
  10. data/config/database.yml +6 -0
  11. data/config/spec.example.yml +18 -0
  12. data/config/vayacondios.example.yml +15 -0
  13. data/config/vcd-server.rb +37 -0
  14. data/examples/configuration.rb +56 -0
  15. data/examples/event_stream.rb +19 -0
  16. data/examples/simple.rb +61 -0
  17. data/features/event.feature +319 -0
  18. data/features/events.feature +208 -0
  19. data/features/stash.feature +840 -0
  20. data/features/stashes.feature +492 -0
  21. data/features/step_definitions/stash_steps.rb +113 -0
  22. data/features/stream.feature +30 -0
  23. data/features/support/em.rb +14 -0
  24. data/features/support/env.rb +13 -0
  25. data/lib/vayacondios/configuration.rb +63 -0
  26. data/lib/vayacondios/server/api.rb +126 -0
  27. data/lib/vayacondios/server/api_options.rb +56 -0
  28. data/lib/vayacondios/server/configuration.rb +23 -0
  29. data/lib/vayacondios/server/driver.rb +71 -0
  30. data/lib/vayacondios/server/drivers/mongo.rb +126 -0
  31. data/lib/vayacondios/server/handlers/document_handler.rb +81 -0
  32. data/lib/vayacondios/server/handlers/event_handler.rb +31 -26
  33. data/lib/vayacondios/server/handlers/events_handler.rb +31 -0
  34. data/lib/vayacondios/server/handlers/stash_handler.rb +69 -0
  35. data/lib/vayacondios/server/handlers/stashes_handler.rb +49 -0
  36. data/lib/vayacondios/server/handlers/stream_handler.rb +39 -0
  37. data/lib/vayacondios/server/models/document.rb +87 -0
  38. data/lib/vayacondios/server/models/event.rb +198 -0
  39. data/lib/vayacondios/server/models/stash.rb +100 -0
  40. data/lib/vayacondios/server.rb +35 -0
  41. data/lib/vayacondios-server.rb +19 -13
  42. data/lib/vayacondios.rb +22 -0
  43. data/pom.xml +124 -4
  44. data/spec/configuration_spec.rb +41 -0
  45. data/spec/server/api_options_spec.rb +32 -0
  46. data/spec/server/api_spec.rb +279 -0
  47. data/spec/server/configuration_spec.rb +27 -0
  48. data/spec/server/drivers/mongo_spec.rb +107 -0
  49. data/spec/server/handlers/event_handler_spec.rb +62 -0
  50. data/spec/server/handlers/events_handler_spec.rb +51 -0
  51. data/spec/server/handlers/stash_handler_spec.rb +68 -0
  52. data/spec/server/handlers/stashes_handler_spec.rb +50 -0
  53. data/spec/server/handlers/stream_handler_spec.rb +5 -0
  54. data/spec/server/models/document_spec.rb +9 -0
  55. data/spec/server/models/event_spec.rb +185 -0
  56. data/spec/server/models/stash_spec.rb +95 -0
  57. data/spec/spec_helper.rb +23 -3
  58. data/spec/support/database_helper.rb +42 -0
  59. data/spec/support/log_helper.rb +19 -0
  60. data/spec/support/shared_context_for_events.rb +22 -0
  61. data/spec/support/shared_context_for_stashes.rb +24 -0
  62. data/spec/support/shared_examples_for_handlers.rb +32 -0
  63. data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
  64. data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
  65. data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +487 -65
  66. data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
  67. data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
  68. data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
  69. data/vayacondios-server.gemspec +9 -9
  70. metadata +127 -122
  71. checksums.yaml +0 -15
  72. data/.rspec +0 -2
  73. data/.yardopts +0 -10
  74. data/Guardfile +0 -41
  75. data/app/http_shim.rb +0 -71
  76. data/bin/vcd.sh +0 -27
  77. data/config/http_shim.rb +0 -43
  78. data/config/vayacondios.example.yaml +0 -7
  79. data/config/vayacondios.yaml +0 -7
  80. data/examples/java/ItemSetTest.java +0 -76
  81. data/lib/tasks/publish.rake +0 -23
  82. data/lib/tasks/spec.rake +0 -11
  83. data/lib/tasks/yard.rake +0 -2
  84. data/lib/vayacondios/client/config.rb +0 -7
  85. data/lib/vayacondios/client/configliere.rb +0 -38
  86. data/lib/vayacondios/client/cube_client.rb +0 -39
  87. data/lib/vayacondios/client/http_client.rb +0 -49
  88. data/lib/vayacondios/client/itemset.rb +0 -130
  89. data/lib/vayacondios/client/legacy_switch.rb +0 -43
  90. data/lib/vayacondios/client/notifier.rb +0 -123
  91. data/lib/vayacondios/client/zabbix_client.rb +0 -148
  92. data/lib/vayacondios/legacy_switch.rb +0 -43
  93. data/lib/vayacondios/server/errors/bad_request.rb +0 -6
  94. data/lib/vayacondios/server/errors/not_found.rb +0 -6
  95. data/lib/vayacondios/server/handlers/config_handler.rb +0 -32
  96. data/lib/vayacondios/server/handlers/itemset_handler.rb +0 -60
  97. data/lib/vayacondios/server/legacy_switch.rb +0 -43
  98. data/lib/vayacondios/server/model/config_document.rb +0 -89
  99. data/lib/vayacondios/server/model/document.rb +0 -25
  100. data/lib/vayacondios/server/model/event_document.rb +0 -94
  101. data/lib/vayacondios/server/model/itemset_document.rb +0 -126
  102. data/lib/vayacondios/server/rack/extract_methods.rb +0 -35
  103. data/lib/vayacondios/server/rack/jsonize.rb +0 -43
  104. data/lib/vayacondios/server/rack/params.rb +0 -50
  105. data/lib/vayacondios/server/rack/path.rb +0 -23
  106. data/lib/vayacondios/server/rack/path_validation.rb +0 -22
  107. data/lib/vayacondios/version.rb +0 -3
  108. data/lib/vayacondios-client.rb +0 -22
  109. data/scripts/hadoop_monitor/configurable.rb +0 -66
  110. data/scripts/hadoop_monitor/hadoop_attempt_scraper.rb +0 -45
  111. data/scripts/hadoop_monitor/hadoop_client.rb +0 -273
  112. data/scripts/hadoop_monitor/hadoop_monitor.rb +0 -101
  113. data/scripts/hadoop_monitor/hadoopable.rb +0 -65
  114. data/scripts/hadoop_monitor/machine_monitor.rb +0 -115
  115. data/scripts/s3_cataloger/buckets +0 -33
  116. data/scripts/s3_cataloger/foreach_bucket +0 -88
  117. data/scripts/s3_cataloger/parse_ls.py +0 -391
  118. data/spec/client/itemset_legacy_spec.rb +0 -55
  119. data/spec/client/itemset_spec.rb +0 -60
  120. data/spec/client/notifier_spec.rb +0 -120
  121. data/spec/server/config_spec.rb +0 -113
  122. data/spec/server/event_spec.rb +0 -103
  123. data/spec/server/itemset_legacy_spec.rb +0 -320
  124. data/spec/server/itemset_spec.rb +0 -317
  125. data/spec/server/rack/extract_methods_spec.rb +0 -60
  126. data/spec/server/rack/path_spec.rb +0 -36
  127. data/spec/server/rack/path_validation_spec.rb +0 -22
  128. data/spec/server/server_spec.rb +0 -20
  129. data/spec/support/mongo_cleaner.rb +0 -32
  130. data/src/main/java/ItemSetTest.java +0 -76
  131. data/src/main/java/com/infochimps/util/CurrentClass.java +0 -26
  132. data/src/main/java/com/infochimps/util/DebugUtil.java +0 -38
  133. data/src/main/java/com/infochimps/util/HttpHelper.java +0 -181
  134. data/src/main/java/com/infochimps/vayacondios/ItemSets.java +0 -373
  135. data/src/main/java/com/infochimps/vayacondios/LinkToVCD.java +0 -18
  136. data/src/main/java/com/infochimps/vayacondios/MemoryVCDShim.java +0 -84
  137. data/src/main/java/com/infochimps/vayacondios/Organization.java +0 -62
  138. data/src/main/java/com/infochimps/vayacondios/PathBuilder.java +0 -13
  139. data/src/main/java/com/infochimps/vayacondios/StandardVCDLink.java +0 -218
  140. data/src/main/java/com/infochimps/vayacondios/VCDIntegrationTest.java +0 -108
  141. data/src/test/java/com/infochimps/vayacondios/TestVayacondiosInMemory.java +0 -78
  142. data/vayacondios-client.gemspec +0 -25
data/Rakefile CHANGED
@@ -1,10 +1,93 @@
1
- # -*- ruby -*-
1
+ require 'rspec/core/rake_task'
2
2
 
3
- require 'bundler' ; Bundler.setup
3
+ namespace :spec do
4
4
 
5
- require 'configliere'
5
+ desc 'Run client RSpec code examples'
6
+ RSpec::Core::RakeTask.new(:client) do |t|
7
+ t.pattern = 'spec/client/**/*_spec.rb'
8
+ end
9
+
10
+ desc 'Run server RSpec code examples'
11
+ RSpec::Core::RakeTask.new(:server) do |t|
12
+ t.pattern = 'spec/server/**/*_spec.rb'
13
+ end
14
+ end
6
15
 
7
- # App-specific tasks
8
- Dir[File.dirname(__FILE__)+'/lib/tasks/**/*.rake'].sort.each{|f| load f }
16
+ desc 'Run both client and server Rspec code examples'
17
+ RSpec::Core::RakeTask.new
18
+
19
+ desc 'Run spec tests with simplecov'
20
+ task :coverage do
21
+ ENV['VAYACONDIOS_COV'] = 'true'
22
+ Rake::Task[:spec].invoke
23
+ end
24
+
25
+ def with_background_process(cmd, options = {}, &blk)
26
+ pr = spawn cmd
27
+ puts "waiting for command #{cmd} to execute fully"
28
+ sleep(options[:wait]) if options[:wait]
29
+ blk.call
30
+ ensure
31
+ Process.kill('KILL', pr)
32
+ Process.wait pr
33
+ end
34
+
35
+ desc 'Run spec coverage with mongo'
36
+ task :mongo do
37
+ # with_background_process('mongod') do
38
+ ENV['WITH_MONGO'] = 'true'
39
+ Rake::Task[:spec].invoke
40
+ # end
41
+ end
42
+
43
+ desc 'Run integration tests'
44
+ task :integration do
45
+ # with_background_process('mongod') do
46
+ with_background_process('bin/vcd-server -e test', wait: 2) do
47
+ Rake::Task[:features].invoke
48
+ end
49
+ # end
50
+ end
51
+
52
+ require 'cucumber/rake/task'
53
+ Cucumber::Rake::Task.new(:features)
54
+
55
+ require 'yard'
56
+ YARD::Rake::YardocTask.new do |t|
57
+ t.files = ['lib/**/*.rb', '-', 'CHANGELOG.md', 'LICENSE.md']
58
+ t.options = ['--readme=README.md', '--markup=markdown', '--verbose']
59
+ end
60
+
61
+ require 'vayacondios'
62
+ Dir['*.gemspec'].each do |gemspec|
63
+ gem_name = gemspec.gsub(/\.gemspec/, '')
64
+
65
+ namespace :build do
66
+ desc "Build #{gem_name} gem into the pkg directory"
67
+ task gem_name do
68
+ system "gem build #{gemspec}"
69
+ FileUtils.mkdir_p('pkg')
70
+ FileUtils.mv(Dir['*.gem'], 'pkg')
71
+ end
72
+ end
73
+
74
+ namespace :release do
75
+ desc "Tags version, pushes to remote, and pushes #{gem_name} gem"
76
+ task gem_name => "build:#{gem_name}" do
77
+ sh 'git', 'tag', '-m', "releasing #{gem_name}", "#{gem_name}-v#{Vayacondios::GEM_VERSION}"
78
+ branch = `git branch | awk -F '/* ' '{print $2}'`.strip
79
+ sh "git push origin #{branch}"
80
+ sh "git push origin #{gem_name}-v#{Vayacondios::GEM_VERSION}"
81
+ sh "ls pkg/#{gem_name}*.gem | xargs -n 1 gem push"
82
+ end
83
+ end
84
+ end
85
+
86
+ desc 'Build both gems'
87
+ task build: ['build:vayacondios-client', 'build:vayacondios-server']
88
+
89
+ desc 'Release both gems'
90
+ task release: ['release:vayacondios-client', 'release:vayacondios-server']
91
+
92
+ task default: [:mongo, :integration]
9
93
 
10
- task :default => :spec
data/bin/vcd ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ vayacondios_gemfile = File.expand_path('../../Gemfile', File.realdirpath(__FILE__))
4
+ ENV['BUNDLE_GEMFILE'] = vayacondios_gemfile
5
+
6
+ require 'bundler'
7
+ Bundler.setup(:default)
8
+
9
+ require 'vayacondios/client/cli'
10
+ Vayacondios::Client::CLI.run
data/bin/vcd-server ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ vayacondios_gemfile = File.expand_path('../../Gemfile', File.realdirpath(__FILE__))
4
+ ENV['BUNDLE_GEMFILE'] = vayacondios_gemfile
5
+
6
+ require 'bundler'
7
+ Bundler.setup(:default)
8
+ require 'vayacondios/server/api'
@@ -0,0 +1,6 @@
1
+ ---
2
+ test:
3
+ name: vayacondios_test
4
+ driver: mongo
5
+ host: localhost
6
+ port: 27017
@@ -0,0 +1,18 @@
1
+ # During normal operation, configuration values like the location of a
2
+ # MongoDB server are passed to Vayacondios server via the
3
+ # command-line.
4
+ #
5
+ # During integration tests (which must instantiate a Vayacondios
6
+ # server *without* a command line) this file is used to specify the
7
+ # location of a MongoDB to use for testing.
8
+ #
9
+ # *WARNING*: The database named here will be emptied of data during
10
+ # *the running of tests.
11
+ #
12
+ # @see spec/spec_helper.rb for the code which reads this file
13
+ # @see spec/support/mongo_helper.rb for the
14
+ ---
15
+ mongo:
16
+ host: localhost
17
+ port: 27017
18
+ database: vayacondios_development
@@ -0,0 +1,15 @@
1
+ # This is an example configuration for the Vayacondios client program
2
+ # `vcd`.
3
+ #
4
+ # You can copy this file to /etc/vayacondios/vayacondios.yml or
5
+ # ~/.vayacondios.yml to have the `vcd` program read it on startup.
6
+ #
7
+ # This provides a convenient way of providing shared access to a
8
+ # Vayacondios server from a given machine.
9
+ #
10
+ # @see Vayacondios::CLI which reads this configuration file
11
+
12
+ ---
13
+ host: localhost
14
+ port: 9000
15
+ organization: example
@@ -0,0 +1,37 @@
1
+ # This configuration script provides several example configurations of
2
+ # Vayacondios server.
3
+ #
4
+ # You can use any of these environments by specifying the
5
+ # --environment or -e flag to `vcd-server`.
6
+ #
7
+ # @see Vayacondios::HttpServer for where the database connection is
8
+ # passed to the rest of the application code.
9
+
10
+ # The production environment uses EventMachine::Synchrony to define a
11
+ # shared pool of open connections to the database. The size of this pool
12
+ # can be on the command-line with the --database.connections option.
13
+ Vayacondios::Server::DbConfig.overlay options[:database]
14
+
15
+ environment(:production) do
16
+ db_options = Vayacondios::Server::DbConfig.env :production
17
+ driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
18
+ logger.info("Opening #{db_options[:connections]} connections to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
19
+ config['db'] = EventMachine::Synchrony::ConnectionPool.new(size: db_options[:connections]) do
20
+ driver.connect db_options.merge(log: logger)
21
+ end
22
+ end
23
+
24
+ # The development environment uses a single database connection.
25
+ environment(:development) do
26
+ db_options = Vayacondios::Server::DbConfig.env :development
27
+ driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
28
+ logger.info("Connecting to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
29
+ config['db'] = driver.connect db_options.merge(log: logger)
30
+ end
31
+
32
+ environment(:test) do
33
+ db_options = Vayacondios::Server::DbConfig.env :test
34
+ driver = Vayacondios::Server::Driver.retrieve db_options[:driver]
35
+ logger.info("Connecting to #{db_options[:host]}:#{db_options[:port]} using #{driver}.")
36
+ config['db'] = driver.connect db_options.merge(log: logger)
37
+ end
@@ -0,0 +1,56 @@
1
+ # All examples assume a running Vayacondios server on localhost:3467
2
+ # with a backing database.
3
+ #
4
+ # bundle exec ruby examples/configuration.rb
5
+ require 'vayacondios/client'
6
+
7
+ # Setting up connection options
8
+ #
9
+ # Vcd::Client::ConnectionOpts reads from the following in order:
10
+ # * library defaults (Vcd::Client::ConnectionOpts.defaults
11
+ # * /etc/vayacondios/vayacondios.yml
12
+ # * $PWD/config/vayacondios.yml
13
+ # * any overlays applied using ConnectionOpts.overlay
14
+
15
+ # Change the base file_name from 'vayacondios.yml'
16
+ Vcd::Client::ConnectionOpts.base_filename = 'foo.yml'
17
+
18
+ # Change the config load order
19
+ Vcd::Client::ConnectionOpts.load_order = %w[ global local ]
20
+
21
+ # Load order calls methods that expect either a Hash or a String filename returned
22
+ Vcd::Client::ConnectionOpts.define_singleton_method(:local) do
23
+ '/path/to/local/config_file'
24
+ end
25
+
26
+ # Override configuration for further Vcd connections
27
+ Vcd::Client::ConnectionOpts.overlay(adapter: :net_http)
28
+
29
+ # As soon as the options are used they become resolved and cannot be changed
30
+ puts Vcd::Client::ConnectionOpts[:adapter]
31
+ puts Vcd::Client::ConnectionOpts.resolved?
32
+ Vcd::Client::ConnectionOpts.overlay(adapter: :em_http)
33
+ Vcd::Client::ConnectionOpts.resolve!
34
+ puts Vcd::Client::ConnectionOpts.resolved_settings
35
+
36
+ # Create a new connection with options
37
+ Vcd::Client::Connection.factory(host: 'foo', port: 1234)
38
+
39
+ # Mixin the http modules and get access to a memoized connection and client methods
40
+ class MyClass
41
+ include Vcd::Client::HttpRead
42
+ include Vcd::Client::HttpWrite
43
+ include Vcd::Client::HttpAdmin
44
+ end
45
+
46
+ my_class = MyClass.new
47
+ puts my_class.http_connection
48
+
49
+ # override memoized connection options for this instance only
50
+ puts my_class.configure_connection(host: 'localhost')
51
+
52
+ # utilize client http methods
53
+ response = my_class.set('id', nil, foo: 'bar')
54
+ puts response.body
55
+ response = my_class.unset('id')
56
+ puts response.body
@@ -0,0 +1,19 @@
1
+ # All examples assume a running Vayacondios server on localhost:3467
2
+ # with a backing database.
3
+ #
4
+ # bundle exec ruby examples/event_stream.rb
5
+ require 'vayacondios/client'
6
+
7
+ client = Vcd::Client::HttpClient.new(organization: 'github')
8
+
9
+ client.stream('commit') do |event|
10
+ line = "#{event['time']} | #{event['username']}: #{event['sha']} => #{event['message']}"
11
+ puts line
12
+ end
13
+
14
+ # In another window:
15
+ # curl -X POST 'http://localhost:3467/v3/github/event/commit' -d '{"username":"Jack","sha":"123abc","message":"watup"}'
16
+ # curl -X POST 'http://localhost:3467/v3/github/event/commit' -d '{"username":"Jill","sha":"abc123","message":"yoyo"}'
17
+ #
18
+ # To remove the event topic:
19
+ # curl -X DELETE 'http://localhost:3467/v3/github/events/commit'
@@ -0,0 +1,61 @@
1
+ # All examples assume a running Vayacondios server on localhost:3467
2
+ # with a backing database.
3
+ #
4
+ # bundle exec ruby examples/simple.rb
5
+ require 'vayacondios/client'
6
+
7
+ # Basic client usage
8
+ client = Vcd::Client::HttpClient.new(organization: 'github')
9
+
10
+ # Events
11
+ client.announce('commit', username: 'Jack', sha: '123abc', message: 'watup')
12
+ puts client.events('commit').body.inspect
13
+ puts client.clear_events('commit').body.inspect
14
+
15
+ # Stashes
16
+ client.set(123, nil, user_name: 'jimbob', user_id: 123, group: 'admin')
17
+ puts client.get(123).body
18
+
19
+ # Mixin Vcd functionality
20
+ class SimpleModel
21
+ extend Vcd::Client::HttpRead
22
+ include Vcd::Client::HttpWrite
23
+ include Vcd::Client::HttpAdmin
24
+
25
+ # Must respond to organization for requests to be formed correctly
26
+ # default is 'vayacondios'
27
+ def self.organization() 'github' ; end
28
+
29
+ def self.find topic
30
+ data = get(topic).body
31
+ self.new data
32
+ end
33
+
34
+ attr_accessor :user_name, :user_id, :group
35
+
36
+ def initialize(data = {})
37
+ @user_name = data['user_name']
38
+ @user_id = data['user_id']
39
+ @group = data['group']
40
+ end
41
+
42
+ def organization
43
+ self.class.organization
44
+ end
45
+
46
+ def to_hash
47
+ { user_name: user_name, user_id: user_id, group: group }
48
+ end
49
+
50
+ def save
51
+ set(user_id, nil, to_hash)
52
+ end
53
+
54
+ def destroy!
55
+ unset(user_id)
56
+ end
57
+ end
58
+
59
+ model = SimpleModel.find('123')
60
+ puts model.to_hash
61
+ model.destroy!
@@ -0,0 +1,319 @@
1
+ Feature: Event
2
+ In order to provide functionality
3
+ As a user of the Vayacondios Api
4
+ I want to document how an Event works
5
+
6
+ Scenario: Retrieving an Event without an Id
7
+ Given there are no Events under topic "topic" in the database
8
+ When the client sends a GET request to "/v3/organization/event/topic" with no body
9
+ Then the response status should be 400
10
+ And the response body should be:
11
+ """
12
+ {
13
+ "error": "Cannot find an event without an ID"
14
+ }
15
+ """
16
+
17
+ Scenario: Retrieving a non-Existent Event with an Id
18
+ Given there are no Events under topic "topic" in the database
19
+ When the client sends a GET request to "/v3/organization/event/topic/id" with no body
20
+ Then the response status should be 404
21
+ And the response body should be:
22
+ """
23
+ {
24
+ "error": "Event with topic <topic> and ID <id> not found"
25
+ }
26
+ """
27
+
28
+ Scenario: Retrieving an Existing Event with an Id
29
+ Given the following Event exists under topic "topic" in the database:
30
+ """
31
+ {
32
+ "_id": "id",
33
+ "_t": "2012-02-13T12:34:42.452Z",
34
+ "_d": {
35
+ "time": "2012-02-13T12:34:42.452Z"
36
+ }
37
+ }
38
+ """
39
+ When the client sends a GET request to "/v3/organization/event/topic/id" with no body
40
+ Then the response status should be 200
41
+ And the response body should be:
42
+ """
43
+ {
44
+ "id": "id",
45
+ "time": "2012-02-13T12:34:42.452Z"
46
+ }
47
+ """
48
+
49
+ Scenario: Creating an Empty Event without an Id
50
+ Given there are no Events under topic "topic" in the database
51
+ When the client sends a POST request to "/v3/organization/event/topic" with no body
52
+ Then the response status should be 200
53
+ And the response body should contain a generated timestamp
54
+ And the response body should contain a randomly assigned Id
55
+ And there is exactly one Event under topic "topic" in the database
56
+
57
+ Scenario: Creating a Hash Event without an Id
58
+ Given there are no Events under topic "topic" in the database
59
+ When the client sends a POST request to "/v3/organization/event/topic" with the following body:
60
+ """
61
+ {
62
+ "foo": "bar"
63
+ }
64
+ """
65
+ Then the response status should be 200
66
+ And the response body should contain:
67
+ """
68
+ {
69
+ "foo": "bar"
70
+ }
71
+ """
72
+ And the response body should contain a generated timestamp
73
+ And the response body should contain a randomly assigned Id
74
+ And there is exactly one Event under topic "topic" in the database
75
+
76
+ Scenario: Creating a Hash Event without an Id, specifying a time
77
+ Given there are no Events under topic "topic" in the database
78
+ When the client sends a POST request to "/v3/organization/event/topic" with the following body:
79
+ """
80
+ {
81
+ "foo": "bar",
82
+ "time": "2012-02-13T12:34:42.452Z"
83
+ }
84
+ """
85
+ Then the response status should be 200
86
+ And the response body should contain:
87
+ """
88
+ {
89
+ "foo": "bar",
90
+ "time": "2012-02-13T12:34:42.452Z"
91
+ }
92
+ """
93
+ And the response body should contain a randomly assigned Id
94
+ And there is exactly one Event under topic "topic" in the database
95
+
96
+ Scenario: Creating a non-Hash Event without an Id
97
+ Given there are no Events under topic "topic" in the database
98
+ When the client sends a POST request to "/v3/organization/event/topic" with the following body:
99
+ """
100
+ [
101
+ "foo",
102
+ "bar"
103
+ ]
104
+ """
105
+ Then the response status should be 400
106
+ And the response body should be:
107
+ """
108
+ {
109
+ "error": "Events must be Hash-like to create"
110
+ }
111
+ """
112
+ And there are no Events under topic "topic" in the database
113
+
114
+ Scenario: Creating an Empty Event with an Id
115
+ Given there are no Events under topic "topic" in the database
116
+ When the client sends a POST request to "/v3/organization/event/topic/id" with no body
117
+ Then the response status should be 200
118
+ And the response body should contain:
119
+ """
120
+ {
121
+ "id": "id"
122
+ }
123
+ """
124
+ And the response body should contain a generated timestamp
125
+ And there should be an Event with Id "id" under topic "topic" in the database
126
+
127
+ Scenario: Creating a Hash Event with an Id
128
+ Given there are no Events under topic "topic" in the database
129
+ When the client sends a POST request to "/v3/organization/event/topic/id" with the following body:
130
+ """
131
+ {
132
+ "foo": "bar"
133
+ }
134
+ """
135
+ Then the response status should be 200
136
+ And the response body should contain:
137
+ """
138
+ {
139
+ "foo": "bar",
140
+ "id": "id"
141
+ }
142
+ """
143
+ And the response body should contain a generated timestamp
144
+ And there should be an Event with Id "id" under topic "topic" in the database
145
+
146
+ Scenario: Creating a Hash Event with an Id, specifying a time
147
+ Given there are no Events under topic "topic" in the database
148
+ When the client sends a POST request to "/v3/organization/event/topic/id" with the following body:
149
+ """
150
+ {
151
+ "foo": "bar",
152
+ "time": "2012-02-13T12:34:42.452Z"
153
+ }
154
+ """
155
+ Then the response status should be 200
156
+ And the response body should be:
157
+ """
158
+ {
159
+ "id": "id",
160
+ "foo": "bar",
161
+ "time": "2012-02-13T12:34:42.452Z"
162
+ }
163
+ """
164
+ And the database should have the following Event under topic "topic":
165
+ """
166
+ {
167
+ "_id": "id",
168
+ "_t": "2012-02-13T12:34:42.452Z",
169
+ "_d": {
170
+ "foo": "bar"
171
+ }
172
+ }
173
+ """
174
+
175
+ Scenario: Creating a non-Hash Event with an Id
176
+ Given there are no Events under topic "topic" in the database
177
+ When the client sends a POST request to "/v3/organization/event/topic/id" with the following body:
178
+ """
179
+ [
180
+ "foo",
181
+ "bar"
182
+ ]
183
+ """
184
+ Then the response status should be 400
185
+ And the response body should be:
186
+ """
187
+ {
188
+ "error": "Events must be Hash-like to create"
189
+ }
190
+ """
191
+ And there are no Events under topic "topic" in the database
192
+
193
+ Scenario: Creating an Event with an Id that Already Exists
194
+ Given the following Event exists under topic "topic" in the database:
195
+ """
196
+ {
197
+ "_id": "id",
198
+ "_t": "2012-02-13T12:34:42.452Z",
199
+ "_d": {
200
+ "foo": "bar"
201
+ }
202
+ }
203
+ """
204
+ When the client sends a POST request to "/v3/organization/event/topic/id" with the following body:
205
+ """
206
+ {
207
+ "time": "2013-01-01T00:00:00.000Z",
208
+ "new": "body"
209
+ }
210
+ """
211
+ Then the response status should be 200
212
+ And the response body should be:
213
+ """
214
+ {
215
+ "id": "id",
216
+ "new": "body",
217
+ "time": "2013-01-01T00:00:00.000Z"
218
+ }
219
+ """
220
+ And the database should have the following Event under topic "topic":
221
+ """
222
+ {
223
+ "_id": "id",
224
+ "_t": "2013-01-01T00:00:00.000Z",
225
+ "_d": {
226
+ "new": "body"
227
+ }
228
+ }
229
+ """
230
+
231
+ Scenario: Updating an Event without an Id
232
+ Given the following Event exists under topic "topic" in the database:
233
+ """
234
+ {
235
+ "_id": "id",
236
+ "_t": "2012-02-13T12:34:42.452Z",
237
+ "_d": { }
238
+ }
239
+ """
240
+ When the client sends a PUT request to "/v3/organization/event/topic" with the following body:
241
+ """
242
+ {
243
+ "foo": "bar"
244
+ }
245
+ """
246
+ Then the response status should be 405
247
+ And the response body should be:
248
+ """
249
+ {
250
+ "error": "Operation update not allowed for Vayacondios::Server::EventHandler. Valid operations are [\"create\", \"retrieve\", \"delete\"]"
251
+ }
252
+ """
253
+
254
+ Scenario: Updating an Event with an Id
255
+ Given the following Event exists under topic "topic" in the database:
256
+ """
257
+ {
258
+ "_id": "id",
259
+ "_t": "2012-02-13T12:34:42.452Z",
260
+ "_d": {
261
+ "time": "2012-02-13T12:34:42.452Z"
262
+ }
263
+ }
264
+ """
265
+ When the client sends a PUT request to "/v3/organization/event/topic/id" with the following body:
266
+ """
267
+ {
268
+ "foo": "bar"
269
+ }
270
+ """
271
+ Then the response status should be 405
272
+ And the response body should be:
273
+ """
274
+ {
275
+ "error": "Operation update not allowed for Vayacondios::Server::EventHandler. Valid operations are [\"create\", \"retrieve\", \"delete\"]"
276
+ }
277
+ """
278
+
279
+ Scenario: Deleting an Event
280
+ Given the following Event exists under topic "topic" in the database:
281
+ """
282
+ {
283
+ "_id": "id",
284
+ "_t": "2012-02-13T12:34:42.452Z",
285
+ "_d": {
286
+ "time": "2012-02-13T12:34:42.452Z"
287
+ }
288
+ }
289
+ """
290
+ When the client sends a DELETE request to "/v3/organization/event/topic" with no body
291
+ Then the response status should be 400
292
+ And the response body should be:
293
+ """
294
+ {
295
+ "error": "An <Id> is required to delete an Event"
296
+ }
297
+ """
298
+ And there should be an Event with Id "id" under topic "topic" in the database
299
+
300
+ Scenario: Deleting an Event with an Id
301
+ Given the following Event exists under topic "topic" in the database:
302
+ """
303
+ {
304
+ "_id": "id",
305
+ "_t": "2012-02-13T12:34:42.452Z",
306
+ "_d": {
307
+ "time": "2012-02-13T12:34:42.452Z"
308
+ }
309
+ }
310
+ """
311
+ When the client sends a DELETE request to "/v3/organization/event/topic/id" with no body
312
+ Then the response status should be 200
313
+ And the response body should be:
314
+ """
315
+ {
316
+ "ok": true
317
+ }
318
+ """
319
+ And there are no Events under topic "topic" in the database