コード例 #1
0
    public async Task <IEnumerable <object> > LoadEvents(string stream, int?version = null)
    {
        EventStoreClient.ReadStreamResult response;

        if (version == null || version == -1)
        {
            response = _client
                       .ReadStreamAsync(Direction.Forwards, _tenantPrefix + stream, StreamPosition.Start);
        }
        else
        {
            response = _client
                       .ReadStreamAsync(Direction.Forwards, _tenantPrefix + stream, Convert.ToUInt64(version));
        }


        if (await response.ReadState == ReadState.StreamNotFound)
        {
            return(new List <object>());
        }

        return(await response
               .Select(e => e.Deserialize())
               .ToListAsync());
    }
コード例 #2
0
        public async Task <StreamReadResults> ReadFrom(string streamId, Func <IAmAStoredEvent, bool> predicate = null, Direction direction = Direction.Backwards, CancellationToken cancellationToken = default)
        {
            var readResult = client.ReadStreamAsync(direction,
                                                    streamId,
                                                    direction == Direction.Backwards ? StreamPosition.End : StreamPosition.Start,
                                                    resolveLinkTos: true,
                                                    configureOperationOptions: options => options.TimeoutAfter = TimeSpan.FromSeconds(30),
                                                    cancellationToken: cancellationToken);

            bool streamExists = false;

            try
            {
                var readState = await readResult.ReadState;
                streamExists = readState == ReadState.Ok;
            }
#pragma warning disable 168
            catch (StreamDeletedException ex)
            // This happens when the stream is hard-deleted. We don't want to throw in that case
#pragma warning restore 168
            {
                streamExists = false;
            }

            if (!streamExists)
            {
                return(new StreamReadResults(emptyReadResult, false, StreamPosition.FromInt64(-1)));
            }

            predicate ??= _ => true;

            var lastIndex = (await client.ReadStreamAsync(Direction.Backwards, streamId,
                                                          revision: StreamPosition.End,
                                                          maxCount: 1,
                                                          resolveLinkTos: false).FirstAsync(cancellationToken)).OriginalEventNumber;

            IAsyncEnumerable <StoredEvent> storedEvents;
            if (direction == Direction.Backwards)
            {
                storedEvents = readResult
                               // Trust me, resharper is wrong in this one. Event can be null
                               // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                               .Where(e => e.Event != null)
                               .Select((e, _) => e.Event.ToStoredEvent(stateFactory))
                               .TakeWhile(e => e.DeserializedEvent is not EntitySoftDeleted)
                               .Where(e => predicate(e));
            }
            else
            {
                storedEvents = readResult
                               // Trust me, resharper is wrong in this one. Event can be null
                               // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                               .Where(e => e.Event != null)
                               .Select((e, c) => e.Event.ToStoredEvent(stateFactory))
                               .Where(e => predicate(e));
            }


            return(new StreamReadResults(storedEvents, true, lastIndex));
        }
コード例 #3
0
        public async Task <bool> CheckIfAggrerootExists <T>(Guid id) where T : AggregateRootWithEvents
        {
            String streamId = GetStreamId <T>(id);

            var readResult = _client.ReadStreamAsync(Direction.Forwards, streamId, StreamPosition.Start, 1);

            return((await readResult.ReadState) == ReadState.Ok);
        }
コード例 #4
0
        public async Task <bool> Exists <TAggregate>(Guid id) where TAggregate : Aggregate
        {
            var stream    = GetStreamName <TAggregate>(id);
            var read      = _client.ReadStreamAsync(Direction.Forwards, stream, StreamPosition.Start, 1);
            var readState = await read.ReadState;

            return(readState != ReadState.StreamNotFound);
        }
コード例 #5
0
ファイル: GetEventStore.cs プロジェクト: jrlost/squidex
        private IAsyncEnumerable <StoredEvent> QueryAsync(string streamName, StreamPosition start, long count,
                                                          CancellationToken ct = default)
        {
            var result = client.ReadStreamAsync(
                Direction.Forwards,
                streamName,
                start,
                count,
                resolveLinkTos: true,
                cancellationToken: ct);

            return(result.Select(x => Formatter.Read(x, StreamPrefix, serializer)));
        }
コード例 #6
0
ファイル: EsdbEventStore.cs プロジェクト: Eventuous/eventuous
    public async Task <bool> StreamExists(StreamName stream, CancellationToken cancellationToken)
    {
        var read = _client.ReadStreamAsync(
            Direction.Backwards,
            stream,
            StreamPosition.End,
            1,
            cancellationToken: cancellationToken
            );

        var state = await read.ReadState.NoContext();

        return(state == ReadState.Ok);
    }
        /// <summary>
        /// Runs the health check, returning the status of the component being checked.
        /// </summary>
        /// <param name="context">A context object associated with the current execution.</param>
        /// <param name="cancellationToken">A <see cref="T:System.Threading.CancellationToken" /> that can be used to cancel the health check.</param>
        /// <returns>
        /// A <see cref="T:System.Threading.Tasks.Task`1" /> that completes when the health check has finished, yielding the status of the component being checked.
        /// </returns>
        /// <exception cref="Exception">$all stream not found</exception>
        public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context,
                                                               CancellationToken cancellationToken = default)
        {
            try
            {
                EventStoreClient client = new EventStoreClient(this.EventStoreClientSettings);
                EventStoreClient.ReadStreamResult readResult = client.ReadStreamAsync(Direction.Forwards,
                                                                                      "$all",
                                                                                      StreamPosition.Start,
                                                                                      userCredentials: this.UserCredentials,
                                                                                      resolveLinkTos: true,
                                                                                      cancellationToken: cancellationToken);
                ReadState readState = await readResult.ReadState;
                if (readState == ReadState.StreamNotFound)
                {
                    throw new Exception("$all stream not found");
                }

                return(HealthCheckResult.Healthy());
            }
            catch (Exception ex)
            {
                return(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
            }
        }
コード例 #8
0
        public static IApplicationBuilder UseStreamMessages(this IApplicationBuilder builder,
                                                            EventStoreClient eventStore)
        {
            return(builder.MapMethods(
                       "/streams/{streamId}/{streamRevision:int}",
                       (HttpMethod.Get, GetStreamMessage)));

            async ValueTask <Response> GetStreamMessage(HttpContext context)
            {
                var streamId       = context.Request.GetStreamId();
                var streamRevision = context.Request.GetStreamRevision();

                try {
                    var @event = await eventStore.ReadStreamAsync(Direction.Forwards, streamId !,
                                                                  StreamPosition.FromStreamRevision(streamRevision !.Value), 1,
                                                                  resolveLinkTos : false, userCredentials : context.GetUserCredentials(),
                                                                  cancellationToken : context.RequestAborted)
                                 .Where(e => e.OriginalEvent.EventNumber == streamRevision)
                                 .SingleOrDefaultAsync(context.RequestAborted);

                    return(new HALResponse(StreamMessageRepresentation.Instance, new StreamMessageResource(
                                               streamId !, streamRevision !.Value, @event))
                    {
                        StatusCode = @event.OriginalEvent == null ? HttpStatusCode.NotFound : HttpStatusCode.OK
                    });
                } catch (StreamNotFoundException) {
                    return(new HALResponse(StreamMessageRepresentation.Instance, new StreamMessageResource(
                                               streamId !, streamRevision !.Value))
                    {
                        StatusCode = HttpStatusCode.NotFound
                    });
コード例 #9
0
    public static async Task <T?> AggregateStream <T>(
        this EventStoreClient eventStore,
        Guid id,
        CancellationToken cancellationToken,
        ulong?fromVersion = null
        ) where T : class, IProjection
    {
        var readResult = eventStore.ReadStreamAsync(
            Direction.Forwards,
            StreamNameMapper.ToStreamId <T>(id),
            fromVersion ?? StreamPosition.Start,
            cancellationToken: cancellationToken
            );

        // TODO: consider adding extension method for the aggregation and deserialisation
        var aggregate = (T)Activator.CreateInstance(typeof(T), true) !;

        await foreach (var @event in readResult)
        {
            var eventData = @event.Deserialize();

            aggregate.When(eventData !);
        }

        return(aggregate);
    }
コード例 #10
0
        public async Task <KeyValuePair <int, GrainState <T> > > ReadStateFromStorage()
        {
            _stream = $"{typeof(T).Name}:{ModelVersion()}:{this.GrainId()}";

            var stream = _eventStore.ReadStreamAsync(
                Direction.Forwards,
                _stream,
                StreamPosition.Start);

            var state   = new GrainState <T>();
            var version = 0;

            if (await stream.ReadState != ReadState.StreamNotFound)
            {
                await foreach (var resolvedEvent in stream)
                {
                    var json = Encoding.UTF8.GetString(resolvedEvent.Event.Data.Span);

                    try
                    {
                        var eventObj = _eventSerializer.Deserialize(typeof(T), resolvedEvent.Event.EventType, json);

                        state = state.Apply(eventObj);
                        version++;
                    }
                    catch (Exception ex)
                    {
                        _logger.LogCritical(5004, ex, ex.Message);
                        return(new KeyValuePair <int, GrainState <T> >(-1, new GrainState <T>()));
                    }
                }
            }

            return(new KeyValuePair <int, GrainState <T> >(version, state));
        }
コード例 #11
0
        public async Task <TEventSourcedAggregate?> GetAsync(TId id, CancellationToken token = default)
        {
            var streamName       = GetStreamName(id);
            var readStreamResult = _client.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.Start, cancellationToken: token);

            if (await readStreamResult.ReadState is ReadState.StreamNotFound)
            {
                return(null);
            }

            TEventSourcedAggregate?aggregate = null;

            await foreach (var resolvedEvent in readStreamResult)
            {
                var(@event, metadata) = EventStoreSerializer.Deserialize(resolvedEvent.Event);

                if (RequestContext.RequestId is not null && RequestContext.RequestId == metadata.CausationId)
                {
                    throw new DuplicateRequestException(RequestContext.RequestId);
                }

                aggregate ??= (TEventSourcedAggregate)Activator.CreateInstance(typeof(TEventSourcedAggregate), true) !;
                aggregate.ApplyEvent(@event);
            }

            return(aggregate);
        }
コード例 #12
0
        private static async Task TestReadFromtombstoned(EventStoreClient client)
        {
            var idForTombstoneTest = Guid.NewGuid().ToString();
            await client.AppendToStreamAsync(idForTombstoneTest, StreamRevision.FromInt64(-1),
                                             new[] { new EventData(Uuid.NewUuid(), "TestType", new byte[] { 0x00 }) });

            await client.TombstoneAsync(idForTombstoneTest, StreamState.Any);

            var testResultNonExistent =
                client.ReadStreamAsync(Direction.Backwards, Guid.NewGuid().ToString(), StreamPosition.End);
            var testResult = client.ReadStreamAsync(Direction.Backwards, idForTombstoneTest, StreamPosition.End,
                                                    configureOperationOptions: o => { o.ThrowOnAppendFailure = false; });
            var testState = await testResultNonExistent.ReadState;

            testState = await testResult.ReadState;
        }
コード例 #13
0
ファイル: EventStoreDb.cs プロジェクト: ArienHartgers/DDD
        async Task <IEventStore.StreamEvents> IEventStore.GetStreamEventsAsync(string streamName)
        {
            var stream = _client.ReadStreamAsync(
                Direction.Forwards,
                streamName,
                StreamPosition.Start);

            var loadedEvents = new List <LoadedEvent>();

            await foreach (var eventObject in stream)
            {
                if (!_externalEventTypes.TryGetValue(eventObject.Event.EventType, out var eventType))
                {
                    throw new InvalidOperationException("Unknown event type found");
                }

                var externalEvent = (IDomainEvent?)JsonSerializer.Deserialize(eventObject.Event.Data.Span, eventType);
                if (externalEvent == null)
                {
                    throw new InvalidOperationException($"Event cannot be null {eventObject.Event.EventType}");
                }

                if (!_eventsConverter.TryConvert(externalEvent, out var internalEvent))
                {
                    throw new InvalidOperationException($"Cannot convert event {eventObject.Event.EventType}");
                }

                loadedEvents.Add(new LoadedEvent(
                                     eventObject.Event.Created,
                                     internalEvent));
            }

            return(new IEventStore.StreamEvents(loadedEvents.Count, loadedEvents));
        }
コード例 #14
0
        public async Task <bool> Exists(string steamId)
        {
            var result = _eventStoreClient.ReadStreamAsync(Direction.Forwards, steamId, StreamPosition.Start, 1);
            var state  = await result.ReadState;

            return(state == ReadState.Ok);
        }
コード例 #15
0
        public async ValueTask <Optional <TAggregateRoot> > GetById(string identifier,
                                                                    CancellationToken cancellationToken = default)
        {
            var streamName = identifier;

            if (_unitOfWork.TryGet(streamName, out var a) && a is TAggregateRoot aggregate)
            {
                return(new Optional <TAggregateRoot>(aggregate));
            }

            try {
                await using var events = _eventStore.ReadStreamAsync(Direction.Forwards,
                                                                     streamName, StreamPosition.Start,
                                                                     configureOperationOptions: options => options.TimeoutAfter = TimeSpan.FromMinutes(20),
                                                                     cancellationToken: cancellationToken);

                aggregate = _factory();

                var version = await aggregate.LoadFromHistory(events.Select(e =>
                                                                            JsonSerializer.Deserialize(e.OriginalEvent.Data.Span,
                                                                                                       _messageTypeMapper.Map(e.OriginalEvent.EventType),
                                                                                                       _serializerOptions)));

                _unitOfWork.Attach(streamName, aggregate, version);

                return(aggregate);
            } catch (StreamNotFoundException) {
                return(Optional <TAggregateRoot> .Empty);
            }
        }
コード例 #16
0
        static async Task Main(string[] args)
        {
            CancellationTokenSource tokenSource       = new CancellationTokenSource();
            CancellationToken       cancellationToken = tokenSource.Token;

            #region createClient
            var settings = EventStoreClientSettings
                           .Create("{connectionString}");
            var client = new EventStoreClient(settings);
            #endregion createClient

            #region createEvent
            var evt = new TestEvent
            {
                EntityId      = Guid.NewGuid().ToString("N"),
                ImportantData = "I wrote my first event!"
            };

            var eventData = new EventData(
                Uuid.NewUuid(),
                "TestEvent",
                JsonSerializer.SerializeToUtf8Bytes(evt)
                );
            #endregion createEvent

            #region appendEvents
            await client.AppendToStreamAsync(
                "some-stream",
                StreamState.Any,
                new[] { eventData },
                cancellationToken : cancellationToken
                );

            #endregion appendEvents

            #region overriding-user-credentials
            await client.AppendToStreamAsync(
                "some-stream",
                StreamState.Any,
                new[] { eventData },
                userCredentials : new UserCredentials("admin", "changeit"),
                cancellationToken : cancellationToken
                );

            #endregion overriding-user-credentials

            #region readStream
            var result = client.ReadStreamAsync(
                Direction.Forwards,
                "some-stream",
                StreamPosition.Start,
                cancellationToken: cancellationToken);

            var events = await result.ToListAsync(cancellationToken);

            #endregion readStream
        }
コード例 #17
0
        public static async Task <StreamSize> GetStreamSize(
            this EventStoreClient client, string stream
            )
        {
            var read = client.ReadStreamAsync(Direction.Backwards, stream, StreamPosition.End, 1);
            var last = await read.ToArrayAsync().ConfigureAwait(false);

            return(new StreamSize(last[0].OriginalEventNumber.ToInt64()));
        }
コード例 #18
0
        private async Task <IReadOnlyCollection <ResolvedEvent> > GetSnapshotStream(string stream, string entityId, string model)
        {
            var streamName = model != null ? $"{stream}-{entityId}-{model}-snapshot" : $"{stream}-{entityId}-snapshot";

            var state = _client.ReadStreamAsync(
                Direction.Backwards,
                streamName,
                StreamPosition.End,
                1);

            var readState = await state.ReadState;

            if (readState == ReadState.StreamNotFound)
            {
                return(new List <ResolvedEvent>());
            }

            return(await state.ToListAsync());
        }
コード例 #19
0
 private void ReadStreamOverridingUserCredentials(EventStoreClient client, CancellationToken cancellationToken)
 {
     #region overriding-user-credentials
     var result = client.ReadStreamAsync(
         Direction.Forwards,
         "some-stream",
         StreamPosition.Start,
         userCredentials: new UserCredentials("admin", "changeit"),
         cancellationToken: cancellationToken);
     #endregion overriding-user-credentials
 }
コード例 #20
0
        private static async Task AppendWithConcurrencyCheck(EventStoreClient client)
        {
            #region append-with-concurrency-check
            var clientOneRead = client.ReadStreamAsync(
                Direction.Forwards,
                "concurrency-stream",
                StreamPosition.Start,
                configureOperationOptions: options => options.ThrowOnAppendFailure = false);
            var clientOneRevision = (await clientOneRead.LastAsync()).Event.EventNumber.ToUInt64();

            var clientTwoRead     = client.ReadStreamAsync(Direction.Forwards, "concurrency-stream", StreamPosition.Start);
            var clientTwoRevision = (await clientTwoRead.LastAsync()).Event.EventNumber.ToUInt64();

            var clientOneData = new EventData(
                Uuid.NewUuid(),
                "some-event",
                Encoding.UTF8.GetBytes("{\"id\": \"1\" \"value\": \"clientOne\"}")
                );

            await client.AppendToStreamAsync(
                "no-stream-stream",
                clientOneRevision,
                new List <EventData> {
                clientOneData
            });

            var clientTwoData = new EventData(
                Uuid.NewUuid(),
                "some-event",
                Encoding.UTF8.GetBytes("{\"id\": \"2\" \"value\": \"clientTwo\"}")
                );

            await client.AppendToStreamAsync(
                "no-stream-stream",
                clientTwoRevision,
                new List <EventData> {
                clientTwoData
            });

            #endregion append-with-concurrency-check
        }
コード例 #21
0
    async ValueTask <List <object> > GetEvents(string streamName, CancellationToken ct)
    {
        await using var readResult = _eventStore.ReadStreamAsync(
                        Direction.Forwards,
                        streamName,
                        StreamPosition.Start,
                        cancellationToken: ct
                        );

        return(await readResult
               .Select(@event => @event.Deserialize())
               .ToListAsync(ct));
    }
コード例 #22
0
        private static async Task ReadFromStreamBackwards(EventStoreClient client)
        {
            #region reading-backwards
            var events = client.ReadStreamAsync(
                Direction.Backwards,
                "some-stream",
                StreamPosition.End);

            await foreach (var e in events)
            {
                Console.WriteLine(Encoding.UTF8.GetString(e.Event.Data.ToArray()));
            }
            #endregion reading-backwards
        }
コード例 #23
0
        private static async Task ReadFromStream(EventStoreClient client)
        {
            #region read-from-stream
            var events = client.ReadStreamAsync(
                Direction.Forwards,
                "some-stream",
                StreamPosition.Start);
            #endregion read-from-stream

            #region iterate-stream
            await foreach (var @event in events)
            {
                Console.WriteLine(Encoding.UTF8.GetString(@event.Event.Data.ToArray()));
            }
            #endregion iterate-stream
        }
コード例 #24
0
    public async Task <IEnumerable <object> > LoadEvents(string streamName)
    {
        var response = _client
                       .ReadStreamAsync(Direction.Forwards, ToStreamName(streamName), StreamPosition.Start);

        var readState = await response.ReadState;

        if (readState == ReadState.StreamNotFound)
        {
            return(new List <object>());
        }

        return(await response
               .Select(e => e.Deserialize() !)
               .ToListAsync());
    }
コード例 #25
0
    public async ValueTask <ulong?> Load(string subscriptionId, CancellationToken ct)
    {
        var streamName = GetCheckpointStreamName(subscriptionId);

        var result = eventStoreClient.ReadStreamAsync(Direction.Backwards, streamName, StreamPosition.End, 1,
                                                      cancellationToken: ct);

        if (await result.ReadState == ReadState.StreamNotFound)
        {
            return(null);
        }

        ResolvedEvent? @event = await result.FirstOrDefaultAsync(ct);

        return(@event?.Deserialize <CheckpointStored>().Position);
    }
コード例 #26
0
        public async Task <TAggregate> GetByIdAsync <TAggregate>(object id) where TAggregate : IAggregate, new()
        {
            var aggregate = new TAggregate();

            var streamName = $"{aggregate.Identifier}-{id}";

            var events = _eventStoreConnection.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.Start);

            await foreach (var evt in events)
            {
                var payload = DeserializeEvent(evt);
                aggregate.ApplyEvent(payload);
            }

            return(aggregate);
        }
コード例 #27
0
        public async Task <IEnumerable <Event> > ReadStream(string streamName)
        {
            var result = _client.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.Start);

            var readState = await result.ReadState;

            if (readState == ReadState.StreamNotFound)
            {
                return(new List <Event>());
            }

            var events = (await result.ToListAsync())
                         .Select(EventSerializer.Deserialize)
                         .ToList();

            return(events);
        }
コード例 #28
0
        public EventStoreAggregate(EventStoreClient eventStore, string stream = InterfaceConst.ESPrime)
        {
            _eventStore = eventStore;
            _stream     = stream;

            var result = _eventStore.ReadStreamAsync(Direction.Forwards, _stream, StreamPosition.Start);

            if (result.ReadState.Result == ReadState.StreamNotFound)
            {
                return;
            }

            foreach (var vnt in result.ToEnumerable())
            {
                Events.Add(vnt.To <T>());
            }
        }
コード例 #29
0
ファイル: EventStoreAggregateStore.cs プロジェクト: FWTL/Auth
        private async Task <TAggregate> GetByIdOrDefaultAsync <TAggregate>(string aggregateId, int version)
            where TAggregate : class, IAggregateRoot, new()
        {
            if (version <= 0)
            {
                throw new InvalidOperationException("Cannot get version <= 0");
            }

            var        streamName = $"{typeof(TAggregate).Name}:{aggregateId}";
            TAggregate aggregate  = new TAggregate
            {
                Version = -1
            };

            RedisValue value = await Policies.RedisValueFallbackPolicy.ExecuteAsync(() => _cache.StringGetAsync(streamName));

            if (value.HasValue)
            {
                aggregate = JsonSerializer.Deserialize <TAggregate>(value);
            }

            long sliceStart = aggregate.Version + 1;

            EventStoreClient.ReadStreamResult stream = _eventStoreClient.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.FromInt64(sliceStart));

            if (await stream.ReadState == ReadState.StreamNotFound)
            {
                return(null);
            }

            await foreach (var @event in stream)
            {
                object eventObject      = DeserializeEvent(@event.Event.Metadata, @event.Event.Data);
                Type   applyType        = typeof(IApply <>).MakeGenericType(eventObject.GetType());
                var    isAssignableFrom = applyType.IsAssignableFrom(aggregate.GetType());
                if (isAssignableFrom)
                {
                    ((dynamic)aggregate).Apply((dynamic)eventObject);
                }
                aggregate.Version++;
            }

            aggregate.Context = _context;
            return(aggregate);
        }
コード例 #30
0
    public static async Task <ulong?> GetPositionToSubscribe(this EventStoreClient client, string stream)
    {
        ulong?startPosition = null;

        try {
            var last = await client.ReadStreamAsync(
                Direction.Backwards,
                stream,
                StreamPosition.End,
                1
                ).ToArrayAsync();

            startPosition = last[0].OriginalEventNumber;
        }
        catch (StreamNotFound) { }

        return(startPosition);
    }