evt-event_source-event_store-http 0.1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a2a518ad3af6f46d6d9aa1c41991aaa6e39204ac
4
+ data.tar.gz: 48eb60be586e4ef09aedcb9184b6ced52009d957
5
+ SHA512:
6
+ metadata.gz: e8f6b2a4685cb92c3538b85858e9b013bd1309b7ad92fa7d4148ad79451991855a10447786dffc4c5e2cbb7d27b415263dc387df4ed7154979b4a36e7cadc47c
7
+ data.tar.gz: d248ef7f2101c549ffc6020c7f2457ab6939062508cdb9a4858a2402f4d38c009e51d48143b4261299ea3c163314cc5db4fbcf2b2440424f055e156e9f1c1c1f
@@ -0,0 +1,17 @@
1
+ require 'net/http'
2
+
3
+ require 'configure'; Configure.activate
4
+ require 'event_source'
5
+ require 'log'
6
+ require 'settings'; Settings.activate
7
+
8
+ require 'event_source/event_store/http/log'
9
+
10
+ require 'event_source/event_store/http/media_types'
11
+
12
+ require 'event_source/event_store/http/session/net_http'
13
+ require 'event_source/event_store/http/session/telemetry'
14
+ require 'event_source/event_store/http/session/substitute'
15
+ require 'event_source/event_store/http/session'
16
+
17
+ require 'event_source/event_store/http/settings'
@@ -0,0 +1,13 @@
1
+ require 'identifier/uuid/controls'
2
+ require 'event_source/controls'
3
+
4
+ require 'event_source/event_store/http/controls/category'
5
+ require 'event_source/event_store/http/controls/event_data'
6
+ require 'event_source/event_store/http/controls/event_data/event_id'
7
+ require 'event_source/event_store/http/controls/event_data/write'
8
+ require 'event_source/event_store/http/controls/media_type'
9
+ require 'event_source/event_store/http/controls/stream'
10
+ require 'event_source/event_store/http/controls/stream_name'
11
+ require 'event_source/event_store/http/controls/uri/path'
12
+ require 'event_source/event_store/http/controls/uuid'
13
+ require 'event_source/event_store/http/controls/write'
@@ -0,0 +1,9 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ Category = EventSource::Controls::Category
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ EventData = EventSource::Controls::EventData
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ module EventData
6
+ module EventID
7
+ def self.example
8
+ UUID.example
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ module EventData
6
+ module Write
7
+ module Text
8
+ def self.example(event_id=nil, type: nil, data: nil, metadata: nil)
9
+ event_id ||= EventID.example
10
+
11
+ event_data = Write.example type: type, data: data, metadata: metadata
12
+
13
+ event_type = event_data.type
14
+ data = event_data.data
15
+ metadata = event_data.metadata
16
+
17
+ raw_data = {
18
+ 'eventId' => event_id,
19
+ 'eventType' => event_type,
20
+ 'data' => data
21
+ }
22
+
23
+ raw_data['metadata'] = metadata if metadata
24
+
25
+ JSON.pretty_generate [raw_data]
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ module MediaType
6
+ def self.example
7
+ unknown
8
+ end
9
+
10
+ def self.events
11
+ EventStore::MediaTypes.vnd_event_store_events_json
12
+ end
13
+
14
+ def self.stream
15
+ EventStore::MediaTypes.vnd_event_store_atom_json
16
+ end
17
+
18
+ def self.unknown
19
+ 'application/octet-stream'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ Stream = EventSource::Controls::Stream
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ StreamName = EventSource::Controls::StreamName
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ module URI
6
+ module Path
7
+ module Stream
8
+ def self.example(**stream_arguments)
9
+ stream = Controls::Stream.example **stream_arguments
10
+
11
+ stream_id = EventSource::StreamName.get_id stream.name
12
+
13
+ "/streams/#{stream.category}-#{stream_id}"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ UUID = Identifier::UUID::Controls::Incrementing
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,50 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ module Controls
5
+ module Write
6
+ def self.call(event_count=nil, data: nil, metadata: nil, stream_name: nil, type: nil)
7
+ event_count ||= 1
8
+ stream_name ||= StreamName.example
9
+
10
+ host = Settings.get :host
11
+ port = Settings.get :port
12
+
13
+ event_data = EventData::Write.example(
14
+ type: type,
15
+ data: data,
16
+ metadata: metadata
17
+ )
18
+
19
+ Net::HTTP.start host, port do |http|
20
+ event_datum = (0...event_count).map do
21
+ event_id = Identifier::UUID::Random.get
22
+
23
+ {
24
+ 'eventId' => event_id,
25
+ 'eventType' => event_data.type,
26
+ 'data' => event_data.data,
27
+ 'metadata' => event_data.metadata
28
+ }
29
+ end
30
+
31
+ headers = { 'Content-Type' => MediaTypes.vnd_event_store_events_json }
32
+
33
+ path = "/streams/#{stream_name}"
34
+
35
+ request_body = JSON.pretty_generate event_datum
36
+
37
+ response = http.request_post path, request_body, headers
38
+
39
+ unless response.code.to_i == 201
40
+ fail "Write failed (StatusCode: #{response.code}, ReasonPhrase: #{response.message})"
41
+ end
42
+ end
43
+
44
+ stream_name
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,13 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Log < ::Log
5
+ def tag!(tags)
6
+ tags << :event_source_event_store_http
7
+ tags << :library
8
+ tags << :verbose
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module EventSource
2
+ module EventStore
3
+ module MediaTypes
4
+ def self.vnd_event_store_atom_json
5
+ 'application/vnd.eventstore.atom+json'
6
+ end
7
+
8
+ def self.vnd_event_store_events_json
9
+ 'application/vnd.eventstore.events+json'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,162 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Session
5
+ include Log::Dependency
6
+
7
+ dependency :net_http, NetHTTP
8
+ dependency :telemetry, ::Telemetry
9
+
10
+ def self.build(settings=nil, namespace: nil)
11
+ instance = new
12
+
13
+ ::Telemetry.configure instance
14
+ NetHTTP.configure instance, settings: settings, namespace: namespace
15
+
16
+ instance.connect
17
+
18
+ instance
19
+ end
20
+
21
+ def self.configure(receiver, settings=nil, namespace: nil, session: nil, attr_name: nil)
22
+ attr_name ||= :session
23
+
24
+ if session.nil?
25
+ instance = build settings, namespace: namespace
26
+ else
27
+ instance = session
28
+ end
29
+
30
+ receiver.public_send "#{attr_name}=", instance
31
+
32
+ instance
33
+ end
34
+
35
+ def self.register_telemetry_sink(instance)
36
+ sink = Telemetry::Sink.new
37
+
38
+ instance.telemetry.register sink
39
+
40
+ sink
41
+ end
42
+
43
+ def connect
44
+ logger.trace(tag: [:http, :db_connection]) {
45
+ "Connecting to EventStore (Host: #{host.inspect}, Port: #{port.inspect})"
46
+ }
47
+
48
+ net_http.start
49
+
50
+ data = Telemetry::Connected.new host, port
51
+
52
+ telemetry.record :connected, data
53
+
54
+ logger.debug(tag: [:http, :db_connection]) {
55
+ "Connected to EventStore (Host: #{host.inspect}, Port: #{port.inspect})"
56
+ }
57
+
58
+ net_http
59
+ end
60
+
61
+ def connected?
62
+ net_http.started?
63
+ end
64
+
65
+ def close
66
+ logger.trace(tag: [:http, :db_connection]) { "Closing connection to EventStore" }
67
+
68
+ net_http.finish
69
+
70
+ logger.debug(tag: [:http, :db_connection]) { "Connection to EventStore closed" }
71
+
72
+ net_http
73
+ end
74
+
75
+ def get(path, media_type, headers=nil, &probe)
76
+ headers ||= {}
77
+
78
+ logger.trace(tag: :http) {
79
+ "Issuing GET request (Path: #{path}, MediaType: #{media_type})"
80
+ }
81
+
82
+ headers['Accept'] = media_type
83
+
84
+ response = net_http.request_get path, headers
85
+
86
+ status_code = response.code.to_i
87
+ response_body = response.body if (200..399).include? status_code
88
+
89
+ logger.debug(tag: :http) {
90
+ "GET request issued (Path: #{path}, MediaType: #{media_type}, StatusCode: #{status_code}, ReasonPhrase: #{response.message}, ContentLength: #{response_body&.bytesize.inspect})"
91
+ }
92
+
93
+ if response.body.empty?
94
+ logger.debug(tags: [:data]) { "Response: (none)" }
95
+ else
96
+ logger.debug(tags: [:data]) { "Response:\n\n#{response.body}" }
97
+ end
98
+
99
+ probe.(response) if probe
100
+
101
+ data = Telemetry::Get.new(
102
+ path,
103
+ status_code,
104
+ response.message,
105
+ response.body,
106
+ media_type
107
+ )
108
+
109
+ telemetry.record :get, data
110
+
111
+ return status_code, response_body
112
+ end
113
+
114
+ def post(path, request_body, media_type, headers=nil, &probe)
115
+ headers ||= {}
116
+ headers['Content-Type'] = media_type
117
+
118
+ logger.trace(tag: :http) {
119
+ "Issuing POST request (Path: #{path}, MediaType: #{media_type}, ContentLength: #{request_body.bytesize})"
120
+ }
121
+ logger.trace(tags: [:data]) { "Request:\n\n#{request_body}" }
122
+
123
+ response = net_http.request_post path, request_body, headers
124
+
125
+ status_code = response.code.to_i
126
+
127
+ logger.debug(tag: :http) {
128
+ "POST request issued (Path: #{path}, MediaType: #{media_type}, ContentLength: #{request_body.bytesize}, StatusCode: #{status_code}, ReasonPhrase: #{response.message})"
129
+ }
130
+
131
+ if response.body.empty?
132
+ logger.debug(tags: [:data]) { "Response: (none)" }
133
+ else
134
+ logger.debug(tags: [:data]) { "Response:\n\n#{response.body}" }
135
+ end
136
+
137
+ probe.(response) if probe
138
+
139
+ data = Telemetry::Post.new(
140
+ path,
141
+ status_code,
142
+ response.message,
143
+ request_body,
144
+ media_type
145
+ )
146
+
147
+ telemetry.record :post, data
148
+
149
+ status_code
150
+ end
151
+
152
+ def host
153
+ net_http.address
154
+ end
155
+
156
+ def port
157
+ net_http.port
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,96 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Session
5
+ module NetHTTP
6
+ def self.configure(receiver, settings: nil, namespace: nil, attr_name: nil)
7
+ attr_name ||= :net_http
8
+ settings ||= Settings.instance
9
+ namespace = Array(namespace)
10
+
11
+ host = settings.get *namespace, :host
12
+ port = settings.get *namespace, :port
13
+ read_timeout = settings.get *namespace, :read_timeout
14
+
15
+ net_http = Net::HTTP.new host, port
16
+
17
+ net_http.read_timeout = read_timeout if read_timeout
18
+
19
+ receiver.public_send "#{attr_name}=", net_http
20
+
21
+ net_http
22
+ end
23
+
24
+ class Substitute
25
+ attr_accessor :address
26
+ attr_writer :response_body
27
+ attr_accessor :port
28
+ attr_accessor :status_code
29
+ attr_accessor :started
30
+
31
+ def self.build
32
+ new
33
+ end
34
+
35
+ def request_get(path, initheader=nil)
36
+ status_code = get_request_status_code
37
+
38
+ OpenStruct.new(
39
+ :code => status_code,
40
+ :body => response_body
41
+ )
42
+ end
43
+
44
+ def request_post(path, request_body, initheader=nil)
45
+ status_code = post_request_status_code
46
+
47
+ OpenStruct.new(
48
+ :code => status_code,
49
+ :body => response_body
50
+ )
51
+ end
52
+
53
+ def start
54
+ self.started = true
55
+ end
56
+
57
+ def started?
58
+ started ? true : false
59
+ end
60
+
61
+ def response_body
62
+ @response_body ||= Defaults.response_body
63
+ end
64
+
65
+ def get_request_status_code
66
+ status_code || Defaults.get_request_status_code
67
+ end
68
+
69
+ def post_request_status_code
70
+ status_code || Defaults.post_request_status_code
71
+ end
72
+
73
+ def set_response(status_code, response_body=nil)
74
+ self.status_code = status_code
75
+ self.response_body = response_body if response_body
76
+ end
77
+
78
+ module Defaults
79
+ def self.get_request_status_code
80
+ 404
81
+ end
82
+
83
+ def self.post_request_status_code
84
+ 201
85
+ end
86
+
87
+ def self.response_body
88
+ ''
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,49 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Session
5
+ module Substitute
6
+ def self.build
7
+ Session.build
8
+ end
9
+
10
+ class Session < Session
11
+ attr_accessor :telemetry_sink
12
+
13
+ def self.build
14
+ instance = new
15
+
16
+ ::Telemetry.configure instance
17
+
18
+ instance.telemetry_sink = register_telemetry_sink instance
19
+
20
+ instance
21
+ end
22
+
23
+ def set_response(status_code, response_body=nil)
24
+ net_http.set_response status_code, response_body
25
+ end
26
+
27
+ module Assertions
28
+ def get_request?(&block)
29
+ block ||= proc { true }
30
+
31
+ telemetry_sink.recorded_get? do |record|
32
+ block.(record.data)
33
+ end
34
+ end
35
+
36
+ def post_request?(&block)
37
+ block ||= proc { true }
38
+
39
+ telemetry_sink.recorded_post? do |record|
40
+ block.(record.data)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Session
5
+ module Telemetry
6
+ class Sink
7
+ include ::Telemetry::Sink
8
+
9
+ record :connected
10
+ record :get
11
+ record :post
12
+ end
13
+
14
+ Connected = Struct.new :host, :port
15
+
16
+ Get = Struct.new(
17
+ :path,
18
+ :status_code,
19
+ :reason_phrase,
20
+ :response_body,
21
+ :acceptable_media_type
22
+ )
23
+
24
+ Post = Struct.new(
25
+ :path,
26
+ :status_code,
27
+ :reason_phrase,
28
+ :request_body,
29
+ :content_type
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ module EventSource
2
+ module EventStore
3
+ module HTTP
4
+ class Settings < ::Settings
5
+ def self.data_source
6
+ 'settings/event_source_event_store_http.json'
7
+ end
8
+
9
+ def self.instance
10
+ @instance ||= build
11
+ end
12
+
13
+ def self.names
14
+ %i(host port read_timeout)
15
+ end
16
+
17
+ def self.set(receiver)
18
+ instance.set receiver
19
+ end
20
+
21
+ def self.get(name)
22
+ instance.get name
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evt-event_source-event_store-http
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.2
5
+ platform: ruby
6
+ authors:
7
+ - The Eventide Project
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: evt-configure
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: evt-event_source
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: evt-settings
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test_bench
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: " "
70
+ email: opensource@eventide-project.org
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/event_source/event_store/http.rb
76
+ - lib/event_source/event_store/http/controls.rb
77
+ - lib/event_source/event_store/http/controls/category.rb
78
+ - lib/event_source/event_store/http/controls/event_data.rb
79
+ - lib/event_source/event_store/http/controls/event_data/event_id.rb
80
+ - lib/event_source/event_store/http/controls/event_data/write.rb
81
+ - lib/event_source/event_store/http/controls/media_type.rb
82
+ - lib/event_source/event_store/http/controls/stream.rb
83
+ - lib/event_source/event_store/http/controls/stream_name.rb
84
+ - lib/event_source/event_store/http/controls/uri/path.rb
85
+ - lib/event_source/event_store/http/controls/uuid.rb
86
+ - lib/event_source/event_store/http/controls/write.rb
87
+ - lib/event_source/event_store/http/log.rb
88
+ - lib/event_source/event_store/http/media_types.rb
89
+ - lib/event_source/event_store/http/session.rb
90
+ - lib/event_source/event_store/http/session/net_http.rb
91
+ - lib/event_source/event_store/http/session/substitute.rb
92
+ - lib/event_source/event_store/http/session/telemetry.rb
93
+ - lib/event_source/event_store/http/settings.rb
94
+ homepage: https://github.com/eventide-project/event-source-event-store-http
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 2.3.3
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.5.2
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Event source client for EventStore's HTTP interface
118
+ test_files: []