event_store_client 1.4.9 → 2.0.0
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 +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
|