event_store_client 1.0.6 → 1.0.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 073a691ef952647fd7be92fad2526a279dccfe05867c524ccab6a86aee815dd2
4
- data.tar.gz: 75c51d92577ceb57488e07761466dd58bf1b8cb52e23ee11a82d40bdfb387039
3
+ metadata.gz: 7046a3740fb53a00a8c30786e4bf6af390ba8a93be973412514baff7065731d1
4
+ data.tar.gz: ba04c6804ebfa8d7e876f14766f87f806adff2dee66e2f1e02a6d0644acad357
5
5
  SHA512:
6
- metadata.gz: c9ba15429219f65fc9a7473642ff2e7a0c048cf14a0246f00ecac62ad5daf38ab9c0a800993911d14cd142706ec1d3f5e233e092279391c7c7d9d43683468a05
7
- data.tar.gz: 27f4088d4e92c6a0cef51a93970559a4253d44789e5d9c3a744afebc59de027f3f1853e0c527de5438ede1031bd5cf9ad36aff2e6f8f82856202c23a45b47025
6
+ metadata.gz: 3657c4a696a35b85f37995cae37af7fd31d7c287f751a8444e1e63c640d7ec5dd9e874164c5448aa0cee5030029d8b80797308676a528a5ec42af71800ea5677
7
+ data.tar.gz: d17ed0da65846b1e79caa8bbef2ad9968de9627605c3eb0b7b64eee6558e1768171e087604e9c2563666334da4f148913e82df8d35acd6a74852b548af641cc1
data/README.md CHANGED
@@ -3,19 +3,19 @@
3
3
 
4
4
  # EventStoreClient
5
5
 
6
- An easy-to use API client for connecting ruby applications with https://eventstore.org/
6
+ An easy-to use API client for connecting ruby applications with [EventStoreDB](https://eventstore.com/)
7
7
 
8
8
  ## Supported adapters
9
9
 
10
- - GRPC - default
10
+ - [GRPC](https://github.com/yousty/event_store_client/tree/master/lib/event_store_client/adapters/grpc/README.md) - default
11
11
  - [HTTP](https://github.com/yousty/event_store_client/tree/master/lib/event_store_client/adapters/http/README.md) - Deprecated
12
- - Memory - for testing
12
+ - InMemory - for testing
13
13
 
14
14
  ## Installation
15
15
  Add this line to your application's Gemfile:
16
16
 
17
17
  ```ruby
18
- gem 'event_store_client'
18
+ gem 'event_store_client', '~> 1.0'
19
19
  ```
20
20
 
21
21
  And then execute:
@@ -30,19 +30,8 @@ $ gem install event_store_client
30
30
 
31
31
  ## Usage
32
32
 
33
- Before you start, make sure you have a running EventStoreDB instance on your machine
34
-
35
- ### EventStore engine setup
36
-
37
- 1. Download Event Store From https://eventstore.org/downloads/ or docker
38
-
39
- ` docker pull eventstore/eventstore`
40
-
41
- 2. Run the Event Store server
42
-
43
- `docker run --env EVENTSTORE_INSECURE=true --name eventstore -it -p 2113:2113 -p 1113:1113 eventstore/eventstore`
44
-
45
- 4. Visit the admin panel http://localhost:2113 and enable Projections for Event-Types
33
+ Before you start, make sure you are connecting to a running EventStoreDB instance. For a detailed guide see:
34
+ [EventStoreServerSetup](https://github.com/yousty/event_store_client/blob/master/docs/eventstore_server_setup.md)
46
35
 
47
36
  ### Create Dummy event and dummy Handler
48
37
 
@@ -76,71 +65,99 @@ class DummyHandler
76
65
  end
77
66
  end
78
67
  ```
79
- ## Usage
68
+
80
69
 
81
70
  ```ruby
82
- # initialize the client
83
- client = EventStoreClient::Client.new
84
- ```
85
71
 
86
- ### Publishing events
72
+ require 'event_store_client'
73
+ require "event_store_client/adapters/grpc"
87
74
 
88
- ```ruby
89
- client.publish(stream: 'newstream', events: [event])
90
- ```
75
+ EventStoreClient.configure do |config|
76
+ config.eventstore_url = ENV['EVENTSTORE_URL']
77
+ config.eventstore_user = ENV['EVENTSTORE_USER']
78
+ config.eventstore_password = ENV['EVENTSTORE_PASSWORD']
79
+ config.verify_ssl = false # remove this line if your server does have the host verified
80
+ end
91
81
 
92
- ### Reading from a stream
82
+ event_store = EventStoreClient::Client.new
93
83
 
94
- ```ruby
95
- events = client.read('newstream')
84
+ event_store.subscribe(
85
+ DummyHandler.new,
86
+ to: [SomethingHappened]
87
+ )
88
+
89
+ event_store.listen
96
90
  ```
97
91
 
98
- **Changing reading direction**
92
+ ## Features
99
93
 
100
- ```ruby
101
- events = client.read('newstream', direction: 'backwards') #default 'forwards'
102
- ```
94
+ ## Basic Usage
103
95
 
104
- **Reading all events from a stream**
96
+ The main interface allows for actions listed below which is enough for basic useage.
97
+ The actual adapter allows for more actions. Contributions as always welcome!
105
98
 
106
99
  ```ruby
107
- events = client.read('newstream', all: true) #default 'false'
108
- ```
100
+ # Publishing to a stream
101
+ event_store.publish(stream: 'newstream', events: [event])
109
102
 
110
- ### Subscribing to events
103
+ # Reading from a stream
104
+ events = event_store.read('newstream').value!
111
105
 
112
- ```ruby
113
- client.subscribe(DummyHandler.new, to: [SomethingHappened])
106
+ # Reading all events from a stream
107
+ events = event_store.read('newstream', options: { all: true }).value! #default 'false'
114
108
 
115
- # Now In another terminal seesion try to publish several events
116
- 10.times { client.publish(stream: 'newstream', events: [event]) }
109
+ # Linking existing events to a new stream
110
+ event_store.link_to(stream_name, events)
117
111
 
118
- # You can also publish multiple events at once
112
+ # Subscribing to events
113
+ event_store.subscribe(DummyHandler.new, to: [SomethingHappened])
119
114
 
120
- events = (1..10).map { event }
121
- client.publish(stream: 'newstream', events: events)
115
+ # Listening to new events for all registered subscriptions
116
+ event_store.listen
122
117
 
118
+ # In the new terminal session publish some events
119
+ events = (1..10).map { event }
120
+ event_store.publish(stream: 'newstream', events: events)
123
121
  # .... wait a little bit ... Your handler should be called for every single event you publish
124
122
  ```
125
123
 
126
- ### Stop polling for new events
124
+ ### Extended usage
127
125
 
128
- ```ruby
129
- client.stop_polling
126
+ You can get access to more features by calling the adapter directly, for example:
127
+
128
+ ```
129
+ event_store.connection.delete_stream(stream)
130
+ event_store.connection.tombstone_stream(stream)
130
131
  ```
131
132
 
132
- ### Configure EventStoreClient
133
+ See the adapters method list for the possible usage.
133
134
 
134
- Before you start, add this to the `initializer` or to the top of your script:
135
+ - [HTTP](https://github.com/yousty/event_store_client/blob/master/lib/event_store_client/adapters/http/client.rb)
136
+ - [GRPC](https://github.com/yousty/event_store_client/blob/master/lib/event_store_client/adapters/grpc/client.rb)
135
137
 
136
- For testing, you can use the InMemory adapter. To do it you should change the configuration.
138
+ ### Configuration
139
+
140
+ There are several configuration options you can pass to customize your client's instance.
141
+ All the config options can be passed the same way:
137
142
 
138
143
  ```ruby
139
144
  EventStoreClient.configure do |config|
140
- config.adapter = EventStoreClient::InMemory.new(host: 'http://localhost', port: '2113')
145
+ config.adapter = :grpc
141
146
  end
142
147
  ```
143
148
 
149
+ | name | value | default | description |
150
+ |:-------------:|:-------------:|:-----:|:-------------:|
151
+ | adapter | `:grpc`, `:http` or `:in_memory` | `:grpc` | different ways to connect with an event_store_db. The in_memory is a mock server useful for testing |
152
+ | verify_ssl | Boolean | true | Useful for self-signed certificates (Kubernetes, local development) |
153
+ | error_handler | Any callable ruby object | EvenStoreClient::ErrorHandler | You can pass a custom error handler for reacting on event_handler errors.|
154
+ | eventstore_url| String| 'http://localhost:2113'| An url for the server instance|
155
+ | user| String| 'admin' | a user used to connect the application with the server|
156
+ | password| String| 'changeit'| a password used to connect the application with the server|
157
+ | per_page| Integer| 20 | a batch size for events subscriptions |
158
+ | service_name| String| 'default' | a prefix (namespace) added to the subscriptions names|
159
+ | mapper| `Mapper::Default` or `Mapper::Encrypted`| `Mapper::Default.new` | an engine used to parse events.
160
+
144
161
  ## Event Mappers
145
162
 
146
163
  At the moment we offer two types of mappers:
@@ -156,86 +173,7 @@ Event parsable by event_store and the other way around.
156
173
  ### Encrypted Mapper
157
174
 
158
175
  This is implemented to match GDPR requirements. It allows you to encrypt any event using your
159
- encryption_key repository.
160
-
161
- ```ruby
162
- mapper = EventStoreClient::Mapper::Encrypted.new(key_repository)
163
- EventStoreClient.configure do |config|
164
- config.mapper = mapper
165
- end
166
- ```
167
-
168
- The Encrypted mapper uses the encryption key repository to encrypt data in your events according to the event definition.
169
-
170
- Here is the minimal repository interface for this to work.
171
-
172
- ```ruby
173
- class DummyRepository
174
- class Key
175
- attr_accessor :iv, :cipher, :id
176
- def initialize(id:, **)
177
- @id = id
178
- end
179
- end
180
-
181
- def find(user_id)
182
- Key.new(id: user_id)
183
- end
184
-
185
- def encrypt(*)
186
- 'darthvader'
187
- end
188
-
189
- def decrypt(*)
190
- { first_name: 'Anakin', last_name: 'Skylwalker'}
191
- end
192
- end
193
- ```
194
-
195
- Now, having that, you only need to define the event encryption schema:
196
-
197
- ```ruby
198
- class EncryptedEvent < EventStoreClient::DeserializedEvent
199
- def schema
200
- Dry::Schema.Params do
201
- required(:user_id).value(:string)
202
- required(:first_name).value(:string)
203
- required(:last_name).value(:string)
204
- required(:profession).value(:string)
205
- end
206
- end
207
-
208
- def self.encryption_schema
209
- {
210
- key: ->(data) { data['user_id'] },
211
- attributes: %i[first_name last_name email]
212
- }
213
- end
214
- end
215
-
216
- event = EncryptedEvent.new(
217
- user_id: SecureRandom.uuid,
218
- first_name: 'Anakin',
219
- last_name: 'Skylwalker',
220
- profession: 'Jedi'
221
- )
222
- ```
223
-
224
- When you'll publish this event, in the store will be saved:
225
-
226
- ```ruby
227
- {
228
- 'data' => {
229
- 'user_id' => 'dab48d26-e4f8-41fc-a9a8-59657e590716',
230
- 'first_name' => 'encrypted',
231
- 'last_name' => 'encrypted',
232
- 'profession' => 'Jedi',
233
- 'encrypted' => '2345l423lj1#$!lkj24f1'
234
- },
235
- type: 'EncryptedEvent'
236
- metadata: { ... }
237
- }
238
- ```
176
+ encryption_key repository. For the detailed guide see the: [Encrypting Events](https://github.com/yousty/event_store_client/blob/master/docs/encrypting_events.md).
239
177
 
240
178
  ## Contributing
241
179
 
@@ -245,6 +183,8 @@ Do you want to contribute? Welcome!
245
183
  2. Create Issue
246
184
  3. Create PR ;)
247
185
 
186
+ For running the client in the dev mode, see: [Development Guide](https://github.com/yousty/event_store_client/blob/master/docs/eventstore_server_setup.md)
187
+
248
188
  ### Publishing new version
249
189
 
250
190
  1. Push commit with updated `version.rb` file to the `release` branch. The new version will be automatically pushed to [rubygems](https://rubygems.org).
@@ -4,13 +4,14 @@ module EventStoreClient
4
4
  end
5
5
 
6
6
  require 'event_store_client/types'
7
- require 'event_store_client/event'
8
- require 'event_store_client/deserialized_event'
7
+
9
8
  require 'event_store_client/serializer/json'
10
9
 
11
10
  require 'event_store_client/mapper'
12
11
 
13
12
  require 'event_store_client/configuration'
13
+ require 'event_store_client/event'
14
+ require 'event_store_client/deserialized_event'
14
15
 
15
16
  require 'event_store_client/subscription'
16
17
  require 'event_store_client/subscriptions'
@@ -0,0 +1,16 @@
1
+ ### GRPC adapter
2
+
3
+ This adapter targets the EventstoreDB version `>= "20.*"
4
+
5
+ ### Configuration
6
+
7
+ As by default EventStoreClient uses GRPC adapter. No need to configure anything if you want to use it,
8
+ however to set it explicitly, place the snippet below in your initializer or when you boot your application.
9
+
10
+ ```ruby
11
+ require 'event_store_client/adapters/grpc'
12
+
13
+ EventStoreClient.configure do |config|
14
+ config.adapter = :grpc
15
+ end
16
+ ```
@@ -44,8 +44,8 @@ module EventStoreClient
44
44
  id: {
45
45
  string: SecureRandom.uuid
46
46
  },
47
- data: event.data,
48
- custom_metadata: JSON.generate(custom_metadata),
47
+ data: event.data.b,
48
+ custom_metadata: JSON.generate(custom_metadata),
49
49
  metadata: event_metadata
50
50
  }
51
51
  )
@@ -1,8 +1,6 @@
1
1
  ### HTTP adapter
2
2
 
3
- This adapter targets the EventstoreDB version `>= "5.*"
4
-
5
- For detailed docs about the http protocol see [EventStoreDB Http Documentation](https://developers.eventstore.com/server/5.0.8/http-api/)
3
+ This adapter targets the EventstoreDB version `>= "20.*"
6
4
 
7
5
  ### Configuration
8
6
 
@@ -10,7 +8,9 @@ As by default EventStoreClient uses gRPC adapter, to switch to http you need to
10
8
  Place the snippet below in your initializer or when you boot your application.
11
9
 
12
10
  ```ruby
11
+ require 'event_store_client/adapters/http'
12
+
13
13
  EventStoreClient.configure do |config|
14
- config.adapter = :api
14
+ config.adapter = :http
15
15
  end
16
16
  ```
@@ -47,9 +47,7 @@ module EventStoreClient
47
47
  # @return Dry::Monads::Result::Success with returned events or Dry::Monads::Result::Failure
48
48
  #
49
49
  def read(stream_name, options: {})
50
- Commands::Streams::Read.new(connection).call(
51
- stream_name, options: options
52
- )
50
+ Commands::Streams::Read.new(connection).call(stream_name, options: options)
53
51
  end
54
52
 
55
53
  # Reads all events from the given stream
@@ -11,10 +11,8 @@ module EventStoreClient
11
11
  count = options[:count] || config.per_page
12
12
  start = options[:start].to_i
13
13
  direction = options[:direction] || 'forward'
14
- headers = {
15
- 'ES-ResolveLinkTos' => options[:resolve_links].to_s,
16
- 'Accept' => 'application/vnd.eventstore.atom+json'
17
- }
14
+ headers = { 'Accept' => 'application/vnd.eventstore.atom+json' }
15
+ headers['ES-ResolveLinkTos'] = true if options.key?(:resolve_links)
18
16
 
19
17
  response =
20
18
  connection.call(
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'dry-configurable'
4
-
4
+ require 'event_store_client/error_handler'
5
5
  module EventStoreClient
6
6
  extend Dry::Configurable
7
7
 
@@ -10,7 +10,7 @@ module EventStoreClient
10
10
  setting :adapter, :grpc
11
11
  setting :verify_ssl, true
12
12
 
13
- setting :error_handler
13
+ setting :error_handler, ErrorHandler.new
14
14
  setting :eventstore_url, 'http://localhost:2113' do |value|
15
15
  value.is_a?(URI) ? value : URI(value)
16
16
  end
@@ -19,7 +19,9 @@ module EventStoreClient
19
19
 
20
20
  def initialize(**args)
21
21
  validation = schema.call(args[:data] || {})
22
- raise InvalidDataError.new(message: validation.errors.to_h) if validation.errors.any?
22
+ if validation.errors.any?
23
+ raise InvalidDataError.new(message: "#{schema.class.name} #{validation.errors.to_h}")
24
+ end
23
25
 
24
26
  @data = args.fetch(:data) { {} }
25
27
  @metadata = args.fetch(:metadata) { {} }.merge(
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EventStoreClient
4
+ class ErrorHandler
5
+ def call(error)
6
+ puts error
7
+ puts error.backtrace
8
+ end
9
+ end
10
+ end
@@ -13,7 +13,8 @@ module EventStoreClient
13
13
  else
14
14
  subscriber.class.name
15
15
  end
16
- @name = "#{service}-#{subscriber_class}"
16
+ @name = subscriber_class.to_s
17
+ @name = "#{service}-" + @name if service != ''
17
18
  @subscriber = subscriber
18
19
  @stream = name
19
20
  @observed_streams = event_types.reduce([]) { |r, type| r << "$et-#{type}" }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EventStoreClient
4
- VERSION = '1.0.6'
4
+ VERSION = '1.0.11'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event_store_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sebastian Wilgosz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-02 00:00:00.000000000 Z
11
+ date: 2021-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-configurable
@@ -156,6 +156,7 @@ files:
156
156
  - lib/event_store_client/adapters/grpc/Protos/shared.proto
157
157
  - lib/event_store_client/adapters/grpc/Protos/streams.proto
158
158
  - lib/event_store_client/adapters/grpc/Protos/users.proto
159
+ - lib/event_store_client/adapters/grpc/README.md
159
160
  - lib/event_store_client/adapters/grpc/client.rb
160
161
  - lib/event_store_client/adapters/grpc/command_registrar.rb
161
162
  - lib/event_store_client/adapters/grpc/commands/command.rb
@@ -212,6 +213,7 @@ files:
212
213
  - lib/event_store_client/data_encryptor.rb
213
214
  - lib/event_store_client/deserialized_event.rb
214
215
  - lib/event_store_client/encryption_metadata.rb
216
+ - lib/event_store_client/error_handler.rb
215
217
  - lib/event_store_client/event.rb
216
218
  - lib/event_store_client/mapper.rb
217
219
  - lib/event_store_client/mapper/default.rb
@@ -242,7 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
242
244
  - !ruby/object:Gem::Version
243
245
  version: '0'
244
246
  requirements: []
245
- rubygems_version: 3.1.4
247
+ rubygems_version: 3.0.6
246
248
  signing_key:
247
249
  specification_version: 4
248
250
  summary: Ruby integration for https://eventstore.org