evt-event_source-event_store-http 0.1.0.2

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.
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: []