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,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grpc'
|
4
|
-
require 'event_store_client/adapters/grpc/connection'
|
5
|
-
|
6
3
|
module EventStoreClient
|
7
4
|
module GRPC
|
8
5
|
class CommandRegistrar
|
@@ -19,13 +16,16 @@ module EventStoreClient
|
|
19
16
|
end
|
20
17
|
|
21
18
|
def self.request(command_klass)
|
22
|
-
@commands
|
19
|
+
@commands.dig(command_klass, :request)
|
23
20
|
end
|
24
21
|
|
22
|
+
# @param command_klass [Class]
|
23
|
+
# Examples:
|
24
|
+
# - EventStoreClient::GRPC::Commands::Streams::Append
|
25
|
+
# - EventStoreClient::GRPC::Commands::Streams::Read
|
26
|
+
# @return [Object] GRPC service class
|
25
27
|
def self.service(command_klass)
|
26
|
-
|
27
|
-
@commands[command_klass][:service]
|
28
|
-
)
|
28
|
+
@commands.dig(command_klass, :service)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -1,43 +1,81 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dry-monads'
|
4
|
-
require 'event_store_client/adapters/grpc/command_registrar'
|
5
|
-
|
6
3
|
module EventStoreClient
|
7
4
|
module GRPC
|
8
5
|
module Commands
|
9
6
|
class Command
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
class << self
|
8
|
+
def use_request(request_klass)
|
9
|
+
CommandRegistrar.register_request(self, request: request_klass)
|
10
|
+
end
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def use_service(service_klass)
|
13
|
+
CommandRegistrar.register_service(self, service: service_klass)
|
14
|
+
end
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
end
|
17
|
+
include Configuration
|
18
|
+
include Dry::Monads[:try, :result]
|
22
19
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
20
|
+
attr_reader :connection
|
21
|
+
private :connection
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
# @param conn_options [Hash]
|
24
|
+
# @option conn_options [String] :host
|
25
|
+
# @option conn_options [Integer] :port
|
26
|
+
# @option conn_options [String] :username
|
27
|
+
# @option conn_options [String] :password
|
28
|
+
def initialize(**conn_options)
|
29
|
+
@connection = EventStoreClient::GRPC::Connection.new(**conn_options)
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
32
|
+
# Override it in your implementation of command.
|
33
|
+
def call
|
34
|
+
raise NotImplementedError
|
35
35
|
end
|
36
36
|
|
37
|
+
# @return [Hash]
|
37
38
|
def metadata
|
39
|
+
return {} unless connection.class.secure?
|
40
|
+
|
38
41
|
credentials =
|
39
|
-
Base64.encode64("#{
|
40
|
-
{ 'authorization' => "Basic #{credentials
|
42
|
+
Base64.encode64("#{connection.username}:#{connection.password}").delete("\n")
|
43
|
+
{ 'authorization' => "Basic #{credentials}" }
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return GRPC params class to be used in the request.
|
47
|
+
# E.g.EventStore::Client::Streams::ReadReq
|
48
|
+
def request
|
49
|
+
CommandRegistrar.request(self.class)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return GRPC request stub class. E.g. EventStore::Client::Streams::Streams::Stub
|
53
|
+
def service
|
54
|
+
connection.call(CommandRegistrar.service(self.class))
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Hash] connection options' hash
|
58
|
+
def connection_options
|
59
|
+
@connection.options_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def retry_request(skip_retry: false)
|
65
|
+
return yield if skip_retry
|
66
|
+
|
67
|
+
retries = 0
|
68
|
+
begin
|
69
|
+
yield
|
70
|
+
rescue ::GRPC::Unavailable => e
|
71
|
+
sleep config.eventstore_url.grpc_retry_interval / 1000.0
|
72
|
+
retries += 1
|
73
|
+
if retries <= config.eventstore_url.grpc_retry_attempts
|
74
|
+
config.logger&.debug("Request failed. Reason: #{e.class}. Retying.")
|
75
|
+
retry
|
76
|
+
end
|
77
|
+
raise
|
78
|
+
end
|
41
79
|
end
|
42
80
|
end
|
43
81
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'event_store_client/adapters/grpc/generated/shared_pb'
|
4
|
+
require 'event_store_client/adapters/grpc/generated/gossip_pb'
|
5
|
+
require 'event_store_client/adapters/grpc/generated/gossip_services_pb'
|
6
|
+
|
7
|
+
module EventStoreClient
|
8
|
+
module GRPC
|
9
|
+
module Commands
|
10
|
+
module Gossip
|
11
|
+
class ClusterInfo < Command
|
12
|
+
use_request EventStore::Client::Empty
|
13
|
+
use_service EventStore::Client::Gossip::Gossip::Stub
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
# @see {EventStoreClient::GRPC::Client#cluster_info}
|
17
|
+
def call
|
18
|
+
Success(retry_request { service.read(request.new, metadata: metadata) })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grpc'
|
4
3
|
require 'event_store_client/adapters/grpc/generated/streams_pb'
|
5
4
|
require 'event_store_client/adapters/grpc/generated/streams_services_pb'
|
6
5
|
|
7
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
8
|
-
|
9
6
|
module EventStoreClient
|
10
7
|
module GRPC
|
11
8
|
module Commands
|
@@ -17,91 +14,69 @@ module EventStoreClient
|
|
17
14
|
ALLOWED_EVENT_METADATA = %w[type content-type created_at].freeze
|
18
15
|
|
19
16
|
# @api private
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
res = append(stream, event, expected_version)
|
31
|
-
break if res.failure?
|
17
|
+
# @see {EventStoreClient::GRPC::Client#append_to_stream}
|
18
|
+
def call(stream_name, event, options:, &blk)
|
19
|
+
payload =
|
20
|
+
[
|
21
|
+
request.new(options: options(stream_name, options)),
|
22
|
+
request.new(proposed_message: proposed_message(event))
|
23
|
+
]
|
24
|
+
yield(*payload) if blk
|
25
|
+
response = retry_request(skip_retry: config.eventstore_url.throw_on_append_failure) do
|
26
|
+
service.append(payload, metadata: metadata)
|
32
27
|
end
|
33
|
-
|
34
|
-
|
28
|
+
validate_response(response)
|
29
|
+
rescue ::GRPC::Unavailable => e
|
30
|
+
Failure(e)
|
35
31
|
end
|
36
32
|
|
37
33
|
private
|
38
34
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
35
|
+
# @param event [EventStoreClient::DeserializedEvent]
|
36
|
+
# @return [EventStore::Client::Streams::AppendReq::ProposedMessage]
|
37
|
+
def proposed_message(event)
|
38
|
+
serialized_event = config.mapper.serialize(event)
|
39
|
+
event_metadata = JSON.parse(serialized_event.metadata)
|
40
|
+
custom_metadata = custom_metadata(serialized_event.type, event_metadata)
|
41
|
+
opts =
|
42
|
+
{
|
43
|
+
id: {
|
44
|
+
string: serialized_event.id
|
45
|
+
},
|
46
|
+
data: serialized_event.data.b,
|
47
|
+
custom_metadata: custom_metadata.to_json,
|
48
|
+
metadata: event_metadata.slice(*ALLOWED_EVENT_METADATA)
|
49
|
+
}
|
50
|
+
EventStore::Client::Streams::AppendReq::ProposedMessage.new(opts)
|
54
51
|
end
|
55
52
|
|
53
|
+
# @param event_type [String]
|
54
|
+
# @param event_metadata [Hash]
|
55
|
+
# @return [Hash]
|
56
56
|
def custom_metadata(event_type, event_metadata)
|
57
57
|
{
|
58
58
|
type: event_type,
|
59
|
-
created_at: Time.
|
59
|
+
created_at: Time.now.utc,
|
60
60
|
encryption: event_metadata['encryption'],
|
61
61
|
'content-type': event_metadata['content-type'],
|
62
62
|
transaction: event_metadata['transaction']
|
63
63
|
}.compact
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
proposed_message: message
|
73
|
-
)
|
74
|
-
]
|
75
|
-
end
|
76
|
-
|
77
|
-
def options(stream, expected_version)
|
78
|
-
{
|
79
|
-
stream_identifier: {
|
80
|
-
streamName: stream
|
81
|
-
},
|
82
|
-
revision: expected_version,
|
83
|
-
any: (expected_version ? nil : {})
|
84
|
-
}.compact
|
85
|
-
end
|
86
|
-
|
87
|
-
def message(data:, event_metadata:, custom_metadata:)
|
88
|
-
{
|
89
|
-
id: {
|
90
|
-
string: SecureRandom.uuid
|
91
|
-
},
|
92
|
-
data: data,
|
93
|
-
custom_metadata: JSON.generate(custom_metadata),
|
94
|
-
metadata: event_metadata
|
95
|
-
}
|
66
|
+
# @param stream_name [String]
|
67
|
+
# @param options [Hash]
|
68
|
+
# @return [EventStore::Client::Streams::AppendReq::Options]
|
69
|
+
def options(stream_name, options)
|
70
|
+
opts = Options::Streams::WriteOptions.new(stream_name, options).request_options
|
71
|
+
EventStore::Client::Streams::AppendReq::Options.new(opts)
|
96
72
|
end
|
97
73
|
|
74
|
+
# @param resp [EventStore::Client::Streams::AppendResp]
|
75
|
+
# @return [Dry::Monads::Success, Dry::Monads::Failure]
|
98
76
|
def validate_response(resp)
|
99
|
-
return Success() if resp.success
|
77
|
+
return Success(resp) if resp.success
|
100
78
|
|
101
|
-
Failure(
|
102
|
-
"current version: #{resp.wrong_expected_version.current_revision} | "\
|
103
|
-
"expected: #{resp.wrong_expected_version.expected_revision}"
|
104
|
-
)
|
79
|
+
Failure(resp.wrong_expected_version)
|
105
80
|
end
|
106
81
|
end
|
107
82
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Naming/PredicateName
|
4
|
+
|
5
|
+
module EventStoreClient
|
6
|
+
module GRPC
|
7
|
+
module Commands
|
8
|
+
module Streams
|
9
|
+
class AppendMultiple < Command
|
10
|
+
# @api private
|
11
|
+
# @see {EventStoreClient::GRPC::Client#append_to_stream}
|
12
|
+
def call(stream_name, events, options:, &blk)
|
13
|
+
result = []
|
14
|
+
events.each.with_index do |event, index|
|
15
|
+
response = Commands::Streams::Append.new(**connection_options).call(
|
16
|
+
stream_name, event, options: options
|
17
|
+
) do |req_opts, proposed_msg_opts|
|
18
|
+
req_opts.options.revision += index if has_revision_option?(req_opts.options)
|
19
|
+
|
20
|
+
yield(req_opts, proposed_msg_opts) if blk
|
21
|
+
end
|
22
|
+
result.push(response)
|
23
|
+
break if response.failure?
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Even if #revision is not set explicitly - its value defaults to 0. Thus, you can't
|
31
|
+
# detect whether #revision is set just by calling #revision method. Instead - check if
|
32
|
+
# option does not set #no_stream, #any or #stream_exists options - they are self-exclusive
|
33
|
+
# options and only one of them can be active at a time
|
34
|
+
# @param options [EventStore::Client::Streams::AppendReq::Options]
|
35
|
+
# @return [Boolean]
|
36
|
+
def has_revision_option?(options)
|
37
|
+
[options.no_stream, options.any, options.stream_exists].all?(&:nil?)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# rubocop:enable Naming/PredicateName
|
@@ -1,10 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'grpc'
|
4
|
-
require 'event_store_client/adapters/grpc/generated/
|
5
|
-
require 'event_store_client/adapters/grpc/generated/projections_services_pb.rb'
|
6
|
-
|
7
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
3
|
+
require 'event_store_client/adapters/grpc/generated/streams_pb'
|
4
|
+
require 'event_store_client/adapters/grpc/generated/streams_services_pb'
|
8
5
|
|
9
6
|
module EventStoreClient
|
10
7
|
module GRPC
|
@@ -14,19 +11,26 @@ module EventStoreClient
|
|
14
11
|
use_request EventStore::Client::Streams::DeleteReq
|
15
12
|
use_service EventStore::Client::Streams::Streams::Stub
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
service.delete(request.new(options: opts), metadata: metadata)
|
27
|
-
Success()
|
14
|
+
# @api private
|
15
|
+
# @see {EventStoreClient::GRPC::Client#delete_stream}
|
16
|
+
def call(stream_name, options:, &blk)
|
17
|
+
options = normalize_options(stream_name, options)
|
18
|
+
yield options if blk
|
19
|
+
Success(
|
20
|
+
retry_request { service.delete(request.new(options: options), metadata: metadata) }
|
21
|
+
)
|
28
22
|
rescue ::GRPC::FailedPrecondition
|
29
|
-
Failure(:
|
23
|
+
Failure(:stream_not_found)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# @param stream_name [String]
|
29
|
+
# @param options [Hash]
|
30
|
+
# @return [EventStore::Client::Streams::TombstoneReq::Options]
|
31
|
+
def normalize_options(stream_name, options)
|
32
|
+
opts = Options::Streams::WriteOptions.new(stream_name, options).request_options
|
33
|
+
EventStore::Client::Streams::DeleteReq::Options.new(opts)
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'event_store_client/adapters/grpc/generated/streams_pb'
|
4
|
+
require 'event_store_client/adapters/grpc/generated/streams_services_pb'
|
5
|
+
|
6
|
+
module EventStoreClient
|
7
|
+
module GRPC
|
8
|
+
module Commands
|
9
|
+
module Streams
|
10
|
+
class HardDelete < Command
|
11
|
+
use_request EventStore::Client::Streams::TombstoneReq
|
12
|
+
use_service EventStore::Client::Streams::Streams::Stub
|
13
|
+
|
14
|
+
# @api private
|
15
|
+
# @see {EventStoreClient::GRPC::Client#hard_delete_stream}
|
16
|
+
def call(stream_name, options:, &blk)
|
17
|
+
options = normalize_options(stream_name, options)
|
18
|
+
yield options if blk
|
19
|
+
Success(
|
20
|
+
retry_request { service.delete(request.new(options: options), metadata: metadata) }
|
21
|
+
)
|
22
|
+
rescue ::GRPC::FailedPrecondition
|
23
|
+
Failure(:stream_not_found)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# @param stream_name [String]
|
29
|
+
# @param options [Hash]
|
30
|
+
# @return [EventStore::Client::Streams::TombstoneReq::Options]
|
31
|
+
def normalize_options(stream_name, options)
|
32
|
+
opts = Options::Streams::WriteOptions.new(stream_name, options).request_options
|
33
|
+
EventStore::Client::Streams::TombstoneReq::Options.new(opts)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,62 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'securerandom'
|
4
|
-
require 'grpc'
|
5
|
-
require 'event_store_client/adapters/grpc/generated/streams_pb.rb'
|
6
|
-
require 'event_store_client/adapters/grpc/generated/streams_services_pb.rb'
|
7
|
-
|
8
|
-
require 'event_store_client/adapters/grpc/commands/command'
|
9
|
-
|
10
3
|
module EventStoreClient
|
11
4
|
module GRPC
|
12
5
|
module Commands
|
13
6
|
module Streams
|
14
7
|
class LinkTo < Command
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
custom_metadata = JSON.generate(
|
23
|
-
"type": '$>',
|
24
|
-
"created_at": Time.now,
|
25
|
-
"encryption": event.metadata['encryption'] || ''
|
26
|
-
)
|
27
|
-
|
28
|
-
event_metadata = event.metadata.tap do |h|
|
29
|
-
h['type'] = '$>'
|
30
|
-
h['content-type'] = 'application/json'
|
31
|
-
h.delete('encryption')
|
32
|
-
end
|
33
|
-
|
34
|
-
event_id = event.id
|
35
|
-
event_id = SecureRandom.uuid if event.id.nil? || event.id.empty?
|
36
|
-
|
37
|
-
payload = [
|
38
|
-
request.new(
|
39
|
-
options: {
|
40
|
-
stream_identifier: {
|
41
|
-
streamName: stream_name
|
42
|
-
},
|
43
|
-
any: {}
|
44
|
-
}
|
45
|
-
),
|
46
|
-
request.new(
|
47
|
-
proposed_message: {
|
48
|
-
id: {
|
49
|
-
string: event_id
|
50
|
-
},
|
51
|
-
data: event.title,
|
52
|
-
custom_metadata: custom_metadata,
|
53
|
-
metadata: event_metadata
|
54
|
-
}
|
55
|
-
)
|
56
|
-
]
|
57
|
-
service.append(payload, metadata: metadata)
|
58
|
-
end
|
59
|
-
Success()
|
8
|
+
# @see {EventStoreClient::GRPC::Client#hard_delete_stream}
|
9
|
+
def call(stream_name, event, options:, &blk)
|
10
|
+
append_cmd = Append.new(**connection_options)
|
11
|
+
link_event = EventStoreClient::DeserializedEvent.new(
|
12
|
+
id: event.id, type: '$>', data: event.title
|
13
|
+
)
|
14
|
+
append_cmd.call(stream_name, link_event, options: options, &blk)
|
60
15
|
end
|
61
16
|
end
|
62
17
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Naming/PredicateName
|
4
|
+
|
5
|
+
module EventStoreClient
|
6
|
+
module GRPC
|
7
|
+
module Commands
|
8
|
+
module Streams
|
9
|
+
class LinkToMultiple < Command
|
10
|
+
# @api private
|
11
|
+
# @see {EventStoreClient::GRPC::Client#link_to}
|
12
|
+
def call(stream_name, events, options:, &blk)
|
13
|
+
result = []
|
14
|
+
link_cmd = Commands::Streams::LinkTo.new(**connection_options)
|
15
|
+
events.each.with_index do |event, index|
|
16
|
+
response =
|
17
|
+
link_cmd.call(stream_name, event, options: options) do |req_opts, proposed_msg_opts|
|
18
|
+
req_opts.options.revision += index if has_revision_option?(req_opts.options)
|
19
|
+
|
20
|
+
yield(req_opts, proposed_msg_opts) if blk
|
21
|
+
end
|
22
|
+
result.push(response)
|
23
|
+
break if response.failure?
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Even if #revision is not set explicitly - its value defaults to 0. Thus, you can't
|
31
|
+
# detect whether #revision is set just by calling #revision method. Instead - check if
|
32
|
+
# option does not set #no_stream, #any or #stream_exists options - they are self-exclusive
|
33
|
+
# options and only one of them can be active at a time
|
34
|
+
# @param options [EventStore::Client::Streams::AppendReq::Options]
|
35
|
+
# @return [Boolean]
|
36
|
+
def has_revision_option?(options)
|
37
|
+
[options.no_stream, options.any, options.stream_exists].all?(&:nil?)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# rubocop:enable Naming/PredicateName
|