private StreamSubscription SubscribeToStream(string streamName, StreamRevision start, Func <StreamSubscription, ResolvedEvent, CancellationToken, Task> eventAppeared, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, Action <StreamSubscription, SubscriptionDroppedReason, Exception> subscriptionDropped = default, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { operationOptions.TimeoutAfter = DeadLine.None; var subscription = new StreamSubscription(ReadInternal(new ReadReq { Options = new ReadReq.Types.Options { ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, ResolveLinks = resolveLinkTos, Stream = ReadReq.Types.Options.Types.StreamOptions.FromStreamNameAndRevision(streamName, start), Subscription = new ReadReq.Types.Options.Types.SubscriptionOptions() } }, operationOptions, userCredentials, cancellationToken), eventAppeared, subscriptionDropped); return(subscription); }
private Task <StreamSubscription> SubscribeToStreamAsync(string streamName, StreamRevision start, Func <StreamSubscription, ResolvedEvent, CancellationToken, Task> eventAppeared, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, Action <StreamSubscription, SubscriptionDroppedReason, Exception> subscriptionDropped = default, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { operationOptions.TimeoutAfter = DeadLine.None; return(StreamSubscription.Confirm(ReadInternal(new ReadReq { Options = new ReadReq.Types.Options { ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, ResolveLinks = resolveLinkTos, Stream = start == StreamRevision.End ? new ReadReq.Types.Options.Types.StreamOptions { End = new Empty(), StreamName = streamName } : new ReadReq.Types.Options.Types.StreamOptions { Revision = start, StreamName = streamName }, Subscription = new ReadReq.Types.Options.Types.SubscriptionOptions() } }, operationOptions, userCredentials, cancellationToken), eventAppeared, subscriptionDropped, _log, cancellationToken: cancellationToken)); }
private Task <IWriteResult> SetStreamMetadataAsync(string streamName, StreamState expectedState, StreamMetadata metadata, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null, CancellationToken cancellationToken = default) => SetStreamMetadataInternal(metadata, new AppendReq { Options = new AppendReq.Types.Options { StreamName = SystemStreams.MetastreamOf(streamName) } }.WithAnyStreamRevision(expectedState), operationOptions, userCredentials, cancellationToken);
private Task <WriteResult> SetStreamMetadataAsync(string streamName, StreamRevision expectedRevision, StreamMetadata metadata, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) => SetStreamMetadataInternal(metadata, new AppendReq { Options = new AppendReq.Types.Options { StreamName = SystemStreams.MetastreamOf(streamName), Revision = expectedRevision } }, operationOptions, userCredentials, cancellationToken);
private IAsyncEnumerable <ResolvedEvent> ReadAllAsync( Direction direction, Position position, ulong maxCount, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, IEventFilter filter = null, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) => ReadInternal(new ReadReq {
private async Task <DeleteResult> TombstoneInternal(TombstoneReq request, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials, CancellationToken cancellationToken) { var result = await _client.TombstoneAsync(request, RequestMetadata.Create(userCredentials), deadline : DeadLine.After(operationOptions.TimeoutAfter), cancellationToken); return(new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition))); }
private Task <IWriteResult> SetStreamMetadataInternal(StreamMetadata metadata, AppendReq appendReq, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials, CancellationToken cancellationToken) => AppendToStreamInternal(appendReq, new[] { new EventData(Uuid.NewUuid(), SystemEventTypes.StreamMetadata, JsonSerializer.SerializeToUtf8Bytes(metadata, StreamMetadataJsonSerializerOptions)), }, operationOptions, userCredentials, cancellationToken);
private async Task <DeleteResult> DeleteInternal(DeleteReq request, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials, CancellationToken cancellationToken) { _log.LogDebug("Deleting stream {streamName}.", request.Options.StreamName); var result = await _client.DeleteAsync(request, RequestMetadata.Create(userCredentials ?? Settings.DefaultCredentials), deadline : DeadLine.After(operationOptions.TimeoutAfter), cancellationToken); return(new DeleteResult(new Position(result.Position.CommitPosition, result.Position.PreparePosition))); }
private Task <DeleteResult> SoftDeleteAsync( string streamName, AnyStreamRevision expectedRevision, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) => DeleteInternal(new DeleteReq { Options = new DeleteReq.Types.Options { StreamName = streamName } }.WithAnyStreamRevision(expectedRevision), operationOptions, userCredentials, cancellationToken);
private Task <DeleteResult> TombstoneAsync( string streamName, StreamState expectedState, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null, CancellationToken cancellationToken = default) => TombstoneInternal(new TombstoneReq { Options = new TombstoneReq.Types.Options { StreamIdentifier = streamName } }.WithAnyStreamRevision(expectedState), operationOptions, userCredentials, cancellationToken);
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)); }
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))); }
private async Task <WriteResult> AppendToStreamInternal( AppendReq header, IEnumerable <EventData> eventData, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials, CancellationToken cancellationToken) { using var call = _client.Append(RequestMetadata.Create(userCredentials), deadline: DeadLine.After(operationOptions.TimeoutAfter), cancellationToken: cancellationToken); try { await call.RequestStream.WriteAsync(header).ConfigureAwait(false); foreach (var e in eventData) { _log.LogTrace("Appending event to stream - {streamName}@{eventId} {eventType}.", header.Options.StreamName, 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); } await call.RequestStream.CompleteAsync().ConfigureAwait(false); } catch (InvalidOperationException exc) { _log.LogTrace(exc, "Got InvalidOperationException when appending events to stream - {streamName}. This is perfectly normal if the connection was closed from the server-side.", header.Options.StreamName); } catch (RpcException exc) { _log.LogTrace(exc, "Got RpcException when appending events to stream - {streamName}. This is perfectly normal if the connection was closed from the server-side.", header.Options.StreamName); } var response = await call.ResponseAsync.ConfigureAwait(false); var writeResult = new WriteResult( response.CurrentRevisionOptionCase == AppendResp.CurrentRevisionOptionOneofCase.NoStream ? AnyStreamRevision.NoStream.ToInt64() : new StreamRevision(response.CurrentRevision).ToInt64(), response.PositionOptionCase == AppendResp.PositionOptionOneofCase.Position ? new Position(response.Position.CommitPosition, response.Position.PreparePosition) : default); _log.LogDebug("Append to stream succeeded - {streamName}@{logPosition}/{nextExpectedVersion}.", header.Options.StreamName, writeResult.LogPosition, writeResult.NextExpectedVersion); return(writeResult); }
private Task <WriteResult> AppendToStreamAsync( string streamName, AnyStreamRevision expectedRevision, IEnumerable <EventData> eventData, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) => AppendToStreamInternal(new AppendReq { Options = new AppendReq.Types.Options { StreamName = streamName } }.WithAnyStreamRevision(expectedRevision), eventData, operationOptions, userCredentials, cancellationToken);
private Task <DeleteResult> TombstoneAsync( string streamName, StreamRevision expectedRevision, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null, CancellationToken cancellationToken = default) => TombstoneInternal(new TombstoneReq { Options = new TombstoneReq.Types.Options { StreamName = streamName, Revision = expectedRevision } }, operationOptions, userCredentials, cancellationToken);
public void setting_options_on_clone_should_not_modify_original() { EventStoreClientOperationOptions options = new EventStoreClientOperationOptions { TimeoutAfter = TimeSpan.FromDays(5), }; var clonedOptions = options.Clone(); clonedOptions.TimeoutAfter = TimeSpan.FromSeconds(1); Assert.Equal(options.TimeoutAfter, TimeSpan.FromDays(5)); Assert.Equal(clonedOptions.TimeoutAfter, TimeSpan.FromSeconds(1)); }
private Task <IWriteResult> AppendToStreamAsync( string streamName, StreamState expectedState, IEnumerable <EventData> eventData, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null, CancellationToken cancellationToken = default) { _log.LogDebug("Append to stream - {streamName}@{expectedRevision}.", streamName, expectedState); return(AppendToStreamInternal(new AppendReq { Options = new AppendReq.Types.Options { StreamIdentifier = streamName } }.WithAnyStreamRevision(expectedState), eventData, operationOptions, userCredentials, cancellationToken)); }
private async IAsyncEnumerable <ResolvedEvent> ReadAllAsync( Direction direction, Position position, long maxCount, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, UserCredentials?userCredentials = null, [EnumeratorCancellation] CancellationToken cancellationToken = default) { await foreach (var(confirmation, _, resolvedEvent) in ReadInternal(new ReadReq { Options = new ReadReq.Types.Options { ReadDirection = direction switch { Direction.Backwards => ReadReq.Types.Options.Types.ReadDirection.Backwards, Direction.Forwards => ReadReq.Types.Options.Types.ReadDirection.Forwards, _ => throw new InvalidOperationException() },
private Task <WriteResult> AppendToStreamAsync( string streamName, StreamRevision expectedRevision, IEnumerable <EventData> eventData, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { _log.LogDebug("Append to stream - {streamName}@{expectedRevision}.", streamName, expectedRevision); return(AppendToStreamInternal(new AppendReq { Options = new AppendReq.Types.Options { StreamName = streamName, Revision = expectedRevision } }, eventData, operationOptions, userCredentials, cancellationToken)); }
public static CallOptions Create(EventStoreClientSettings settings, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials, CancellationToken cancellationToken) => new CallOptions( cancellationToken: cancellationToken, deadline: DeadlineAfter(operationOptions.TimeoutAfter), headers: new Metadata(), credentials: CallCredentials.FromInterceptor(async(context, metadata) => { var credentials = settings.DefaultCredentials ?? userCredentials; if (credentials == null) { return; } var authorizationHeader = await settings.OperationOptions .GetAuthenticationHeaderValue(credentials, CancellationToken.None) .ConfigureAwait(false); metadata.Add(Constants.Headers.Authorization, authorizationHeader); }) );
private async Task <WriteResult> AppendToStreamInternal( AppendReq header, IEnumerable <EventData> eventData, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials, CancellationToken cancellationToken) { using var call = _client.Append(RequestMetadata.Create(userCredentials), deadline: DeadLine.After(operationOptions.TimeoutAfter), cancellationToken: cancellationToken); await call.RequestStream.WriteAsync(header).ConfigureAwait(false); foreach (var e in eventData) { await call.RequestStream.WriteAsync(new AppendReq { ProposedMessage = new AppendReq.Types.ProposedMessage { Id = e.EventId.ToStreamsDto(), Data = ByteString.CopyFrom(e.Data), CustomMetadata = ByteString.CopyFrom(e.Metadata), Metadata = { { Constants.Metadata.Type, e.Type }, { Constants.Metadata.IsJson, e.IsJson.ToString().ToLowerInvariant() } } } }).ConfigureAwait(false); } await call.RequestStream.CompleteAsync().ConfigureAwait(false); var response = await call.ResponseAsync.ConfigureAwait(false); return(new WriteResult( response.CurrentRevisionOptionCase == AppendResp.CurrentRevisionOptionOneofCase.NoStream ? AnyStreamRevision.NoStream.ToInt64() : new StreamRevision(response.CurrentRevision).ToInt64(), response.PositionOptionCase == AppendResp.PositionOptionOneofCase.Position ? new Position(response.Position.CommitPosition, response.Position.PreparePosition) : default)); }
private async Task <StreamMetadataResult> GetStreamMetadataAsync(string streamName, EventStoreClientOperationOptions operationOptions, UserCredentials?userCredentials = null, CancellationToken cancellationToken = default) { ResolvedEvent metadata; _log.LogDebug("Read stream metadata for {streamName}."); try { metadata = await ReadStreamAsync(Direction.Backwards, SystemStreams.MetastreamOf(streamName), StreamPosition.End, 1, operationOptions, false, userCredentials, cancellationToken) .FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); } catch (StreamNotFoundException) { _log.LogWarning("Stream metadata for {streamName} not found."); return(StreamMetadataResult.None(streamName)); } return(metadata.Event == null ? StreamMetadataResult.None(streamName) : StreamMetadataResult.Create(streamName, metadata.OriginalEventNumber, JsonSerializer.Deserialize <StreamMetadata>(metadata.Event.Data.Span, StreamMetadataJsonSerializerOptions))); }
private Task <StreamSubscription> SubscribeToAllAsync(Position start, Func <StreamSubscription, ResolvedEvent, CancellationToken, Task> eventAppeared, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, Action <StreamSubscription, SubscriptionDroppedReason, Exception> subscriptionDropped = default, SubscriptionFilterOptions filterOptions = null, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { operationOptions.TimeoutAfter = DeadLine.None; return(StreamSubscription.Confirm(ReadInternal(new ReadReq { Options = new ReadReq.Types.Options { ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, ResolveLinks = resolveLinkTos, All = ReadReq.Types.Options.Types.AllOptions.FromPosition(start), Subscription = new ReadReq.Types.Options.Types.SubscriptionOptions(), Filter = GetFilterOptions(filterOptions) } }, operationOptions, userCredentials, cancellationToken), eventAppeared, subscriptionDropped, _log, filterOptions?.CheckpointReached, cancellationToken)); }
private async Task <StreamMetadataResult> GetStreamMetadataAsync(string streamName, EventStoreClientOperationOptions operationOptions, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { ResolvedEvent metadata = default; try { metadata = await ReadStreamAsync(Direction.Backwards, SystemStreams.MetastreamOf(streamName), StreamRevision.End, 1, operationOptions, resolveLinkTos : false, userCredentials : userCredentials, cancellationToken : cancellationToken).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); } catch (StreamNotFoundException) { return(StreamMetadataResult.None(streamName)); } return(metadata.Event == null ? StreamMetadataResult.None(streamName) : StreamMetadataResult.Create( streamName, metadata.OriginalEventNumber, JsonSerializer.Deserialize <StreamMetadata>(metadata.Event.Data, StreamMetadataJsonSerializerOptions))); }
private StreamSubscription SubscribeToAll( Func <StreamSubscription, ResolvedEvent, CancellationToken, Task> eventAppeared, EventStoreClientOperationOptions operationOptions, bool resolveLinkTos = false, Action <StreamSubscription, SubscriptionDroppedReason, Exception> subscriptionDropped = default, IEventFilter filter = null, UserCredentials userCredentials = default, CancellationToken cancellationToken = default) { operationOptions.TimeoutAfter = DeadLine.None; var subscription = new StreamSubscription(ReadInternal(new ReadReq { Options = new ReadReq.Types.Options { ReadDirection = ReadReq.Types.Options.Types.ReadDirection.Forwards, ResolveLinks = resolveLinkTos, All = ReadReq.Types.Options.Types.AllOptions.FromPosition(Position.Start), Subscription = new ReadReq.Types.Options.Types.SubscriptionOptions(), Filter = GetFilterOptions(filter) } }, operationOptions, userCredentials, cancellationToken), eventAppeared, subscriptionDropped); return(subscription); }
public static CallOptions Create(EventStoreClientSettings settings, EventStoreClientOperationOptions operationOptions, UserCredentials? userCredentials, CancellationToken cancellationToken) => new(
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); } } }