vayacondios-server 0.2.11 → 0.3.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 +3 -1
- data/.travis.yml +2 -0
- data/Gemfile +15 -9
- data/LICENSE.md +2 -6
- data/Procfile +1 -1
- data/README.md +656 -111
- data/Rakefile +89 -6
- data/bin/vcd +10 -0
- data/bin/vcd-server +8 -0
- data/config/database.yml +6 -0
- data/config/spec.example.yml +18 -0
- data/config/vayacondios.example.yml +15 -0
- data/config/vcd-server.rb +37 -0
- data/examples/configuration.rb +56 -0
- data/examples/event_stream.rb +19 -0
- data/examples/simple.rb +61 -0
- data/features/event.feature +319 -0
- data/features/events.feature +208 -0
- data/features/stash.feature +840 -0
- data/features/stashes.feature +492 -0
- data/features/step_definitions/stash_steps.rb +113 -0
- data/features/stream.feature +30 -0
- data/features/support/em.rb +14 -0
- data/features/support/env.rb +13 -0
- data/lib/vayacondios/configuration.rb +63 -0
- data/lib/vayacondios/server/api.rb +126 -0
- data/lib/vayacondios/server/api_options.rb +56 -0
- data/lib/vayacondios/server/configuration.rb +23 -0
- data/lib/vayacondios/server/driver.rb +71 -0
- data/lib/vayacondios/server/drivers/mongo.rb +126 -0
- data/lib/vayacondios/server/handlers/document_handler.rb +81 -0
- data/lib/vayacondios/server/handlers/event_handler.rb +31 -26
- data/lib/vayacondios/server/handlers/events_handler.rb +31 -0
- data/lib/vayacondios/server/handlers/stash_handler.rb +69 -0
- data/lib/vayacondios/server/handlers/stashes_handler.rb +49 -0
- data/lib/vayacondios/server/handlers/stream_handler.rb +39 -0
- data/lib/vayacondios/server/models/document.rb +87 -0
- data/lib/vayacondios/server/models/event.rb +198 -0
- data/lib/vayacondios/server/models/stash.rb +100 -0
- data/lib/vayacondios/server.rb +35 -0
- data/lib/vayacondios-server.rb +19 -13
- data/lib/vayacondios.rb +22 -0
- data/pom.xml +124 -4
- data/spec/configuration_spec.rb +41 -0
- data/spec/server/api_options_spec.rb +32 -0
- data/spec/server/api_spec.rb +279 -0
- data/spec/server/configuration_spec.rb +27 -0
- data/spec/server/drivers/mongo_spec.rb +107 -0
- data/spec/server/handlers/event_handler_spec.rb +62 -0
- data/spec/server/handlers/events_handler_spec.rb +51 -0
- data/spec/server/handlers/stash_handler_spec.rb +68 -0
- data/spec/server/handlers/stashes_handler_spec.rb +50 -0
- data/spec/server/handlers/stream_handler_spec.rb +5 -0
- data/spec/server/models/document_spec.rb +9 -0
- data/spec/server/models/event_spec.rb +185 -0
- data/spec/server/models/stash_spec.rb +95 -0
- data/spec/spec_helper.rb +23 -3
- data/spec/support/database_helper.rb +42 -0
- data/spec/support/log_helper.rb +19 -0
- data/spec/support/shared_context_for_events.rb +22 -0
- data/spec/support/shared_context_for_stashes.rb +24 -0
- data/spec/support/shared_examples_for_handlers.rb +32 -0
- data/src/main/java/com/infochimps/vayacondios/BaseClient.java +342 -0
- data/src/main/java/com/infochimps/vayacondios/HTTPClient.java +426 -0
- data/src/main/java/com/infochimps/vayacondios/VayacondiosClient.java +487 -65
- data/src/main/java/com/infochimps/vayacondios/test/IntegrationTest.java +3 -0
- data/src/test/java/com/infochimps/vayacondios/BaseClientTest.java +50 -0
- data/src/test/java/com/infochimps/vayacondios/HTTPClientIT.java +267 -0
- data/vayacondios-server.gemspec +9 -9
- metadata +127 -122
- checksums.yaml +0 -15
- data/.rspec +0 -2
- data/.yardopts +0 -10
- data/Guardfile +0 -41
- data/app/http_shim.rb +0 -71
- data/bin/vcd.sh +0 -27
- data/config/http_shim.rb +0 -43
- data/config/vayacondios.example.yaml +0 -7
- data/config/vayacondios.yaml +0 -7
- data/examples/java/ItemSetTest.java +0 -76
- data/lib/tasks/publish.rake +0 -23
- data/lib/tasks/spec.rake +0 -11
- data/lib/tasks/yard.rake +0 -2
- data/lib/vayacondios/client/config.rb +0 -7
- data/lib/vayacondios/client/configliere.rb +0 -38
- data/lib/vayacondios/client/cube_client.rb +0 -39
- data/lib/vayacondios/client/http_client.rb +0 -49
- data/lib/vayacondios/client/itemset.rb +0 -130
- data/lib/vayacondios/client/legacy_switch.rb +0 -43
- data/lib/vayacondios/client/notifier.rb +0 -123
- data/lib/vayacondios/client/zabbix_client.rb +0 -148
- data/lib/vayacondios/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/errors/bad_request.rb +0 -6
- data/lib/vayacondios/server/errors/not_found.rb +0 -6
- data/lib/vayacondios/server/handlers/config_handler.rb +0 -32
- data/lib/vayacondios/server/handlers/itemset_handler.rb +0 -60
- data/lib/vayacondios/server/legacy_switch.rb +0 -43
- data/lib/vayacondios/server/model/config_document.rb +0 -89
- data/lib/vayacondios/server/model/document.rb +0 -25
- data/lib/vayacondios/server/model/event_document.rb +0 -94
- data/lib/vayacondios/server/model/itemset_document.rb +0 -126
- data/lib/vayacondios/server/rack/extract_methods.rb +0 -35
- data/lib/vayacondios/server/rack/jsonize.rb +0 -43
- data/lib/vayacondios/server/rack/params.rb +0 -50
- data/lib/vayacondios/server/rack/path.rb +0 -23
- data/lib/vayacondios/server/rack/path_validation.rb +0 -22
- data/lib/vayacondios/version.rb +0 -3
- data/lib/vayacondios-client.rb +0 -22
- data/scripts/hadoop_monitor/configurable.rb +0 -66
- data/scripts/hadoop_monitor/hadoop_attempt_scraper.rb +0 -45
- data/scripts/hadoop_monitor/hadoop_client.rb +0 -273
- data/scripts/hadoop_monitor/hadoop_monitor.rb +0 -101
- data/scripts/hadoop_monitor/hadoopable.rb +0 -65
- data/scripts/hadoop_monitor/machine_monitor.rb +0 -115
- data/scripts/s3_cataloger/buckets +0 -33
- data/scripts/s3_cataloger/foreach_bucket +0 -88
- data/scripts/s3_cataloger/parse_ls.py +0 -391
- data/spec/client/itemset_legacy_spec.rb +0 -55
- data/spec/client/itemset_spec.rb +0 -60
- data/spec/client/notifier_spec.rb +0 -120
- data/spec/server/config_spec.rb +0 -113
- data/spec/server/event_spec.rb +0 -103
- data/spec/server/itemset_legacy_spec.rb +0 -320
- data/spec/server/itemset_spec.rb +0 -317
- data/spec/server/rack/extract_methods_spec.rb +0 -60
- data/spec/server/rack/path_spec.rb +0 -36
- data/spec/server/rack/path_validation_spec.rb +0 -22
- data/spec/server/server_spec.rb +0 -20
- data/spec/support/mongo_cleaner.rb +0 -32
- data/src/main/java/ItemSetTest.java +0 -76
- data/src/main/java/com/infochimps/util/CurrentClass.java +0 -26
- data/src/main/java/com/infochimps/util/DebugUtil.java +0 -38
- data/src/main/java/com/infochimps/util/HttpHelper.java +0 -181
- data/src/main/java/com/infochimps/vayacondios/ItemSets.java +0 -373
- data/src/main/java/com/infochimps/vayacondios/LinkToVCD.java +0 -18
- data/src/main/java/com/infochimps/vayacondios/MemoryVCDShim.java +0 -84
- data/src/main/java/com/infochimps/vayacondios/Organization.java +0 -62
- data/src/main/java/com/infochimps/vayacondios/PathBuilder.java +0 -13
- data/src/main/java/com/infochimps/vayacondios/StandardVCDLink.java +0 -218
- data/src/main/java/com/infochimps/vayacondios/VCDIntegrationTest.java +0 -108
- data/src/test/java/com/infochimps/vayacondios/TestVayacondiosInMemory.java +0 -78
- data/vayacondios-client.gemspec +0 -25
data/pom.xml
CHANGED
@@ -4,17 +4,99 @@
|
|
4
4
|
<groupId>com.infochimps</groupId>
|
5
5
|
<artifactId>vayacondios</artifactId>
|
6
6
|
<packaging>jar</packaging>
|
7
|
-
|
8
|
-
<name>
|
7
|
+
<version>2.0.0-LESLIE</version>
|
8
|
+
<name>Vayacondios</name>
|
9
9
|
<url>http://maven.apache.org</url>
|
10
10
|
|
11
11
|
<parent>
|
12
12
|
<groupId>com.infochimps</groupId>
|
13
13
|
<artifactId>parent-pom</artifactId>
|
14
|
-
|
15
|
-
<relativePath></relativePath>
|
14
|
+
<version>1.0.0-SNAPSHOT</version>
|
16
15
|
</parent>
|
17
16
|
|
17
|
+
<reporting>
|
18
|
+
<plugins>
|
19
|
+
<plugin>
|
20
|
+
<groupId>org.apache.maven.plugins</groupId>
|
21
|
+
<artifactId>maven-javadoc-plugin</artifactId>
|
22
|
+
<version>2.9</version>
|
23
|
+
<configuration>
|
24
|
+
<show>public</show>
|
25
|
+
</configuration>
|
26
|
+
</plugin>
|
27
|
+
</plugins>
|
28
|
+
</reporting>
|
29
|
+
|
30
|
+
<build>
|
31
|
+
<plugins>
|
32
|
+
<plugin>
|
33
|
+
<artifactId>maven-failsafe-plugin</artifactId>
|
34
|
+
<version>2.6</version>
|
35
|
+
<executions>
|
36
|
+
<execution>
|
37
|
+
<goals>
|
38
|
+
<goal>integration-test</goal>
|
39
|
+
<goal>verify</goal>
|
40
|
+
</goals>
|
41
|
+
</execution>
|
42
|
+
</executions>
|
43
|
+
</plugin>
|
44
|
+
<plugin>
|
45
|
+
<groupId>org.apache.maven.plugins</groupId>
|
46
|
+
<artifactId>maven-surefire-plugin</artifactId>
|
47
|
+
<version>2.11</version>
|
48
|
+
<dependencies>
|
49
|
+
<dependency>
|
50
|
+
<groupId>org.apache.maven.surefire</groupId>
|
51
|
+
<artifactId>surefire-junit47</artifactId>
|
52
|
+
<version>2.12</version>
|
53
|
+
</dependency>
|
54
|
+
</dependencies>
|
55
|
+
<configuration>
|
56
|
+
<includes>
|
57
|
+
<include>**/*.class</include>
|
58
|
+
</includes>
|
59
|
+
<excludedGroups>com.infochimps.vayacondios.test.IntegrationTest</excludedGroups>
|
60
|
+
</configuration>
|
61
|
+
</plugin>
|
62
|
+
|
63
|
+
<!-- <plugin> -->
|
64
|
+
<!-- <groupId>org.apache.maven.plugins</groupId> -->
|
65
|
+
<!-- <artifactId>maven-shade-plugin</artifactId> -->
|
66
|
+
<!-- <version>2.0</version> -->
|
67
|
+
<!-- <executions> -->
|
68
|
+
<!-- <execution> -->
|
69
|
+
<!-- <phase>package</phase> -->
|
70
|
+
<!-- <goals> -->
|
71
|
+
<!-- <goal>shade</goal> -->
|
72
|
+
<!-- </goals> -->
|
73
|
+
<!-- <configuration> -->
|
74
|
+
<!-- <transformers> -->
|
75
|
+
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> -->
|
76
|
+
<!-- <mainClass>com.infochimps.vayacondios.VCDIntegrationTest</mainClass> -->
|
77
|
+
<!-- </transformer> -->
|
78
|
+
<!-- </transformers> -->
|
79
|
+
<!-- </configuration> -->
|
80
|
+
<!-- </execution> -->
|
81
|
+
<!-- </executions> -->
|
82
|
+
<!-- </plugin> -->
|
83
|
+
<plugin>
|
84
|
+
<groupId>org.codehaus.mojo</groupId>
|
85
|
+
<artifactId>exec-maven-plugin</artifactId>
|
86
|
+
<version>1.2.1</version>
|
87
|
+
<configuration>
|
88
|
+
<executable>java</executable>
|
89
|
+
<arguments>
|
90
|
+
<argument>-cp</argument>
|
91
|
+
<classpath/>
|
92
|
+
<argument>-jar</argument>
|
93
|
+
<argument>target/${project.artifactId}-${project.version}.jar</argument>
|
94
|
+
</arguments>
|
95
|
+
</configuration>
|
96
|
+
</plugin>
|
97
|
+
</plugins>
|
98
|
+
</build>
|
99
|
+
|
18
100
|
<repositories>
|
19
101
|
<!-- Infochimps Repositories -->
|
20
102
|
<repository>
|
@@ -44,5 +126,43 @@
|
|
44
126
|
<artifactId>commons-codec</artifactId>
|
45
127
|
<version>1.2</version>
|
46
128
|
</dependency>
|
129
|
+
<dependency>
|
130
|
+
<groupId>org.slf4j</groupId>
|
131
|
+
<artifactId>slf4j-api</artifactId>
|
132
|
+
<version>1.7.2</version>
|
133
|
+
</dependency>
|
134
|
+
<dependency>
|
135
|
+
<groupId>org.slf4j</groupId>
|
136
|
+
<artifactId>slf4j-simple</artifactId>
|
137
|
+
<version>1.7.2</version>
|
138
|
+
</dependency>
|
139
|
+
<dependency>
|
140
|
+
<groupId>junit</groupId>
|
141
|
+
<artifactId>junit</artifactId>
|
142
|
+
<version>4.8.1</version>
|
143
|
+
<scope>test</scope>
|
144
|
+
</dependency>
|
145
|
+
<dependency>
|
146
|
+
<groupId>com.ning</groupId>
|
147
|
+
<artifactId>async-http-client</artifactId>
|
148
|
+
<version>1.7.16</version>
|
149
|
+
</dependency>
|
150
|
+
<dependency>
|
151
|
+
<groupId>org.apache.commons</groupId>
|
152
|
+
<artifactId>commons-lang3</artifactId>
|
153
|
+
<version>3.1</version>
|
154
|
+
</dependency>
|
155
|
+
<dependency>
|
156
|
+
<groupId>org.apache.httpcomponents</groupId>
|
157
|
+
<artifactId>httpclient</artifactId>
|
158
|
+
<version>4.2.5</version>
|
159
|
+
</dependency>
|
160
|
+
<dependency>
|
161
|
+
<groupId>org.mongodb</groupId>
|
162
|
+
<artifactId>mongo-java-driver</artifactId>
|
163
|
+
<version>2.11.1</version>
|
164
|
+
<scope>verify</scope>
|
165
|
+
</dependency>
|
166
|
+
|
47
167
|
</dependencies>
|
48
168
|
</project>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Configuration do
|
4
|
+
|
5
|
+
def change_defaults new_defaults
|
6
|
+
subject.define_singleton_method(:defaults) do
|
7
|
+
new_defaults
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context '#defaults' do
|
12
|
+
it 'defines defaults' do
|
13
|
+
subject.defaults.should eq(Hash.new)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context '#resolved_settings' do
|
18
|
+
it 'resolves settings automatically when accessed' do
|
19
|
+
subject.should_not be_resolved
|
20
|
+
subject.resolved_settings.should eq(Hash.new)
|
21
|
+
subject.should be_resolved
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context '#overlay' do
|
26
|
+
before{ change_defaults(foo: 'bar', baz: 'qix') }
|
27
|
+
|
28
|
+
it 'allows a top-level override of settings' do
|
29
|
+
subject.overlay(foo: 'override')
|
30
|
+
subject.resolved_settings.should eq(foo: 'override', baz: 'qix')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context '#[]' do
|
35
|
+
before{ change_defaults(foo: 'bar') }
|
36
|
+
|
37
|
+
it 'allows access to the resolved_settings' do
|
38
|
+
subject[:foo].should eq('bar')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Server::ApiOptions do
|
4
|
+
|
5
|
+
let(:api) do
|
6
|
+
api_options = described_class
|
7
|
+
Class.new{ include api_options }.new
|
8
|
+
end
|
9
|
+
let(:settings){ Hash.new }
|
10
|
+
let(:parser) { OptionParser.new }
|
11
|
+
|
12
|
+
it 'sets the default config file location' do
|
13
|
+
api.options_parser(parser, settings)
|
14
|
+
settings[:config].should eq(File.join(Vayacondios.library_dir, 'config/vcd-server.rb'))
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'sets the default server port' do
|
18
|
+
api.options_parser(parser, settings)
|
19
|
+
settings[:port].should eq(3467)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'allows commandline overrides for database options' do
|
23
|
+
ARGV.replace %w[-d foo -h foo.com -D bar -o 1234 -n 10]
|
24
|
+
api.options_parser(parser, settings)
|
25
|
+
parser.parse!
|
26
|
+
settings[:database].should eq(driver: 'foo',
|
27
|
+
connections: 10,
|
28
|
+
host: 'foo.com',
|
29
|
+
name: 'bar',
|
30
|
+
port: 1234)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Server::Api do
|
4
|
+
include Goliath::TestHelper
|
5
|
+
|
6
|
+
TestResponse = Struct.new(:status, :body, :headers) do
|
7
|
+
def parsed_body
|
8
|
+
MultiJson.load body
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_request(verb, path, options = {})
|
13
|
+
options[:path] = path
|
14
|
+
proc{ |&callback| send("#{verb}_request", options, &callback) }
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:captured_assertions){ Array.new }
|
18
|
+
|
19
|
+
def perform(request, &blk)
|
20
|
+
response = nil
|
21
|
+
with_api(described_class) do |server|
|
22
|
+
yield server.api if block_given?
|
23
|
+
request.call do |client|
|
24
|
+
response = TestResponse.new(client.response_header.status.to_i, client.response, client.response_header)
|
25
|
+
end
|
26
|
+
captured_assertions.each{ |a| raise a if a.is_a?(Exception) }
|
27
|
+
end
|
28
|
+
response
|
29
|
+
end
|
30
|
+
|
31
|
+
def capture_assertions(&code)
|
32
|
+
code.call
|
33
|
+
rescue RSpec::Expectations::ExpectationNotMetError => e
|
34
|
+
captured_assertions << e
|
35
|
+
end
|
36
|
+
|
37
|
+
def stub_response(api, result = nil, &blk)
|
38
|
+
api.stub(:response) do |env|
|
39
|
+
capture_assertions do
|
40
|
+
blk.call(api, env)
|
41
|
+
end
|
42
|
+
result || success_response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def success_response
|
47
|
+
[200, {}, {}]
|
48
|
+
end
|
49
|
+
|
50
|
+
def stub_handler(api, result = {}, &blk)
|
51
|
+
handler = double(:handle, call: result)
|
52
|
+
handler_class = double(:handler_class, new: handler)
|
53
|
+
api.stub(:handler).and_return handler_class
|
54
|
+
if block_given?
|
55
|
+
handler.should_receive(:call) do |action, routes, document|
|
56
|
+
capture_assertions{ blk.call(action, routes, document) }
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'Rack', 'Heartbeat' do
|
63
|
+
subject(:response){ perform build_request(:get, '/status') }
|
64
|
+
|
65
|
+
it 'returns a heartbeat message' do
|
66
|
+
response.body.should eq('OK')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'Rack', 'ApiVersion' do
|
71
|
+
subject(:response){ perform build_request(:get, '/version') }
|
72
|
+
|
73
|
+
it 'returns the server api version' do
|
74
|
+
response.parsed_body.should eq(Vayacondios::GEM_VERSION)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'attaches a version header to every response' do
|
78
|
+
response = perform build_request(:get, '/v3/org/event/topic')
|
79
|
+
response.headers['X_VAYACONDIOS_VERSION'].should eq(Vayacondios::GEM_VERSION)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'Rack', 'ForceContentType' do
|
84
|
+
let(:request) { build_request(:post, '/v3/org/event/topic', body: '{"foo":"bar"}') }
|
85
|
+
let(:response){ perform request }
|
86
|
+
|
87
|
+
it 'accepts a JSON body with no header' do
|
88
|
+
perform(request) do |server|
|
89
|
+
stub_handler(server, {}) do |action, routes, document|
|
90
|
+
document.should eq('foo' => 'bar')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'attaches a JSON content header to every response' do
|
96
|
+
response.headers['CONTENT_TYPE'].should match('application/json')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'Rack', 'Formatters::JSON' do
|
101
|
+
subject(:response) do
|
102
|
+
perform build_request(:get, '/v3/org/event/topic') do |server|
|
103
|
+
stub_handler(server, { foo: 'bar' })
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'serializes all response bodies as JSON' do
|
108
|
+
response.parsed_body.should eq('foo' => 'bar')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'Rack', 'Params' do
|
113
|
+
it 'provides parsed params to the response method' do
|
114
|
+
request = build_request(:post, '/v3/org/event/topic', body: '{"foo":"bar"}')
|
115
|
+
perform(request) do |server|
|
116
|
+
stub_response(server, success_response) do |api|
|
117
|
+
api.should respond_to(:document)
|
118
|
+
api.document.should eq('foo' => 'bar')
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'handles non-Hash JSON values' do
|
124
|
+
request = build_request(:post, '/v3/org/event/topic', body: '["foo","bar"]')
|
125
|
+
perform(request) do |server|
|
126
|
+
stub_response(server, success_response) do |api|
|
127
|
+
api.document.should eq(%w[ foo bar ])
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'Rack', 'Validation::RequestMethod' do
|
134
|
+
%w[ HEAD OPTIONS ].each do |method|
|
135
|
+
it "returns a validation error on #{method} requests" do
|
136
|
+
response = perform build_request(method.downcase.to_sym, '/v3/org/event/topic')
|
137
|
+
response.status.should eq(405)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'Rack', 'ControlMethods' do
|
143
|
+
{
|
144
|
+
post: :create,
|
145
|
+
get: :retrieve,
|
146
|
+
patch: :update,
|
147
|
+
patch: :update,
|
148
|
+
delete: :delete,
|
149
|
+
}.each_pair do |http_verb, handler_action|
|
150
|
+
it "maps #{http_verb.to_s.upcase} verbs to handler method #{handler_action}" do
|
151
|
+
perform build_request(http_verb, '/v3/org/event/topic') do |server|
|
152
|
+
stub_handler(server) do |action, routes, document|
|
153
|
+
action.should eq(handler_action)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'Rack', 'Validation::Routes' do
|
161
|
+
it 'returns a validation error when the route is not valid' do
|
162
|
+
response = perform build_request(:get, '/invalid/route/fool')
|
163
|
+
response.status.should eq(400)
|
164
|
+
response.parsed_body['error'].should match('/v3/<organization>/<type>/<topic>/<id>')
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'parses the route pieces' do
|
168
|
+
perform build_request(:get, '/v3/twitter/event/hashtag/emoji') do |server|
|
169
|
+
stub_response(server) do |api|
|
170
|
+
api.should respond_to(:routes)
|
171
|
+
api.routes.should eq(organization: 'twitter',
|
172
|
+
type: 'event',
|
173
|
+
topic: 'hashtag',
|
174
|
+
id: 'emoji')
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'Rack', 'Validation::RouteHandler' do
|
181
|
+
{
|
182
|
+
event: Vayacondios::Server::EventHandler,
|
183
|
+
events: Vayacondios::Server::EventsHandler,
|
184
|
+
stash: Vayacondios::Server::StashHandler,
|
185
|
+
stashes: Vayacondios::Server::StashesHandler,
|
186
|
+
stream: Vayacondios::Server::StreamHandler,
|
187
|
+
}.each_pair do |type, handler|
|
188
|
+
it "maps type #{type} to handler #{handler}" do
|
189
|
+
request = build_request(:get, "/v3/infochimps/#{type}/topic")
|
190
|
+
perform(request) do |server|
|
191
|
+
stub_response(server, success_response) do |api|
|
192
|
+
api.handler.should be(handler)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'returns a validation error when a handler cannot be found' do
|
199
|
+
response = perform build_request(:get, '/v3/infochimps/invalid/topic')
|
200
|
+
response.status.should eq(400)
|
201
|
+
response.parsed_body['error'].should match('No handler found')
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'Rack', 'Validation::RequiredRoutes' do
|
206
|
+
it 'returns a validation error when a stash does not have a topic' do
|
207
|
+
response = perform build_request(:get, '/v3/infochimps/stash')
|
208
|
+
response.status.should eq(400)
|
209
|
+
response.parsed_body['error'].should match('A topic route is required')
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'returns a validation error when an event does not have a topic' do
|
213
|
+
response = perform build_request(:get, '/v3/infochimps/event')
|
214
|
+
response.status.should eq(400)
|
215
|
+
response.parsed_body['error'].should match('A topic route is required')
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'returns a validation error when events do not have a topic' do
|
219
|
+
response = perform build_request(:get, '/v3/infochimps/events')
|
220
|
+
response.status.should eq(400)
|
221
|
+
response.parsed_body['error'].should match('A topic route is required')
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'returns a validation error when stream do not have a topic' do
|
225
|
+
response = perform build_request(:get, '/v3/infochimps/stream')
|
226
|
+
response.status.should eq(400)
|
227
|
+
response.parsed_body['error'].should match('A topic route is required')
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'Rack', '#response' do
|
232
|
+
let(:request){ build_request(:get, '/v3/infochimps/event/topic') }
|
233
|
+
|
234
|
+
it 'returns a validation error when a handler raises one' do
|
235
|
+
response = perform(request) do |server|
|
236
|
+
stub_handler(server) do |action, routes, document|
|
237
|
+
raise Goliath::Validation::NotFoundError.new("Dude, where's my car?")
|
238
|
+
end
|
239
|
+
end
|
240
|
+
response.status.should eq(404)
|
241
|
+
response.parsed_body['error'].should eq("Dude, where's my car?")
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'returns a document error when a handler raises one' do
|
245
|
+
response = perform(request) do |server|
|
246
|
+
stub_handler(server) do |action, routes, document|
|
247
|
+
raise Vayacondios::Server::Document::Error.new('Invalid')
|
248
|
+
end
|
249
|
+
end
|
250
|
+
response.status.should eq(400)
|
251
|
+
response.parsed_body['error'].should eq('Invalid')
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'returns a server error when a handler raises one' do
|
255
|
+
response = perform(request) do |server|
|
256
|
+
stub_handler(server) do |action, routes, document|
|
257
|
+
raise ZeroDivisionError.new('infinity')
|
258
|
+
end
|
259
|
+
end
|
260
|
+
response.status.should eq(500)
|
261
|
+
response.parsed_body['error'].should match('ZeroDivisionError')
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'returns a successful response on success' do
|
265
|
+
response = perform(request) do |server|
|
266
|
+
stub_handler(server, { foo: 'bar' })
|
267
|
+
end
|
268
|
+
response.status.should eq(200)
|
269
|
+
response.parsed_body.should eq('foo' => 'bar')
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'returns a streaming response when requested', focus: true do
|
273
|
+
request = build_request(:get, '/v3/infochimps/stream/topic', connection_options: { inactivity_timeout: 0.5 })
|
274
|
+
response = perform(request)
|
275
|
+
response.status.should eq(200)
|
276
|
+
response.body.should eq('')
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Server::Configuration do
|
4
|
+
its(:defaults) do
|
5
|
+
should eq(development: {
|
6
|
+
driver: 'mongo',
|
7
|
+
host: 'localhost',
|
8
|
+
port: 27017,
|
9
|
+
name: 'vayacondios_development',
|
10
|
+
connections: 20,
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'defines a db config constant' do
|
15
|
+
Vayacondios::Server::DbConfig.should be_a(described_class)
|
16
|
+
end
|
17
|
+
|
18
|
+
context '#env' do
|
19
|
+
it 'allows hash access scoped by environment' do
|
20
|
+
subject.env(:development).should eq(driver: 'mongo',
|
21
|
+
host: 'localhost',
|
22
|
+
port: 27017,
|
23
|
+
name: 'vayacondios_development',
|
24
|
+
connections: 20)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Server::MongoDriver, if: WITH_MONGO do
|
4
|
+
include LogHelper
|
5
|
+
|
6
|
+
let!(:settings){ Vayacondios::Server::DbConfig.env :test }
|
7
|
+
|
8
|
+
subject{ described_class.connect settings.merge(log: log) }
|
9
|
+
|
10
|
+
def mongo
|
11
|
+
Mongo::MongoClient.new(settings[:host], settings[:port])
|
12
|
+
end
|
13
|
+
|
14
|
+
def db
|
15
|
+
mongo.db settings[:name]
|
16
|
+
end
|
17
|
+
|
18
|
+
def collection name
|
19
|
+
db.collection name
|
20
|
+
end
|
21
|
+
|
22
|
+
def using(location, &blk)
|
23
|
+
EM.synchrony do
|
24
|
+
subject.set_location location
|
25
|
+
blk.call(subject)
|
26
|
+
EM::Synchrony.sleep(0.1) # ensure the operation completes
|
27
|
+
EM.stop
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def clean name
|
32
|
+
collection(name).drop
|
33
|
+
end
|
34
|
+
|
35
|
+
context '#to_dotted_hash' do
|
36
|
+
let(:nested){ { foo: { bar: { baz: 'qix' } }, hey: { you: 'there' } } }
|
37
|
+
it 'flattens a nested hash into dotted keys' do
|
38
|
+
EM.synchrony do
|
39
|
+
subject.to_dotted_hash(nested).should eq('foo.bar.baz' => 'qix', 'hey.you' => 'there')
|
40
|
+
EM.stop
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context '#insert' do
|
46
|
+
after do
|
47
|
+
clean 'organization.foo.events'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns the id' do
|
51
|
+
result = nil
|
52
|
+
using('organization.foo.events') do |driver|
|
53
|
+
result = driver.insert(foo: 'bar')
|
54
|
+
end
|
55
|
+
collection('organization.foo.events').find(_id: BSON::ObjectId(result[:_id])).to_a.size.should eq(1)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context '#search' do
|
60
|
+
after{ clean 'organization.stash' }
|
61
|
+
|
62
|
+
it 'returns an array of results' do
|
63
|
+
collection('organization.stash').insert(_id: 'topic', foo: 'bar')
|
64
|
+
result = nil
|
65
|
+
using('organization.stash') do |driver|
|
66
|
+
result = driver.search({}, { foo: 'bar' }, {})
|
67
|
+
end
|
68
|
+
result.should eq([{ _id: 'topic', foo: 'bar' }])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context '#retrieve' do
|
73
|
+
after{ clean 'organization.stash' }
|
74
|
+
|
75
|
+
it 'returns the record if found' do
|
76
|
+
collection('organization.stash').insert(_id: 'topic', foo: 'bar')
|
77
|
+
result = nil
|
78
|
+
using('organization.stash') do |driver|
|
79
|
+
result = driver.retrieve(_id: 'topic')
|
80
|
+
end
|
81
|
+
result.should eq(_id: 'topic', foo: 'bar')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns nil if the record is not found' do
|
85
|
+
collection('organization.stash').insert(_id: 'topic', foo: 'bar')
|
86
|
+
result = nil
|
87
|
+
using('organization.stash') do |driver|
|
88
|
+
result = driver.retrieve(_id: 'invalid')
|
89
|
+
end
|
90
|
+
result.should be_nil
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context '#remove' do
|
95
|
+
after{ clean 'organization.stash' }
|
96
|
+
|
97
|
+
it 'returns nil after completion' do
|
98
|
+
collection('organization.stash').insert(_id: 'topic', foo: 'bar')
|
99
|
+
result = nil
|
100
|
+
using('organization.stash') do |driver|
|
101
|
+
result = driver.remove({}, foo: 'bar')
|
102
|
+
end
|
103
|
+
result.should be_nil
|
104
|
+
collection('organization.stash').find(_id: 'topic').to_a.should be_empty
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vayacondios::Server::EventHandler, behaves_like: 'handler' do
|
4
|
+
|
5
|
+
let(:params) { { organization: 'organization', topic: 'topic' } }
|
6
|
+
let(:document) { { foo: 'bar', time: '2013-01-01T10:23:10.432Z' } }
|
7
|
+
let(:model_class){ Vayacondios::Server::Event }
|
8
|
+
|
9
|
+
context '#create' do
|
10
|
+
it 'returns the created event' do
|
11
|
+
model_class.should_receive(:create).with(params, document).and_call_original
|
12
|
+
driver.should_receive(:insert).and_return(_id: 'abc123')
|
13
|
+
handler.create(params, document).should eq(id: 'abc123',
|
14
|
+
foo: 'bar',
|
15
|
+
time: '2013-01-01T10:23:10.432Z')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context '#retrieve', 'when an event is found' do
|
20
|
+
let(:params){ { organization: 'organization', topic: 'topic', id: 'abc123' } }
|
21
|
+
|
22
|
+
it 'returns the selected event' do
|
23
|
+
model_class.should_receive(:find).with(params).and_call_original
|
24
|
+
driver.should_receive(:retrieve).and_return(_id: 'abc123', _t: '2013-01-01T10:23:10.432Z', _d: { foo: 'bar' })
|
25
|
+
handler.retrieve(params, {}).should eq(id: 'abc123',
|
26
|
+
foo: 'bar',
|
27
|
+
time: '2013-01-01T10:23:10.432Z')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context '#retrieve', 'when an event is not found', focus: true do
|
32
|
+
let(:params){ { organization: 'organization', topic: 'topic', id: 'abc123' } }
|
33
|
+
|
34
|
+
it 'raises a validation error' do
|
35
|
+
model_class.should_receive(:find).with(params).and_call_original
|
36
|
+
driver.should_receive(:retrieve).and_return(nil)
|
37
|
+
expect{ handler.retrieve(params, {}) }.to raise_error(validation_error, /not found/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context '#update' do
|
42
|
+
it 'raises a validation error' do
|
43
|
+
expect{ handler.update(params, document) }.to raise_error(validation_error, /update/)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context '#delete', 'when params have no id' do
|
48
|
+
it 'raises a validation error' do
|
49
|
+
expect{ handler.delete(params, {}) }.to raise_error(validation_error, /id/i)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context '#delete', 'when successful' do
|
54
|
+
let(:params){ { organization: 'organization', topic: 'topic', id: 'abc123' } }
|
55
|
+
|
56
|
+
it 'returns success response' do
|
57
|
+
model_class.should_receive(:destroy).with(params, {}).and_call_original
|
58
|
+
driver.should_receive(:remove).and_return(true)
|
59
|
+
handler.delete(params, {}).should eq(success_response)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|