event_store_client 1.0.6 → 1.0.11

Sign up to get free protection for your applications and to get access to all the features.
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