event_store_client 1.4.9 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +30 -145
- data/docs/appending_events.md +155 -0
- data/docs/catch_up_subscriptions.md +253 -0
- data/docs/configuration.md +83 -0
- data/docs/deleting_streams.md +25 -0
- data/docs/encrypting_events.md +84 -0
- data/docs/linking_events.md +149 -0
- data/docs/reading_events.md +200 -0
- data/lib/event_store_client/adapters/grpc/client.rb +244 -105
- data/lib/event_store_client/adapters/grpc/cluster/gossip_discover.rb +131 -0
- data/lib/event_store_client/adapters/grpc/cluster/insecure_connection.rb +21 -0
- data/lib/event_store_client/adapters/grpc/cluster/member.rb +18 -0
- data/lib/event_store_client/adapters/grpc/cluster/queryless_discover.rb +25 -0
- data/lib/event_store_client/adapters/grpc/cluster/secure_connection.rb +71 -0
- data/lib/event_store_client/adapters/grpc/command_registrar.rb +7 -7
- data/lib/event_store_client/adapters/grpc/commands/command.rb +63 -25
- data/lib/event_store_client/adapters/grpc/commands/gossip/cluster_info.rb +24 -0
- data/lib/event_store_client/adapters/grpc/commands/streams/append.rb +43 -68
- data/lib/event_store_client/adapters/grpc/commands/streams/append_multiple.rb +44 -0
- data/lib/event_store_client/adapters/grpc/commands/streams/delete.rb +21 -17
- data/lib/event_store_client/adapters/grpc/commands/streams/hard_delete.rb +39 -0
- data/lib/event_store_client/adapters/grpc/commands/streams/link_to.rb +7 -52
- data/lib/event_store_client/adapters/grpc/commands/streams/link_to_multiple.rb +44 -0
- data/lib/event_store_client/adapters/grpc/commands/streams/read.rb +20 -85
- data/lib/event_store_client/adapters/grpc/commands/streams/read_paginated.rb +174 -0
- data/lib/event_store_client/adapters/grpc/commands/streams/subscribe.rb +31 -106
- data/lib/event_store_client/adapters/grpc/connection.rb +56 -36
- data/lib/event_store_client/adapters/grpc/discover.rb +75 -0
- data/lib/event_store_client/adapters/grpc/generated/cluster_pb.rb +106 -18
- data/lib/event_store_client/adapters/grpc/generated/cluster_services_pb.rb +12 -12
- data/lib/event_store_client/adapters/grpc/generated/code_pb.rb +34 -0
- data/lib/event_store_client/adapters/grpc/generated/gossip_pb.rb +3 -2
- data/lib/event_store_client/adapters/grpc/generated/gossip_services_pb.rb +3 -3
- data/lib/event_store_client/adapters/grpc/generated/monitoring_pb.rb +25 -0
- data/lib/event_store_client/adapters/grpc/generated/monitoring_services_pb.rb +26 -0
- data/lib/event_store_client/adapters/grpc/generated/operations_pb.rb +2 -1
- data/lib/event_store_client/adapters/grpc/generated/operations_services_pb.rb +8 -7
- data/lib/event_store_client/adapters/grpc/generated/persistent_pb.rb +199 -38
- data/lib/event_store_client/adapters/grpc/generated/persistent_services_pb.rb +7 -3
- data/lib/event_store_client/adapters/grpc/generated/projections_pb.rb +9 -26
- data/lib/event_store_client/adapters/grpc/generated/projections_services_pb.rb +4 -3
- data/lib/event_store_client/adapters/grpc/generated/serverfeatures_pb.rb +29 -0
- data/lib/event_store_client/adapters/grpc/generated/serverfeatures_services_pb.rb +26 -0
- data/lib/event_store_client/adapters/grpc/generated/shared_pb.rb +54 -12
- data/lib/event_store_client/adapters/grpc/generated/status_pb.rb +23 -0
- data/lib/event_store_client/adapters/grpc/generated/streams_pb.rb +104 -64
- data/lib/event_store_client/adapters/grpc/generated/streams_services_pb.rb +3 -2
- data/lib/event_store_client/adapters/grpc/generated/users_services_pb.rb +2 -2
- data/lib/event_store_client/adapters/grpc/options/streams/read_options.rb +78 -0
- data/lib/event_store_client/adapters/grpc/options/streams/write_options.rb +39 -0
- data/lib/event_store_client/adapters/grpc/shared/event_deserializer.rb +52 -0
- data/lib/event_store_client/adapters/grpc/shared/options/filter_options.rb +76 -0
- data/lib/event_store_client/adapters/grpc/shared/options/stream_options.rb +91 -0
- data/lib/event_store_client/adapters/grpc/shared/streams/process_response.rb +28 -0
- data/lib/event_store_client/adapters/grpc/shared/streams/process_responses.rb +33 -0
- data/lib/event_store_client/adapters/grpc.rb +28 -12
- data/lib/event_store_client/configuration.rb +39 -54
- data/lib/event_store_client/connection/url.rb +57 -0
- data/lib/event_store_client/connection/url_parser.rb +144 -0
- data/lib/event_store_client/data_decryptor.rb +2 -9
- data/lib/event_store_client/deserialized_event.rb +35 -10
- data/lib/event_store_client/encryption_metadata.rb +0 -1
- data/lib/event_store_client/event.rb +4 -2
- data/lib/event_store_client/extensions/options_extension.rb +87 -0
- data/lib/event_store_client/mapper/default.rb +12 -9
- data/lib/event_store_client/mapper/encrypted.rb +18 -17
- data/lib/event_store_client/types.rb +1 -1
- data/lib/event_store_client/utils.rb +30 -0
- data/lib/event_store_client/version.rb +1 -1
- data/lib/event_store_client.rb +8 -7
- metadata +74 -83
- data/lib/event_store_client/adapters/grpc/Protos/cluster.proto +0 -149
- data/lib/event_store_client/adapters/grpc/Protos/gossip.proto +0 -44
- data/lib/event_store_client/adapters/grpc/Protos/operations.proto +0 -45
- data/lib/event_store_client/adapters/grpc/Protos/persistent.proto +0 -180
- data/lib/event_store_client/adapters/grpc/Protos/projections.proto +0 -174
- data/lib/event_store_client/adapters/grpc/Protos/shared.proto +0 -22
- data/lib/event_store_client/adapters/grpc/Protos/streams.proto +0 -242
- data/lib/event_store_client/adapters/grpc/Protos/users.proto +0 -119
- data/lib/event_store_client/adapters/grpc/README.md +0 -16
- data/lib/event_store_client/adapters/grpc/commands/persistent_subscriptions/create.rb +0 -46
- data/lib/event_store_client/adapters/grpc/commands/persistent_subscriptions/delete.rb +0 -34
- data/lib/event_store_client/adapters/grpc/commands/persistent_subscriptions/read.rb +0 -77
- data/lib/event_store_client/adapters/grpc/commands/persistent_subscriptions/settings_schema.rb +0 -38
- data/lib/event_store_client/adapters/grpc/commands/persistent_subscriptions/update.rb +0 -48
- data/lib/event_store_client/adapters/grpc/commands/projections/create.rb +0 -48
- data/lib/event_store_client/adapters/grpc/commands/projections/delete.rb +0 -34
- data/lib/event_store_client/adapters/grpc/commands/projections/update.rb +0 -44
- data/lib/event_store_client/adapters/grpc/commands/streams/read_all.rb +0 -43
- data/lib/event_store_client/adapters/grpc/commands/streams/tombstone.rb +0 -35
- data/lib/event_store_client/adapters/http/README.md +0 -16
- data/lib/event_store_client/adapters/http/client.rb +0 -161
- data/lib/event_store_client/adapters/http/commands/command.rb +0 -27
- data/lib/event_store_client/adapters/http/commands/persistent_subscriptions/ack.rb +0 -15
- data/lib/event_store_client/adapters/http/commands/persistent_subscriptions/create.rb +0 -35
- data/lib/event_store_client/adapters/http/commands/persistent_subscriptions/read.rb +0 -60
- data/lib/event_store_client/adapters/http/commands/projections/create.rb +0 -33
- data/lib/event_store_client/adapters/http/commands/projections/update.rb +0 -31
- data/lib/event_store_client/adapters/http/commands/streams/append.rb +0 -49
- data/lib/event_store_client/adapters/http/commands/streams/delete.rb +0 -16
- data/lib/event_store_client/adapters/http/commands/streams/link_to.rb +0 -49
- data/lib/event_store_client/adapters/http/commands/streams/read.rb +0 -52
- data/lib/event_store_client/adapters/http/commands/streams/tombstone.rb +0 -17
- data/lib/event_store_client/adapters/http/connection.rb +0 -46
- data/lib/event_store_client/adapters/http/request_method.rb +0 -28
- data/lib/event_store_client/adapters/http.rb +0 -17
- data/lib/event_store_client/adapters/in_memory.rb +0 -144
- data/lib/event_store_client/broker.rb +0 -40
- data/lib/event_store_client/catch_up_subscription.rb +0 -42
- data/lib/event_store_client/catch_up_subscriptions.rb +0 -92
- data/lib/event_store_client/client.rb +0 -73
- data/lib/event_store_client/error_handler.rb +0 -10
- data/lib/event_store_client/subscription.rb +0 -23
- data/lib/event_store_client/subscriptions.rb +0 -38
- data/lib/event_store_client/value_objects/read_direction.rb +0 -43
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'grpc'
|
4
|
-
require 'event_store_client/adapters/grpc/generated/projections_pb.rb'
|
5
|
-
require 'event_store_client/adapters/grpc/generated/projections_services_pb.rb'
|
6
|
-
|
7
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
8
|
-
|
9
|
-
module EventStoreClient
|
10
|
-
module GRPC
|
11
|
-
module Commands
|
12
|
-
module Projections
|
13
|
-
class Update < Command
|
14
|
-
use_request EventStore::Client::Projections::UpdateReq
|
15
|
-
use_service EventStore::Client::Projections::Projections::Stub
|
16
|
-
|
17
|
-
def call(name, streams)
|
18
|
-
data = <<~STRING
|
19
|
-
fromStreams(#{streams})
|
20
|
-
.when({
|
21
|
-
$any: function(s,e) {
|
22
|
-
linkTo("#{name}", e)
|
23
|
-
}
|
24
|
-
})
|
25
|
-
STRING
|
26
|
-
|
27
|
-
options =
|
28
|
-
{
|
29
|
-
query: data,
|
30
|
-
name: name,
|
31
|
-
emit_enabled: true
|
32
|
-
}
|
33
|
-
|
34
|
-
service.update(request.new(options: options), metadata: metadata)
|
35
|
-
|
36
|
-
Success()
|
37
|
-
rescue ::GRPC::AlreadyExists
|
38
|
-
Failure(:conflict)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'grpc'
|
4
|
-
require 'event_store_client/adapters/grpc/generated/projections_pb.rb'
|
5
|
-
require 'event_store_client/adapters/grpc/generated/projections_services_pb.rb'
|
6
|
-
|
7
|
-
require 'event_store_client/configuration'
|
8
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
9
|
-
require 'event_store_client/adapters/grpc/commands/streams/read'
|
10
|
-
|
11
|
-
module EventStoreClient
|
12
|
-
module GRPC
|
13
|
-
module Commands
|
14
|
-
module Streams
|
15
|
-
class ReadAll < Command
|
16
|
-
include Configuration
|
17
|
-
|
18
|
-
use_request EventStore::Client::Streams::ReadReq
|
19
|
-
use_service EventStore::Client::Streams::Streams::Stub
|
20
|
-
|
21
|
-
def call(stream_name, options: {})
|
22
|
-
start ||= options[:start] || 0
|
23
|
-
count ||= options[:count] || 20
|
24
|
-
events = []
|
25
|
-
|
26
|
-
loop do
|
27
|
-
res = Read.new.call(
|
28
|
-
stream_name, options: options.merge(start: start, count: count)
|
29
|
-
)
|
30
|
-
break if res.failure?
|
31
|
-
break if (entries = res.value!).empty?
|
32
|
-
|
33
|
-
events += entries
|
34
|
-
start += count
|
35
|
-
end
|
36
|
-
|
37
|
-
Success(events)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'grpc'
|
4
|
-
require 'event_store_client/adapters/grpc/generated/projections_pb.rb'
|
5
|
-
require 'event_store_client/adapters/grpc/generated/projections_services_pb.rb'
|
6
|
-
|
7
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
8
|
-
|
9
|
-
module EventStoreClient
|
10
|
-
module GRPC
|
11
|
-
module Commands
|
12
|
-
module Streams
|
13
|
-
class Tombstone < Command
|
14
|
-
use_request EventStore::Client::Streams::TombstoneReq
|
15
|
-
use_service EventStore::Client::Streams::Streams::Stub
|
16
|
-
|
17
|
-
def call(name, options: {})
|
18
|
-
opts =
|
19
|
-
{
|
20
|
-
stream_identifier: {
|
21
|
-
streamName: name
|
22
|
-
},
|
23
|
-
any: {}
|
24
|
-
}
|
25
|
-
|
26
|
-
service.tombstone(request.new(options: opts), metadata: metadata)
|
27
|
-
Success()
|
28
|
-
rescue ::GRPC::FailedPrecondition
|
29
|
-
Failure(:not_found)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
### HTTP adapter
|
2
|
-
|
3
|
-
This adapter targets the EventstoreDB version `>= "20.*"
|
4
|
-
|
5
|
-
### Configuration
|
6
|
-
|
7
|
-
As by default EventStoreClient uses gRPC adapter, to switch to http you need to configure it first.
|
8
|
-
Place the snippet below in your initializer or when you boot your application.
|
9
|
-
|
10
|
-
```ruby
|
11
|
-
require 'event_store_client/adapters/http'
|
12
|
-
|
13
|
-
EventStoreClient.configure do |config|
|
14
|
-
config.adapter = :http
|
15
|
-
end
|
16
|
-
```
|
@@ -1,161 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'event_store_client/adapters/http/connection'
|
4
|
-
require 'dry/monads/result'
|
5
|
-
|
6
|
-
module EventStoreClient
|
7
|
-
module HTTP
|
8
|
-
class Client
|
9
|
-
include Configuration
|
10
|
-
include Dry::Monads[:result]
|
11
|
-
# Appends given events to the stream
|
12
|
-
# @param [String] Stream name to append events to
|
13
|
-
# @param [Array](each: EventStoreClient::DeserializedEvent) list of events to publish
|
14
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
15
|
-
#
|
16
|
-
def append_to_stream(stream_name, events, options: {})
|
17
|
-
Commands::Streams::Append.new(connection).call(
|
18
|
-
stream_name, events, options: options
|
19
|
-
)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Softly deletes the given stream
|
23
|
-
# @param [String] Stream name to delete
|
24
|
-
# @param options [Hash] additional options to the request
|
25
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
26
|
-
#
|
27
|
-
def delete_stream(stream_name, options: {})
|
28
|
-
Commands::Streams::Delete.new(connection).call(
|
29
|
-
stream_name, options: options
|
30
|
-
)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Completely removes the given stream
|
34
|
-
# @param [String] Stream name to delete
|
35
|
-
# @param options [Hash] additional options to the request
|
36
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
37
|
-
#
|
38
|
-
def tombstone_stream(stream_name, options: {})
|
39
|
-
Commands::Streams::Tombstone.new(connection).call(
|
40
|
-
stream_name, options: options
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Reads a page of events from the given stream
|
45
|
-
# @param [String] Stream name to read events from
|
46
|
-
# @param options [Hash] additional options to the request
|
47
|
-
# @return Dry::Monads::Result::Success with returned events or Dry::Monads::Result::Failure
|
48
|
-
#
|
49
|
-
def read(stream_name, options: {})
|
50
|
-
Commands::Streams::Read.new(connection).call(stream_name, options: options)
|
51
|
-
end
|
52
|
-
|
53
|
-
# Reads all events from the given stream
|
54
|
-
# @param [String] Stream name to read events from
|
55
|
-
# @param options [Hash] additional options to the request
|
56
|
-
# @return Dry::Monads::Result::Success with returned events or Dry::Monads::Result::Failure
|
57
|
-
#
|
58
|
-
def read_all_from_stream(stream_name, options: {})
|
59
|
-
start ||= options[:start] || 0
|
60
|
-
count ||= options[:count] || 20
|
61
|
-
events = []
|
62
|
-
failed_requests_count = 0
|
63
|
-
|
64
|
-
while failed_requests_count < 3
|
65
|
-
res = read(stream_name, options: options.merge(start: start, count: count))
|
66
|
-
if res.failure?
|
67
|
-
failed_requests_count += 1
|
68
|
-
else
|
69
|
-
break if res.value!.empty?
|
70
|
-
events += res.value!
|
71
|
-
failed_requests_count = 0
|
72
|
-
start += count
|
73
|
-
end
|
74
|
-
end
|
75
|
-
return Failure(:connection_failed) if failed_requests_count >= 3
|
76
|
-
|
77
|
-
Success(events)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Creates the subscription for the given stream
|
81
|
-
# @param [EventStoreClient::Subscription] subscription to observe
|
82
|
-
# @param options [Hash] additional options to the request
|
83
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
84
|
-
#
|
85
|
-
def subscribe_to_stream(subscription, options: {})
|
86
|
-
join_streams(subscription.name, subscription.observed_streams)
|
87
|
-
Commands::PersistentSubscriptions::Create.new(connection).call(
|
88
|
-
subscription.stream,
|
89
|
-
subscription.name,
|
90
|
-
options: options
|
91
|
-
)
|
92
|
-
end
|
93
|
-
|
94
|
-
# Links given events with the given stream
|
95
|
-
# @param [String] Stream name to link events to
|
96
|
-
# @param [Array](each: EventStoreClient::DeserializedEvent) a list of events to link
|
97
|
-
# @param expected_version [Integer] expected number of events in the stream
|
98
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
99
|
-
#
|
100
|
-
def link_to(stream_name, events, options: {})
|
101
|
-
Commands::Streams::LinkTo.new(connection).call(
|
102
|
-
stream_name, events, options: options
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Runs the persistent subscription indeinitely
|
107
|
-
# @param [EventStoreClient::Subscription] subscription to observe
|
108
|
-
# @param options [Hash] additional options to the request
|
109
|
-
# @return - Nothing, it is a blocking operation, yields the given block with event instead
|
110
|
-
#
|
111
|
-
def listen(subscription, options: {})
|
112
|
-
loop do
|
113
|
-
begin
|
114
|
-
consume_feed(subscription) do |event|
|
115
|
-
yield event if block_given?
|
116
|
-
end
|
117
|
-
rescue StandardError => e
|
118
|
-
config.error_handler&.call(e)
|
119
|
-
end
|
120
|
-
sleep(options[:interval] || 5) # wait for events to be processed
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
private
|
125
|
-
|
126
|
-
attr_reader :connection
|
127
|
-
|
128
|
-
def initialize
|
129
|
-
@connection =
|
130
|
-
Connection.new(config.eventstore_url, ssl: { verify: config.verify_ssl })
|
131
|
-
end
|
132
|
-
|
133
|
-
# @api private
|
134
|
-
# Joins multiple streams into the new one under the given name
|
135
|
-
# @param [String] Name of the stream containing the ones to join
|
136
|
-
# @param [Array] (each: String) list of streams to join together
|
137
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
138
|
-
#
|
139
|
-
def join_streams(name, streams, options: {})
|
140
|
-
res = Commands::Projections::Create.new(connection).call(name, streams, options: options)
|
141
|
-
return res if res.success?
|
142
|
-
|
143
|
-
Commands::Projections::Update.new(connection).call(name, streams, options: options)
|
144
|
-
end
|
145
|
-
|
146
|
-
# @api private
|
147
|
-
# Consumes the new events from the subscription
|
148
|
-
# @param [EventStoreClient::Subscription] subscription to observe
|
149
|
-
# @param options [Hash] additional options to the request
|
150
|
-
# @return Dry::Monads::Result::Success or Dry::Monads::Result::Failure
|
151
|
-
#
|
152
|
-
def consume_feed(subscription, options: {})
|
153
|
-
Commands::PersistentSubscriptions::Read.new(connection).call(
|
154
|
-
subscription.stream, subscription.name, options: options
|
155
|
-
) do |event|
|
156
|
-
yield event if block_given?
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'dry-monads'
|
4
|
-
require 'event_store_client/adapters/grpc/command_registrar'
|
5
|
-
|
6
|
-
module EventStoreClient
|
7
|
-
module HTTP
|
8
|
-
module Commands
|
9
|
-
class Command
|
10
|
-
def self.inherited(klass)
|
11
|
-
super
|
12
|
-
klass.class_eval do
|
13
|
-
include Dry::Monads[:result]
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
protected
|
18
|
-
|
19
|
-
attr_reader :connection
|
20
|
-
|
21
|
-
def initialize(connection)
|
22
|
-
@connection = connection
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module PersistentSubscriptions
|
7
|
-
class Create < Command
|
8
|
-
def call(stream_name, subscription_name, options: {})
|
9
|
-
stats = options[:stats] || true
|
10
|
-
start = options[:start] || 0
|
11
|
-
retries = options[:retries] || 5
|
12
|
-
max_checkpoint_count = options[:max_checkpoint_count] || 0
|
13
|
-
min_checkpoint_count = options[:min_checkpoint_count] || 0
|
14
|
-
|
15
|
-
connection.call(
|
16
|
-
:put,
|
17
|
-
"/subscriptions/#{stream_name}/#{subscription_name}",
|
18
|
-
body: {
|
19
|
-
extraStatistics: stats,
|
20
|
-
startFrom: start,
|
21
|
-
maxRetryCount: retries,
|
22
|
-
maxCheckPointCount: max_checkpoint_count,
|
23
|
-
minCheckPointCount: min_checkpoint_count,
|
24
|
-
resolveLinkTos: true
|
25
|
-
},
|
26
|
-
headers: {
|
27
|
-
'Content-Type' => 'application/json'
|
28
|
-
}
|
29
|
-
)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'event_store_client/adapters/http/commands/persistent_subscriptions/ack'
|
4
|
-
module EventStoreClient
|
5
|
-
module HTTP
|
6
|
-
module Commands
|
7
|
-
module PersistentSubscriptions
|
8
|
-
class Read < Command
|
9
|
-
include Configuration
|
10
|
-
|
11
|
-
def call(stream_name, subscription_name, options: {})
|
12
|
-
count = options[:count] || 20
|
13
|
-
long_poll = options[:long_poll].to_i
|
14
|
-
headers = long_poll.positive? ? { 'ES-LongPoll' => long_poll.to_s } : {}
|
15
|
-
headers['Content-Type'] = 'application/vnd.eventstore.competingatom+json'
|
16
|
-
headers['Accept'] = 'application/vnd.eventstore.competingatom+json'
|
17
|
-
headers['ES-ResolveLinktos'] = (options[:resolve_links] || true).to_s
|
18
|
-
|
19
|
-
response = connection.call(
|
20
|
-
:get,
|
21
|
-
"/subscriptions/#{stream_name}/#{subscription_name}/#{count}",
|
22
|
-
headers: headers
|
23
|
-
)
|
24
|
-
|
25
|
-
return { events: [] } if response.body.nil? || response.body.empty?
|
26
|
-
|
27
|
-
body = JSON.parse(response.body)
|
28
|
-
|
29
|
-
ack_info = body['links'].find { |link| link['relation'] == 'ackAll' }
|
30
|
-
return { events: [] } unless ack_info
|
31
|
-
|
32
|
-
skip_decryption = options[:skip_decryption] || false
|
33
|
-
body['entries'].map do |entry|
|
34
|
-
yield deserialize_event(entry, skip_decryption: skip_decryption)
|
35
|
-
end
|
36
|
-
|
37
|
-
Ack.new(connection).call(ack_info['uri'])
|
38
|
-
Success()
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def deserialize_event(entry, skip_decryption: false)
|
44
|
-
event = EventStoreClient::Event.new(
|
45
|
-
id: entry['eventId'],
|
46
|
-
title: entry['title'],
|
47
|
-
type: entry['eventType'],
|
48
|
-
data: entry['data'] || '{}',
|
49
|
-
metadata: entry['isMetaData'] ? entry['metaData'] : '{}'
|
50
|
-
)
|
51
|
-
|
52
|
-
config.mapper.deserialize(event, skip_decryption: skip_decryption)
|
53
|
-
rescue EventStoreClient::DeserializedEvent::InvalidDataError
|
54
|
-
event
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Projections
|
7
|
-
class Create < Command
|
8
|
-
def call(name, streams, options: {})
|
9
|
-
data =
|
10
|
-
<<~STRING
|
11
|
-
fromStreams(#{streams})
|
12
|
-
.when({
|
13
|
-
$any: function(s,e) {
|
14
|
-
linkTo("#{name}", e)
|
15
|
-
}
|
16
|
-
})
|
17
|
-
STRING
|
18
|
-
|
19
|
-
|
20
|
-
res = connection.call(
|
21
|
-
:post,
|
22
|
-
"/projections/continuous?name=#{name}&type=js&enabled=yes&emit=true&trackemittedstreams=true", # rubocop:disable Metrics/LineLength
|
23
|
-
body: data,
|
24
|
-
headers: {}
|
25
|
-
)
|
26
|
-
|
27
|
-
(200...300).cover?(res.status) ? Success() : Failure(res)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Projections
|
7
|
-
class Update < Command
|
8
|
-
def call(name, streams, options: {})
|
9
|
-
data =
|
10
|
-
<<~STRING
|
11
|
-
fromStreams(#{streams})
|
12
|
-
.when({
|
13
|
-
$any: function(s,e) {
|
14
|
-
linkTo("#{name}", e)
|
15
|
-
}
|
16
|
-
})
|
17
|
-
STRING
|
18
|
-
res = connection.call(
|
19
|
-
:put,
|
20
|
-
"/projection/#{name}/query?type=js&enabled=yes&emit=true&trackemittedstreams=true", # rubocop:disable Metrics/LineLength
|
21
|
-
body: data,
|
22
|
-
headers: {}
|
23
|
-
)
|
24
|
-
|
25
|
-
(200...300).cover?(res.status) ? Success() : Failure(res)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Streams
|
7
|
-
class Append < Command
|
8
|
-
include Configuration
|
9
|
-
|
10
|
-
def call(stream_name, events, options: {})
|
11
|
-
expected_version = options[:expected_version]
|
12
|
-
serialized_events = events.map { |event| config.mapper.serialize(event) }
|
13
|
-
headers = {
|
14
|
-
'ES-ExpectedVersion' => expected_version&.to_s
|
15
|
-
}.reject { |_key, val| val.nil? || val.empty? }
|
16
|
-
|
17
|
-
data = build_events_data(serialized_events)
|
18
|
-
response =
|
19
|
-
connection.call(:post, "/streams/#{stream_name}", body: data, headers: headers)
|
20
|
-
validate_response(response, expected_version)
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def build_events_data(events)
|
26
|
-
[events].flatten.map do |event|
|
27
|
-
{
|
28
|
-
eventId: event.id,
|
29
|
-
eventType: event.type,
|
30
|
-
data: event.data,
|
31
|
-
metadata: event.metadata
|
32
|
-
}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def validate_response(resp, expected_version)
|
37
|
-
wrong_version = resp.status == 400 && resp.reason_phrase == 'Wrong expected EventNumber'
|
38
|
-
return Success() unless wrong_version
|
39
|
-
|
40
|
-
Failure(
|
41
|
-
"current version: #{resp.headers.fetch('es-currentversion')} | "\
|
42
|
-
"expected: #{expected_version}"
|
43
|
-
)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Streams
|
7
|
-
class Delete < Command
|
8
|
-
def call(stream_name, options: {}) # rubocop:disable Lint/UnusedMethodArgument
|
9
|
-
connection.call(:delete, "/streams/#{stream_name}", body: {})
|
10
|
-
Success()
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Streams
|
7
|
-
class LinkTo < Command
|
8
|
-
def call(stream_name, events, options: {})
|
9
|
-
expected_version = options[:expected_version]
|
10
|
-
data = build_linking_data(events)
|
11
|
-
headers = {
|
12
|
-
'ES-ExpectedVersion' => expected_version&.to_s
|
13
|
-
}.reject { |_key, val| val.nil? || val.empty? }
|
14
|
-
|
15
|
-
response = connection.call(
|
16
|
-
:post,
|
17
|
-
"/streams/#{stream_name}",
|
18
|
-
body: data,
|
19
|
-
headers: headers
|
20
|
-
)
|
21
|
-
validate_response(response, expected_version)
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def validate_response(resp, expected_version)
|
27
|
-
wrong_version = resp.status == 400 && resp.reason_phrase == 'Wrong expected EventNumber'
|
28
|
-
return Success() unless wrong_version
|
29
|
-
|
30
|
-
Failure(
|
31
|
-
"current version: #{resp.headers.fetch('es-currentversion')} | "\
|
32
|
-
"expected: #{expected_version}"
|
33
|
-
)
|
34
|
-
end
|
35
|
-
|
36
|
-
def build_linking_data(events)
|
37
|
-
[events].flatten.map do |event|
|
38
|
-
{
|
39
|
-
eventId: event.id,
|
40
|
-
eventType: '$>',
|
41
|
-
data: event.title
|
42
|
-
}
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventStoreClient
|
4
|
-
module HTTP
|
5
|
-
module Commands
|
6
|
-
module Streams
|
7
|
-
class Read < Command
|
8
|
-
include Configuration
|
9
|
-
|
10
|
-
def call(stream_name, options: {})
|
11
|
-
count = options[:count] || config.per_page
|
12
|
-
start = options[:start].to_i
|
13
|
-
direction = options[:direction] || 'forward'
|
14
|
-
headers = { 'Accept' => 'application/vnd.eventstore.atom+json' }
|
15
|
-
headers['ES-ResolveLinkTos'] = true if options.key?(:resolve_links)
|
16
|
-
|
17
|
-
response =
|
18
|
-
connection.call(
|
19
|
-
:get,
|
20
|
-
"/streams/#{stream_name}/#{start}/#{direction}/#{count}",
|
21
|
-
headers: headers
|
22
|
-
)
|
23
|
-
|
24
|
-
return Failure(:stream_not_found) unless response.success? || response.status == 404
|
25
|
-
return Failure(:connection_failed) if response.body.nil? || response.body.empty?
|
26
|
-
skip_decryption = options[:skip_decryption] || false
|
27
|
-
entries = JSON.parse(response.body)['entries'].map do |entry|
|
28
|
-
deserialize_event(entry, skip_decryption: skip_decryption)
|
29
|
-
end.reverse
|
30
|
-
Success(entries)
|
31
|
-
rescue Faraday::ConnectionFailed
|
32
|
-
Failure(:connection_failed)
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def deserialize_event(entry, skip_decryption: false)
|
38
|
-
event = EventStoreClient::Event.new(
|
39
|
-
id: entry['eventId'],
|
40
|
-
title: entry['title'],
|
41
|
-
type: entry['eventType'],
|
42
|
-
data: entry['data'] || '{}',
|
43
|
-
metadata: entry['isMetaData'] ? entry['metaData'] : '{}'
|
44
|
-
)
|
45
|
-
|
46
|
-
config.mapper.deserialize(event, skip_decryption: skip_decryption)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|