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.
- 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
|