http_event_store 0.2.1

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: 8092ccdf90fa8150f7f8243e5229a6bada5bf74b
4
+ data.tar.gz: 3a441eab628a4597c037c72ec2790a479bb5700c
5
+ SHA512:
6
+ metadata.gz: 58d3133164929972ab97f4332de1fad981cff2fa43bd452620138f6881a3aa855a0d90fa9402d4738e7ac879b0fc562ddaa7b7bd0d06ca5282fd4925d63953d9
7
+ data.tar.gz: fa7782fc7348caf60ae321e8818c79d50c456df54cfd28042bbe37d3ec993669492fc2c1cca166468b879cad272c5ff3230e1a642a7f0ab47e25b4fa79db33f7
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .ruby-gemset
11
+ .ruby-version
12
+ .idea/*
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.2
4
+ before_install: gem install bundler
5
+ gemfile: Gemfile
6
+ notifications:
7
+ slack:
8
+ secure: DhTubz8XU/uzGEV3g4FhWfedYcQRqzB6jEZ6/iSjIhk8D77b/GO/RVXezYG5dNTmmlunOYTm1kGIlxu33yFH+8r33Q4tj7TDtt/yrGO3UvwiEP7UJcvThpMUs3BusGVz4INCnpoinh3Hz56d1tELLlmcnPkjg/mlReje6MIHg+Y=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in http_event_store.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Arkency
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ [![Build Status](https://travis-ci.org/arkency/http_event_store.svg?branch=master)](https://travis-ci.org/arkency/http_event_store)
2
+ [![Gem Version](https://badge.fury.io/rb/http_event_store.svg)](http://badge.fury.io/rb/http_event_store)
3
+ [![Join the chat at https://gitter.im/arkency/http_event_store](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/arkency/http_event_store?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+
5
+ # HttpEventStore
6
+
7
+ HttpEventStore is a HTTP connector to the Greg's [Event Store](https://geteventstore.com/).
8
+ The `master` branch is curently targeting EventStore 3.x, for EventStore 2.x version check `EventStore2.x` branch.
9
+
10
+ ## Attention: gem has been renamed!
11
+ #### The name has changed from http_eventstore to http_event_store.
12
+
13
+ # Documentation
14
+
15
+ All documentation and sample codes are available at [http://httpeventstore.arkency.com](http://httpeventstore.arkency.com)
16
+
17
+ ## Supported version's of Event Store
18
+
19
+ To take advantage of all the functionality offered by our gem the minimum recommended version of Event Store is **3.0**
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it ( https://github.com/[my-github-username]/http_event_store/fork )
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
26
+ 4. Push to the branch (`git push origin my-new-feature`)
27
+ 5. Create a new Pull Request
28
+
29
+ ## About
30
+
31
+ <img src="http://arkency.com/images/arkency.png" alt="Arkency" width="20%" align="left" />
32
+
33
+ This repository is funded and maintained by Arkency. Check out our other [open-source projects](https://github.com/arkency).
34
+
35
+ You can also [hire us](http://arkency.com) or [read our blog](http://blog.arkency.com).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'http_event_store/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'http_event_store'
8
+ spec.version = HttpEventStore::VERSION
9
+ spec.authors = ['Mirosław Pragłowski']
10
+ spec.email = ['m@praglowski.com', 'dev@arkency.com']
11
+
12
+ spec.summary = %q{HttpEventStore is a HTTP connector to the Greg's Event Store.}
13
+ spec.description = %q{HttpEventStore is a HTTP connector to the Greg's Event Store.}
14
+ spec.homepage = "https://github.com/arkency/http_event_store"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.8'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec'
24
+ spec.add_development_dependency 'pry'
25
+
26
+ spec.add_dependency 'faraday'
27
+ spec.add_dependency 'faraday_middleware'
28
+ spec.add_dependency 'json'
29
+ spec.add_dependency 'hashie'
30
+ end
@@ -0,0 +1,18 @@
1
+ require 'http_event_store/api/client'
2
+ require 'http_event_store/api/connection'
3
+ require 'http_event_store/api/errors_handler'
4
+ require 'http_event_store/connection'
5
+ require 'http_event_store/event'
6
+ require 'http_event_store/errors'
7
+ require 'http_event_store/endpoint'
8
+ require 'http_event_store/helpers/parse_entries'
9
+ require 'http_event_store/helpers/parse_state'
10
+ require 'http_event_store/actions/append_event_to_stream'
11
+ require 'http_event_store/actions/delete_stream'
12
+ require 'http_event_store/actions/read_all_stream_events'
13
+ require 'http_event_store/actions/read_all_stream_events_backward'
14
+ require 'http_event_store/actions/read_all_stream_events_forward'
15
+ require 'http_event_store/actions/read_stream_events_backward'
16
+ require 'http_event_store/actions/read_stream_events_forward'
17
+ require 'http_event_store/actions/read_projection_state'
18
+ require 'http_event_store/actions/set_projection_state'
@@ -0,0 +1,44 @@
1
+ require 'ostruct'
2
+
3
+ module HttpEventStore
4
+ module Actions
5
+ class AppendEventToStream
6
+
7
+ def initialize(client)
8
+ @client = client
9
+ end
10
+
11
+ def call(stream_name, event_data, expected_version = nil)
12
+ events = [event_data].flatten.map do |event_data|
13
+ event_data = OpenStruct.new(event_data) if event_data.is_a?(Hash)
14
+ event = create_event(event_data)
15
+ raise IncorrectStreamData if event.validate || stream_name_incorrect?(stream_name)
16
+ event
17
+ end
18
+
19
+ create_event_in_es(stream_name, events, expected_version)
20
+ rescue ClientError => e
21
+ raise WrongExpectedEventNumber if e.code == 400
22
+ raise StreamAlreadyDeleted if e.code == 410
23
+ end
24
+
25
+ private
26
+ attr_reader :client
27
+
28
+ def create_event(event_data)
29
+ type = event_data.event_type
30
+ data = event_data.data
31
+ event_id = event_data.event_id if event_data.respond_to?(:event_id)
32
+ Event.new(type, data, event_id)
33
+ end
34
+
35
+ def create_event_in_es(stream_name, event, expected_version)
36
+ client.append_to_stream(stream_name, event, expected_version)
37
+ end
38
+
39
+ def stream_name_incorrect?(stream_name)
40
+ stream_name.nil? || stream_name.empty?
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,24 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class DeleteStream
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(stream_name, hard_delete)
10
+ raise IncorrectStreamData if stream_name.nil? || stream_name.empty?
11
+ delete_stream(stream_name, hard_delete)
12
+ rescue ClientError => e
13
+ raise StreamAlreadyDeleted
14
+ end
15
+
16
+ private
17
+ attr_reader :client
18
+
19
+ def delete_stream(stream_name, hard_delete)
20
+ client.delete_stream(stream_name, hard_delete)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadAllStreamEvents
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(stream_name)
10
+ raise IncorrectStreamData if stream_name.nil? || stream_name.empty?
11
+ entries = get_all_stream_entries(stream_name)
12
+ return_events(entries)
13
+ rescue ClientError => e
14
+ raise StreamAlreadyDeleted if e.code == 410
15
+ raise StreamNotFound if e.code == 404
16
+ end
17
+
18
+ private
19
+ attr_reader :client
20
+
21
+ def get_all_stream_entries(stream_name, start_point = nil, entries = [])
22
+ loop do
23
+ start_point, entries = get_next_stream_entries(stream_name, start_point, entries)
24
+ break if start_point.nil?
25
+ end
26
+ entries
27
+ end
28
+
29
+ def get_next_stream_entries(stream_name, start_point = nil, entries = [])
30
+ stream_data = get_stream_batch(stream_name, start_point)
31
+ entries = append_entries(entries, stream_data['entries'])
32
+ start_point = get_next_start_point(stream_data['links'])
33
+ [start_point, entries]
34
+ end
35
+
36
+ def return_events(entries)
37
+ Helpers::ParseEntries.new.call(entries)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,43 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadAllStreamEventsBackward < ReadAllStreamEvents
4
+
5
+ def initialize(client, page_size)
6
+ super(client)
7
+ @start_point = :head
8
+ @count = page_size
9
+ end
10
+
11
+ private
12
+ attr_reader :start_point, :count
13
+
14
+ def append_entries(entries, batch)
15
+ entries + batch
16
+ end
17
+
18
+ def get_stream_batch(stream_name, start)
19
+ if start.nil?
20
+ read_stream_backward(stream_name, start_point, count)
21
+ else
22
+ read_stream_by_url(start)
23
+ end
24
+ end
25
+
26
+ def read_stream_backward(stream_name, next_id, count)
27
+ client.read_stream_backward(stream_name, next_id, count)
28
+ end
29
+
30
+ def read_stream_by_url(uri)
31
+ client.read_stream_page(uri)
32
+ end
33
+
34
+ def get_next_start_point(links)
35
+ link = links.detect { |link| link['relation'] == 'next' }
36
+ unless link.nil?
37
+ link['uri'].slice! client.endpoint.url
38
+ link['uri']
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,43 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadAllStreamEventsForward < ReadAllStreamEvents
4
+
5
+ def initialize(client, page_size)
6
+ super(client)
7
+ @start_point = 0
8
+ @count = page_size
9
+ end
10
+
11
+ private
12
+ attr_reader :start_point, :count
13
+
14
+ def append_entries(entries, batch)
15
+ entries + batch.reverse!
16
+ end
17
+
18
+ def get_stream_batch(stream_name, start)
19
+ if start.nil?
20
+ read_stream_forward(stream_name, start_point, count)
21
+ else
22
+ read_stream_by_url(start)
23
+ end
24
+ end
25
+
26
+ def read_stream_forward(stream_name, next_id, count)
27
+ client.read_stream_forward(stream_name, next_id, count)
28
+ end
29
+
30
+ def read_stream_by_url(uri)
31
+ client.read_stream_page(uri)
32
+ end
33
+
34
+ def get_next_start_point(links)
35
+ link = links.detect { |link| link['relation'] == 'previous' }
36
+ unless link.nil?
37
+ link['uri'].slice! client.endpoint.url
38
+ link['uri']
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,29 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadProjectionState
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(projection_name)
10
+ response = get_projection_state(projection_name)
11
+ return_state(response)
12
+ rescue ClientError => e
13
+ raise StreamAlreadyDeleted if e.code == 410
14
+ raise StreamNotFound if e.code == 404
15
+ end
16
+
17
+ private
18
+ attr_reader :client
19
+
20
+ def get_projection_state(projection_name)
21
+ client.read_projection_page("/projection/#{projection_name}/state")
22
+ end
23
+
24
+ def return_state(state)
25
+ Helpers::ParseState.new.(state)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadStreamEventsBackward
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(stream_name, start, count)
10
+ response = get_stream_batch(stream_name, start, count)
11
+ return_events(response['entries'])
12
+ rescue ClientError => e
13
+ raise StreamAlreadyDeleted if e.code == 410
14
+ raise StreamNotFound if e.code == 404
15
+ end
16
+
17
+ private
18
+ attr_reader :client
19
+
20
+ def get_stream_batch(stream_name, start, count)
21
+ client.read_stream_backward(stream_name, start, count)
22
+ end
23
+
24
+ def return_events(entries)
25
+ Helpers::ParseEntries.new.call(entries)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class ReadStreamEventsForward
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(stream_name, start, count, pool)
10
+ response = get_stream_batch(stream_name, start, count, pool)
11
+ return_events(response['entries'])
12
+ rescue ClientError => e
13
+ raise StreamAlreadyDeleted if e.code == 410
14
+ raise StreamNotFound if e.code == 404
15
+ end
16
+
17
+ private
18
+ attr_reader :client
19
+
20
+ def get_stream_batch(stream_name, start, count, pool)
21
+ client.read_stream_forward(stream_name, start, count, pool)
22
+ end
23
+
24
+ def return_events(entries)
25
+ Helpers::ParseEntries.new.call(entries)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ module HttpEventStore
2
+ module Actions
3
+ class SetProjectionState
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def call(projection_name, state)
10
+ response = set_projection_state(projection_name, state)
11
+ rescue ClientError => e
12
+
13
+ end
14
+
15
+ private
16
+ attr_reader :client
17
+
18
+ def set_projection_state(projection_name, state)
19
+ client.set_projection_state(projection_name, state)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ module HttpEventStore
2
+ module Api
3
+ class Client
4
+ VDN_EVENTSTORE_EVENTS_JSON = 'application/vnd.eventstore.events+json'.freeze
5
+ JSON = 'application/json'.freeze
6
+
7
+ VDN_EVENTSTORE_EVENTS_JSON_HEADERS = { "accept" => VDN_EVENTSTORE_EVENTS_JSON, "content-type" => VDN_EVENTSTORE_EVENTS_JSON }.freeze
8
+ JSON_HEADERS = { "accept" => JSON, "content-type" => JSON }.freeze
9
+
10
+ def initialize(endpoint, port, page_size)
11
+ @endpoint = Endpoint.new(endpoint, port)
12
+ @page_size = page_size
13
+ end
14
+ attr_reader :endpoint, :page_size
15
+
16
+ def append_to_stream(stream_name, event_data, expected_version = nil)
17
+ headers = VDN_EVENTSTORE_EVENTS_JSON_HEADERS.merge({"ES-ExpectedVersion" => "#{expected_version}"}.reject { |key, val| val.empty? })
18
+
19
+ data = [event_data].flatten.map do |event|
20
+ {
21
+ eventId: event.event_id,
22
+ eventType: event.type,
23
+ data: event.data
24
+ }
25
+ end
26
+
27
+ make_request(:post, "/streams/#{stream_name}", data, headers)
28
+ end
29
+
30
+ def delete_stream(stream_name, hard_delete)
31
+ headers = JSON_HEADERS.merge({"ES-HardDelete" => "#{hard_delete}"})
32
+ make_request(:delete, "/streams/#{stream_name}", {}, headers)
33
+ end
34
+
35
+ def read_stream_backward(stream_name, start, count)
36
+ make_request(:get, "/streams/#{stream_name}/#{start}/backward/#{count}", {}, JSON_HEADERS)
37
+ end
38
+
39
+ def read_stream_forward(stream_name, start, count, long_pool = 0)
40
+ headers = long_pool > 0 ? JSON_HEADERS.merge({"ES-LongPoll" => "#{long_pool}"}) : JSON_HEADERS
41
+ make_request(:get, "/streams/#{stream_name}/#{start}/forward/#{count}", {}, headers)
42
+ end
43
+
44
+ def read_stream_page(uri)
45
+ make_request(:get, uri, {}, JSON_HEADERS)
46
+ end
47
+ alias_method :read_projection_page, :read_stream_page
48
+
49
+ private
50
+
51
+ def make_request(method, path, body={}, headers={})
52
+ connection.send(method, path) do |req|
53
+ req.headers = req.headers.merge(headers)
54
+ req.body = body.to_json
55
+ req.params['embed'] = 'body' if method == :get
56
+ end.body
57
+ end
58
+
59
+ def connection
60
+ @connection ||= Api::Connection.new(endpoint).call
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,27 @@
1
+ module HttpEventStore
2
+ module Api
3
+ class Connection
4
+ APP_JSON = 'application/json'.freeze
5
+
6
+ def initialize(endpoint)
7
+ @endpoint = endpoint
8
+ end
9
+
10
+ def call
11
+ Faraday.new(
12
+ url: endpoint.url,
13
+ ) do |builder|
14
+ builder.request :retry, max: 4, interval: 0.05,
15
+ interval_randomness: 0.5, backoff_factor: 2
16
+ builder.adapter Faraday.default_adapter
17
+ builder.response :json, content_type: APP_JSON
18
+ builder.response :mashify
19
+ builder.use ErrorsHandler
20
+ end
21
+ end
22
+
23
+ private
24
+ attr_reader :endpoint
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module HttpEventStore
5
+ module Api
6
+ class ErrorsHandler < Faraday::Response::Middleware
7
+
8
+ def on_complete(env)
9
+ code = env[:status]
10
+ case code
11
+ when (400..499)
12
+ raise ClientError.new(code)
13
+ when (500..599)
14
+ raise ServerError.new(code)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ module HttpEventStore
2
+ class Connection
3
+ attr_accessor :endpoint, :port, :page_size
4
+
5
+ def initialize
6
+ setup_defaults
7
+ yield(self) if block_given?
8
+ end
9
+
10
+ def append_to_stream(stream_name, event_data, expected_version = nil)
11
+ Actions::AppendEventToStream.new(client).call(stream_name, event_data, expected_version)
12
+ end
13
+
14
+ def delete_stream(stream_name, hard_delete = false)
15
+ Actions::DeleteStream.new(client).call(stream_name, hard_delete)
16
+ end
17
+
18
+ def read_events_forward(stream_name, start, count, pool = 0)
19
+ Actions::ReadStreamEventsForward.new(client).call(stream_name, start, count, pool)
20
+ end
21
+
22
+ def read_events_backward(stream_name, start, count)
23
+ Actions::ReadStreamEventsBackward.new(client).call(stream_name, start, count)
24
+ end
25
+
26
+ def read_all_events_forward(stream_name)
27
+ Actions::ReadAllStreamEventsForward.new(client, page_size).call(stream_name)
28
+ end
29
+
30
+ def read_all_events_backward(stream_name)
31
+ Actions::ReadAllStreamEventsBackward.new(client, page_size).call(stream_name)
32
+ end
33
+
34
+ def read_projection_state(projection_name)
35
+ Actions::ReadProjectionState.new(client).call(projection_name)
36
+ end
37
+
38
+ def set_projection_state(projection_name, state)
39
+ Actions::SetProjectionState.new(client).call(projection_name, state)
40
+ end
41
+
42
+ private
43
+
44
+ def client
45
+ @client ||= Api::Client.new(endpoint, port, page_size)
46
+ end
47
+
48
+ def setup_defaults
49
+ @endpoint = 'localhost'
50
+ @port = 2113
51
+ @page_size = 20
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,16 @@
1
+ module HttpEventStore
2
+ class Endpoint
3
+
4
+ def initialize(endpoint, port)
5
+ @endpoint = endpoint
6
+ @port = port
7
+ end
8
+
9
+ def url
10
+ "http://#{endpoint}:#{port.to_s}"
11
+ end
12
+
13
+ private
14
+ attr_reader :endpoint, :port
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ module HttpEventStore
2
+ class ClientError < StandardError
3
+ attr_accessor :code
4
+ def initialize(code)
5
+ @code = code
6
+ super()
7
+ end
8
+ end
9
+ class ServerError < StandardError
10
+ attr_accessor :code
11
+ def initialize(code)
12
+ @code = code
13
+ super()
14
+ end
15
+ end
16
+ IncorrectStreamData = Class.new(StandardError)
17
+ WrongExpectedEventNumber = Class.new(StandardError)
18
+ StreamAlreadyDeleted = Class.new(StandardError)
19
+ StreamNotFound = Class.new(StandardError)
20
+ end
@@ -0,0 +1,16 @@
1
+ require 'securerandom'
2
+
3
+ class Event < Struct.new(:type, :data, :source_event_uri, :event_id, :id, :position, :stream_name, :created_time)
4
+ def initialize(type, data, source_event_uri=nil, event_id=nil, id=nil, position=nil, stream_name=nil, created_time=nil)
5
+ event_id = SecureRandom.uuid if event_id.nil?
6
+ super
7
+ end
8
+
9
+ def validate
10
+ [self.event_id, self.type, self.data].any? { |var| var.nil? || var.empty? }
11
+ end
12
+
13
+ def to_json(options)
14
+ self.to_h.to_json
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ require 'time'
2
+
3
+ module HttpEventStore
4
+ module Helpers
5
+ class ParseEntries
6
+
7
+ def call(entries)
8
+ entries.collect do |entry|
9
+ create_event(entry)
10
+ end.compact
11
+ end
12
+
13
+ private
14
+
15
+ def create_event(entry)
16
+ id = entry['eventNumber']
17
+ event_id = entry['eventId']
18
+ type = entry['eventType']
19
+ source_event_uri = entry['id']
20
+ return nil unless entry['data']
21
+ data = JSON.parse(entry['data'])
22
+ stream_name = entry['streamId']
23
+ position = entry['positionEventNumber']
24
+ created_time = entry['updated'] ? Time.parse(entry['updated']) : nil
25
+ Event.new(type, data, source_event_uri, event_id, id, position, stream_name, created_time)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,10 @@
1
+ module HttpEventStore
2
+ module Helpers
3
+ class ParseState
4
+
5
+ def call(state)
6
+ state
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module HttpEventStore
2
+ VERSION = '0.2.1'
3
+ end
metadata ADDED
@@ -0,0 +1,183 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: http_event_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Mirosław Pragłowski
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: pry
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
+ - !ruby/object:Gem::Dependency
70
+ name: faraday
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday_middleware
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: hashie
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: HttpEventStore is a HTTP connector to the Greg's Event Store.
126
+ email:
127
+ - m@praglowski.com
128
+ - dev@arkency.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - ".gitignore"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - LICENSE
137
+ - README.md
138
+ - Rakefile
139
+ - http_event_store.gemspec
140
+ - lib/http_event_store.rb
141
+ - lib/http_event_store/actions/append_event_to_stream.rb
142
+ - lib/http_event_store/actions/delete_stream.rb
143
+ - lib/http_event_store/actions/read_all_stream_events.rb
144
+ - lib/http_event_store/actions/read_all_stream_events_backward.rb
145
+ - lib/http_event_store/actions/read_all_stream_events_forward.rb
146
+ - lib/http_event_store/actions/read_projection_state.rb
147
+ - lib/http_event_store/actions/read_stream_events_backward.rb
148
+ - lib/http_event_store/actions/read_stream_events_forward.rb
149
+ - lib/http_event_store/actions/set_projection_state.rb
150
+ - lib/http_event_store/api/client.rb
151
+ - lib/http_event_store/api/connection.rb
152
+ - lib/http_event_store/api/errors_handler.rb
153
+ - lib/http_event_store/connection.rb
154
+ - lib/http_event_store/endpoint.rb
155
+ - lib/http_event_store/errors.rb
156
+ - lib/http_event_store/event.rb
157
+ - lib/http_event_store/helpers/parse_entries.rb
158
+ - lib/http_event_store/helpers/parse_state.rb
159
+ - lib/http_event_store/version.rb
160
+ homepage: https://github.com/arkency/http_event_store
161
+ licenses: []
162
+ metadata: {}
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ requirements: []
178
+ rubyforge_project:
179
+ rubygems_version: 2.5.1
180
+ signing_key:
181
+ specification_version: 4
182
+ summary: HttpEventStore is a HTTP connector to the Greg's Event Store.
183
+ test_files: []