Create() public static method

public static Create ( EventStore.Client.EventStoreClientSettings settings, EventStore.Client.EventStoreClientOperationOptions operationOptions, UserCredentials? userCredentials, CancellationToken cancellationToken ) : CallOptions
settings EventStore.Client.EventStoreClientSettings
operationOptions EventStore.Client.EventStoreClientOperationOptions
userCredentials UserCredentials?
cancellationToken CancellationToken
return CallOptions
        public async Task <UserDetails> GetUserAsync(string loginName, UserCredentials?userCredentials = null,
                                                     CancellationToken cancellationToken = default)
        {
            if (loginName == null)
            {
                throw new ArgumentNullException(nameof(loginName));
            }

            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }

            using var call = _client.Details(new DetailsReq {
                Options = new DetailsReq.Types.Options {
                    LoginName = loginName
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            await call.ResponseStream.MoveNext().ConfigureAwait(false);

            var userDetails = call.ResponseStream.Current.UserDetails;

            return(ConvertUserDetails(userDetails));
        }
        public async Task <DatabaseScavengeResult> StartScavengeAsync(
            int threadCount    = 1,
            int startFromChunk = 0,
            UserCredentials?userCredentials     = null,
            CancellationToken cancellationToken = default)
        {
            if (threadCount <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(threadCount));
            }

            if (startFromChunk < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(startFromChunk));
            }

            var result = await _client.StartScavengeAsync(new StartScavengeReq {
                Options = new StartScavengeReq.Types.Options {
                    ThreadCount    = threadCount,
                    StartFromChunk = startFromChunk
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            return(result.ScavengeResult switch {
                ScavengeResp.Types.ScavengeResult.Started => DatabaseScavengeResult.Started(result.ScavengeId),
                ScavengeResp.Types.ScavengeResult.Stopped => DatabaseScavengeResult.Stopped(result.ScavengeId),
                ScavengeResp.Types.ScavengeResult.InProgress => DatabaseScavengeResult.InProgress(result.ScavengeId),
                _ => throw new InvalidOperationException()
            });
        public async Task ResetPasswordAsync(string loginName, string newPassword,
                                             UserCredentials?userCredentials = null, CancellationToken cancellationToken = default)
        {
            if (loginName == null)
            {
                throw new ArgumentNullException(nameof(loginName));
            }
            if (newPassword == null)
            {
                throw new ArgumentNullException(nameof(newPassword));
            }
            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }
            if (newPassword == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(newPassword));
            }

            await _client.ResetPasswordAsync(new ResetPasswordReq {
                Options = new ResetPasswordReq.Types.Options {
                    NewPassword = newPassword,
                    LoginName   = loginName
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
示例#4
0
 public async Task ResignNodeAsync(
     UserCredentials?userCredentials     = null,
     CancellationToken cancellationToken = default)
 {
     await _client.ResignNodeAsync(EmptyResult,
                                   EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
示例#5
0
 public async Task SetNodePriorityAsync(int nodePriority,
                                        UserCredentials?userCredentials     = null,
                                        CancellationToken cancellationToken = default)
 {
     await _client.SetNodePriorityAsync(new SetNodePriorityReq { Priority = nodePriority },
                                        EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
 public async Task RestartPersistentSubscriptions(UserCredentials?userCredentials     = null,
                                                  CancellationToken cancellationToken = default)
 {
     await new Operations.Operations.OperationsClient(
         await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).RestartPersistentSubscriptionsAsync(
         EmptyResult,
         EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
 public async Task EnableAsync(string name, UserCredentials?userCredentials = null,
                               CancellationToken cancellationToken          = default)
 {
     using var call = _client.EnableAsync(new EnableReq {
         Options = new EnableReq.Types.Options {
             Name = name
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
示例#8
0
 public async Task DeleteAsync(string streamName, string groupName, UserCredentials?userCredentials = null,
                               CancellationToken cancellationToken = default)
 {
     await _client.DeleteAsync(new DeleteReq {
         Options = new DeleteReq.Types.Options {
             StreamIdentifier = streamName,
             GroupName        = groupName
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
 public async Task CreateOneTimeAsync(string query, UserCredentials?userCredentials = null,
                                      CancellationToken cancellationToken           = default)
 {
     using var call = _client.CreateAsync(new CreateReq {
         Options = new CreateReq.Types.Options {
             OneTime = new Empty(),
             Query   = query
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
		private async Task<DeleteResult> DeleteInternal(DeleteReq request,
			EventStoreClientOperationOptions operationOptions,
			UserCredentials? userCredentials,
			CancellationToken cancellationToken) {
			_log.LogDebug("Deleting stream {streamName}.", request.Options.StreamIdentifier);
			var result = await new Streams.Streams.StreamsClient(
				await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).DeleteAsync(request,
				EventStoreCallOptions.Create(Settings, operationOptions, userCredentials, cancellationToken));

			return new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition));
		}
示例#11
0
 public async Task DeleteAsync(string streamName, string groupName, UserCredentials?userCredentials = null,
                               CancellationToken cancellationToken = default)
 {
     await new PersistentSubscriptions.PersistentSubscriptions.PersistentSubscriptionsClient(
         await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).DeleteAsync(new DeleteReq {
         Options = new DeleteReq.Types.Options {
             StreamIdentifier = streamName,
             GroupName        = groupName
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
        private async Task <DeleteResult> TombstoneInternal(TombstoneReq request,
                                                            EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials,
                                                            CancellationToken cancellationToken)
        {
            _log.LogDebug("Tombstoning stream {streamName}.", request.Options.StreamIdentifier);

            var result = await _client.TombstoneAsync(request,
                                                      EventStoreCallOptions.Create(Settings, operationOptions, userCredentials, cancellationToken));

            return(new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition)));
        }
 public async Task SetNodePriorityAsync(int nodePriority,
                                        UserCredentials?userCredentials     = null,
                                        CancellationToken cancellationToken = default)
 {
     await new Operations.Operations.OperationsClient(
         await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).SetNodePriorityAsync(
         new SetNodePriorityReq {
         Priority = nodePriority
     },
         EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
 }
 private async Task DisableInternalAsync(string name, bool writeCheckpoint, UserCredentials?userCredentials,
                                         CancellationToken cancellationToken)
 {
     using var call = _client.DisableAsync(new DisableReq {
         Options = new DisableReq.Types.Options {
             Name            = name,
             WriteCheckpoint = writeCheckpoint
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
示例#15
0
 public async Task ResetAsync(string name, UserCredentials?userCredentials = null,
                              CancellationToken cancellationToken          = default)
 {
     using var call = new Projections.Projections.ProjectionsClient(
               await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).ResetAsync(new ResetReq {
         Options = new ResetReq.Types.Options {
             Name            = name,
             WriteCheckpoint = true
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
        public Task <PersistentSubscription> SubscribeAsync(string streamName, string groupName,
                                                            Func <PersistentSubscription, ResolvedEvent, int?, CancellationToken, Task> eventAppeared,
                                                            Action <PersistentSubscription, SubscriptionDroppedReason, Exception?>?subscriptionDropped = null,
                                                            UserCredentials?userCredentials     = null, int bufferSize = 10, bool autoAck = true,
                                                            CancellationToken cancellationToken = default)
        {
            if (streamName == null)
            {
                throw new ArgumentNullException(nameof(streamName));
            }

            if (groupName == null)
            {
                throw new ArgumentNullException(nameof(groupName));
            }

            if (eventAppeared == null)
            {
                throw new ArgumentNullException(nameof(eventAppeared));
            }

            if (streamName == string.Empty)
            {
                throw new ArgumentException($"{nameof(streamName)} may not be empty.", nameof(streamName));
            }

            if (groupName == string.Empty)
            {
                throw new ArgumentException($"{nameof(groupName)} may not be empty.", nameof(groupName));
            }

            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bufferSize));
            }

            var operationOptions = Settings.OperationOptions.Clone();

            operationOptions.TimeoutAfter = new TimeSpan?();

            var call = _client.Read(EventStoreCallOptions.Create(Settings, operationOptions, userCredentials,
                                                                 cancellationToken));

            return(PersistentSubscription.Confirm(call, new ReadReq.Types.Options {
                BufferSize = bufferSize,
                GroupName = groupName,
                StreamIdentifier = streamName,
                UuidOption = new ReadReq.Types.Options.Types.UUIDOption {
                    Structured = new Empty()
                }
            }, autoAck, eventAppeared,
                                                  subscriptionDropped ?? delegate { }, cancellationToken));
        }
 public async Task CreateTransientAsync(string name, string query, UserCredentials?userCredentials = null,
                                        CancellationToken cancellationToken = default)
 {
     using var call = new Projections.Projections.ProjectionsClient(
               await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).CreateAsync(new CreateReq {
         Options = new CreateReq.Types.Options {
             Transient = new CreateReq.Types.Options.Types.Transient {
                 Name = name
             },
             Query = query
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
 public async Task CreateContinuousAsync(string name, string query, bool trackEmittedStreams = false,
                                         UserCredentials?userCredentials = null, CancellationToken cancellationToken = default)
 {
     using var call = _client.CreateAsync(new CreateReq {
         Options = new CreateReq.Types.Options {
             Continuous = new CreateReq.Types.Options.Types.Continuous {
                 Name = name,
                 TrackEmittedStreams = trackEmittedStreams
             },
             Query = query
         }
     }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
     await call.ResponseAsync.ConfigureAwait(false);
 }
        public async Task DisableUserAsync(string loginName, UserCredentials?userCredentials = null,
                                           CancellationToken cancellationToken = default)
        {
            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }

            await _client.DisableAsync(new DisableReq {
                Options = new DisableReq.Types.Options {
                    LoginName = loginName
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
        public async IAsyncEnumerable <UserDetails> ListAllAsync(UserCredentials?userCredentials = null,
                                                                 [EnumeratorCancellation] CancellationToken cancellationToken = default)
        {
            using var call = _client.Details(new DetailsReq(),
                                             EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            await foreach (var userDetail in call.ResponseStream
                           .ReadAllAsync(cancellationToken)
                           .Select(x => ConvertUserDetails(x.UserDetails))
                           .WithCancellation(cancellationToken)
                           .ConfigureAwait(false))
            {
                yield return(userDetail);
            }
        }
        private async ValueTask <Value> GetResultInternalAsync(string name, string?partition,
                                                               UserCredentials?userCredentials,
                                                               CancellationToken cancellationToken)
        {
            using var call = _client.ResultAsync(new ResultReq {
                Options = new ResultReq.Types.Options {
                    Name      = name,
                    Partition = partition ?? string.Empty
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            var response = await call.ResponseAsync.ConfigureAwait(false);

            return(response.Result);
        }
示例#22
0
        private async ValueTask <Value> GetStateInternalAsync(string name, string?partition,
                                                              UserCredentials?userCredentials,
                                                              CancellationToken cancellationToken)
        {
            using var call = new Projections.Projections.ProjectionsClient(
                      await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).StateAsync(new StateReq {
                Options = new StateReq.Types.Options {
                    Name      = name,
                    Partition = partition ?? string.Empty
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            var response = await call.ResponseAsync.ConfigureAwait(false);

            return(response.State);
        }
        private async IAsyncEnumerable <ProjectionDetails> ListInternalAsync(StatisticsReq.Types.Options options,
                                                                             UserCredentials?userCredentials,
                                                                             [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            using var call = _client.Statistics(new StatisticsReq {
                Options = options
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            await foreach (var projectionDetails in call.ResponseStream
                           .ReadAllAsync(cancellationToken)
                           .Select(ConvertToProjectionDetails)
                           .WithCancellation(cancellationToken)
                           .ConfigureAwait(false))
            {
                yield return(projectionDetails);
            }
        }
示例#24
0
        public async Task CreateUserAsync(string loginName, string fullName, string[] groups, string password,
                                          UserCredentials?userCredentials     = null,
                                          CancellationToken cancellationToken = default)
        {
            if (loginName == null)
            {
                throw new ArgumentNullException(nameof(loginName));
            }
            if (fullName == null)
            {
                throw new ArgumentNullException(nameof(fullName));
            }
            if (groups == null)
            {
                throw new ArgumentNullException(nameof(groups));
            }
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }
            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }
            if (fullName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(fullName));
            }
            if (password == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(password));
            }

            await new Users.Users.UsersClient(
                await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).CreateAsync(new CreateReq {
                Options = new CreateReq.Types.Options {
                    LoginName = loginName,
                    FullName  = fullName,
                    Password  = password,
                    Groups    = { groups }
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
        public async Task UpdateAsync(string streamName, string groupName, PersistentSubscriptionSettings settings,
                                      UserCredentials?userCredentials     = null,
                                      CancellationToken cancellationToken = default)
        {
            if (streamName == null)
            {
                throw new ArgumentNullException(nameof(streamName));
            }

            if (groupName == null)
            {
                throw new ArgumentNullException(nameof(groupName));
            }

            if (settings == null)
            {
                throw new ArgumentNullException(nameof(settings));
            }

            await new PersistentSubscriptions.PersistentSubscriptions.PersistentSubscriptionsClient(
                await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).UpdateAsync(new UpdateReq {
                Options = new UpdateReq.Types.Options {
                    StreamIdentifier = streamName,
                    GroupName        = groupName,
                    Settings         = new UpdateReq.Types.Settings {
                        Revision              = settings.StartFrom,
                        CheckpointAfterMs     = (int)settings.CheckPointAfter.TotalMilliseconds,
                        ExtraStatistics       = settings.ExtraStatistics,
                        MessageTimeoutMs      = (int)settings.MessageTimeout.TotalMilliseconds,
                        ResolveLinks          = settings.ResolveLinkTos,
                        HistoryBufferSize     = settings.HistoryBufferSize,
                        LiveBufferSize        = settings.LiveBufferSize,
                        MaxCheckpointCount    = settings.MaxCheckPointCount,
                        MaxRetryCount         = settings.MaxRetryCount,
                        MaxSubscriberCount    = settings.MaxSubscriberCount,
                        MinCheckpointCount    = settings.MinCheckPointCount,
                        NamedConsumerStrategy = NamedConsumerStrategyToUpdateProto[settings.NamedConsumerStrategy],
                        ReadBatchSize         = settings.ReadBatchSize
                    }
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
示例#26
0
        public async Task EnableUserAsync(string loginName, UserCredentials?userCredentials = null,
                                          CancellationToken cancellationToken = default)
        {
            if (loginName == null)
            {
                throw new ArgumentNullException(nameof(loginName));
            }

            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }

            await new Users.Users.UsersClient(
                await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).EnableAsync(new EnableReq {
                Options = new EnableReq.Types.Options {
                    LoginName = loginName
                }
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
示例#27
0
        public async Task DeleteAsync(string streamName, string groupName, UserCredentials?userCredentials = null,
                                      CancellationToken cancellationToken = default)
        {
            var deleteOptions = new DeleteReq.Types.Options {
                GroupName = groupName
            };

            if (streamName == SystemStreams.AllStream)
            {
                deleteOptions.All = new Empty();
            }
            else
            {
                deleteOptions.StreamIdentifier = streamName;
            }

            await new PersistentSubscriptions.PersistentSubscriptions.PersistentSubscriptionsClient(
                await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).DeleteAsync(new DeleteReq {
                Options = deleteOptions
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
示例#28
0
        public async Task ChangePasswordAsync(string loginName, string currentPassword, string newPassword,
                                              UserCredentials?userCredentials = null, CancellationToken cancellationToken = default)
        {
            if (loginName == null)
            {
                throw new ArgumentNullException(nameof(loginName));
            }
            if (currentPassword == null)
            {
                throw new ArgumentNullException(nameof(currentPassword));
            }
            if (newPassword == null)
            {
                throw new ArgumentNullException(nameof(newPassword));
            }
            if (loginName == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(loginName));
            }
            if (currentPassword == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(currentPassword));
            }
            if (newPassword == string.Empty)
            {
                throw new ArgumentOutOfRangeException(nameof(newPassword));
            }

            await new Users.Users.UsersClient(
                await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).ChangePasswordAsync(
                new ChangePasswordReq {
                Options = new ChangePasswordReq.Types.Options {
                    CurrentPassword = currentPassword,
                    NewPassword     = newPassword,
                    LoginName       = loginName
                }
            },
                EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));
        }
示例#29
0
        public async Task UpdateAsync(string name, string query, bool?emitEnabled = null,
                                      UserCredentials?userCredentials             = null, CancellationToken cancellationToken = default)
        {
            var options = new UpdateReq.Types.Options {
                Name  = name,
                Query = query
            };

            if (emitEnabled.HasValue)
            {
                options.EmitEnabled = emitEnabled.Value;
            }
            else
            {
                options.NoEmitOptions = new Empty();
            }

            using var call = _client.UpdateAsync(new UpdateReq {
                Options = options
            }, EventStoreCallOptions.Create(Settings, Settings.OperationOptions, userCredentials, cancellationToken));

            await call.ResponseAsync.ConfigureAwait(false);
        }
        private async Task <IWriteResult> AppendToStreamInternal(
            AppendReq header,
            IEnumerable <EventData> eventData,
            EventStoreClientOperationOptions operationOptions,
            UserCredentials?userCredentials,
            CancellationToken cancellationToken)
        {
            using var call = new Streams.Streams.StreamsClient(
                      await SelectCallInvoker(cancellationToken).ConfigureAwait(false)).Append(EventStoreCallOptions.Create(
                                                                                                   Settings, operationOptions, userCredentials, cancellationToken));

            IWriteResult writeResult;

            try {
                await call.RequestStream.WriteAsync(header).ConfigureAwait(false);

                foreach (var e in eventData)
                {
                    _log.LogTrace("Appending event to stream - {streamName}@{eventId} {eventType}.",
                                  header.Options.StreamIdentifier, e.EventId, e.Type);
                    await call.RequestStream.WriteAsync(new AppendReq {
                        ProposedMessage = new AppendReq.Types.ProposedMessage {
                            Id             = e.EventId.ToDto(),
                            Data           = ByteString.CopyFrom(e.Data.Span),
                            CustomMetadata = ByteString.CopyFrom(e.Metadata.Span),
                            Metadata       =
                            {
                                { Constants.Metadata.Type,        e.Type        },
                                { Constants.Metadata.ContentType, e.ContentType }
                            }
                        }
                    }).ConfigureAwait(false);
                }
            } finally {
                await call.RequestStream.CompleteAsync().ConfigureAwait(false);

                var response = await call.ResponseAsync.ConfigureAwait(false);

                if (response.Success != null)
                {
                    writeResult = new SuccessResult(response.Success.CurrentRevisionOptionCase ==
                                                    AppendResp.Types.Success.CurrentRevisionOptionOneofCase.NoStream
                                                        ? StreamRevision.None
                                                        : new StreamRevision(response.Success.CurrentRevision),
                                                    response.Success.PositionOptionCase == AppendResp.Types.Success.PositionOptionOneofCase.Position
                                                        ? new Position(response.Success.Position.CommitPosition,
                                                                       response.Success.Position.PreparePosition)
                                                        : default);
                    _log.LogDebug("Append to stream succeeded - {streamName}@{logPosition}/{nextExpectedVersion}.",
                                  header.Options.StreamIdentifier, writeResult.LogPosition, writeResult.NextExpectedStreamRevision);
                }
                else
                {
                    if (response.WrongExpectedVersion != null)
                    {
                        var actualStreamRevision = response.WrongExpectedVersion.CurrentRevisionOptionCase switch {
                            AppendResp.Types.WrongExpectedVersion.CurrentRevisionOptionOneofCase.CurrentNoStream =>
                            StreamRevision.None,
                            _ => new StreamRevision(response.WrongExpectedVersion.CurrentRevision)
                        };

                        _log.LogDebug(
                            "Append to stream failed with Wrong Expected Version - {streamName}/{expectedRevision}/{currentRevision}",
                            header.Options.StreamIdentifier, new StreamRevision(header.Options.Revision),
                            actualStreamRevision);

                        if (operationOptions.ThrowOnAppendFailure)
                        {
                            if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types
                                .WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedRevision)
                            {
                                throw new WrongExpectedVersionException(header.Options.StreamIdentifier,
                                                                        new StreamRevision(response.WrongExpectedVersion.ExpectedRevision),
                                                                        actualStreamRevision);
                            }

                            var expectedStreamState = response.WrongExpectedVersion.ExpectedRevisionOptionCase switch {
                                AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedAny =>
                                StreamState.Any,
                                AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedNoStream =>
                                StreamState.NoStream,
                                AppendResp.Types.WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedStreamExists =>
                                StreamState.StreamExists,
                                _ => throw new InvalidOperationException()
                            };

                            throw new WrongExpectedVersionException(header.Options.StreamIdentifier,
                                                                    expectedStreamState, actualStreamRevision);
                        }

                        if (response.WrongExpectedVersion.ExpectedRevisionOptionCase == AppendResp.Types
                            .WrongExpectedVersion.ExpectedRevisionOptionOneofCase.ExpectedRevision)
                        {
                            writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier,
                                                                         new StreamRevision(response.WrongExpectedVersion.ExpectedRevision),
                                                                         actualStreamRevision);
                        }
                        else
                        {
                            writeResult = new WrongExpectedVersionResult(header.Options.StreamIdentifier,
                                                                         StreamRevision.None,
                                                                         actualStreamRevision);
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("The operation completed with an unexpected result.");
                    }
                }
            }

            return(writeResult);
        }
    }
}