private Task <WriteResult> SetStreamMetadataInternal(StreamMetadata metadata,
                                                      AppendReq appendReq,
                                                      UserCredentials userCredentials,
                                                      CancellationToken cancellationToken) =>
 AppendToStreamInternal(appendReq, new[] {
     new EventData(Uuid.NewUuid(), SystemEventTypes.StreamMetadata,
                   JsonSerializer.SerializeToUtf8Bytes(metadata, StreamMetadataJsonSerializerOptions)),
 }, userCredentials, cancellationToken);
예제 #2
0
        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);
        }
        public async Task <IActionResult> Append([FromBody] AppendReq req)
        {
            if (string.IsNullOrWhiteSpace(req.Key) || req.Value == null)
            {
                NotFound("Method Dictionary/Append params");
            }

            Logger.LogInformation($"Append dictionary key: {req.Key}, value: ${req.Value}");


            await _service.Append(req.Key, req.Value).ConfigureAwait(false);

            return(Ok());
        }
        private async Task <WriteResult> AppendToStreamInternal(
            AppendReq header,
            IEnumerable <EventData> eventData,
            UserCredentials userCredentials,
            CancellationToken cancellationToken)
        {
            using var call = _client.Append(RequestMetadata.Create(userCredentials),
                                            cancellationToken: cancellationToken);

            await call.RequestStream.WriteAsync(header);

            foreach (var e in eventData)
            {
                await call.RequestStream.WriteAsync(new AppendReq {
                    ProposedMessage = new AppendReq.Types.ProposedMessage {
                        Id = new Streams.UUID {
                            String = e.EventId.ToString("n")
                        },
                        Data           = ByteString.CopyFrom(e.Data),
                        CustomMetadata = ByteString.CopyFrom(e.Metadata),
                        Metadata       =
                        {
                            { Constants.Metadata.Type,   e.Type                                 },
                            { Constants.Metadata.IsJson, e.IsJson.ToString().ToLowerInvariant() }
                        }
                    }
                });
            }

            await call.RequestStream.CompleteAsync();

            var response = await call.ResponseAsync;

            return(new WriteResult(
                       response.CurrentRevisionOptionsCase == AppendResp.CurrentRevisionOptionsOneofCase.NoStream
                                        ? AnyStreamRevision.NoStream.ToInt64()
                                        : new StreamRevision(response.CurrentRevision).ToInt64(),
                       response.PositionOptionsCase == AppendResp.PositionOptionsOneofCase.Position
                                        ? new Position(response.Position.CommitPosition, response.Position.PreparePosition)
                                        : default));
        }
        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);
        }
    }
}