/// <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));
            }
        }
Example #2
0
        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);
        }
Example #3
0
        /// <summary>
        /// Gets the events backwards asynchronous.
        /// </summary>
        /// <param name="streamName">Name of the stream.</param>
        /// <param name="maxNumberOfEventsToRetrieve">The maximum number of events to retrieve.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        public async Task <IList <ResolvedEvent> > GetEventsBackwardAsync(String streamName,
                                                                          Int32 maxNumberOfEventsToRetrieve,
                                                                          CancellationToken cancellationToken)
        {
            List <ResolvedEvent> resolvedEvents = new();

            EventStoreClient.ReadStreamResult response = this.EventStoreClient.ReadStreamAsync(Direction.Backwards,
                                                                                               streamName,
                                                                                               StreamPosition.End,
                                                                                               maxNumberOfEventsToRetrieve,
                                                                                               resolveLinkTos: true,
                                                                                               cancellationToken: cancellationToken);

            if (await response.ReadState == ReadState.StreamNotFound)
            {
                return(resolvedEvents);
            }

            List <ResolvedEvent> events = await response.ToListAsync(cancellationToken);

            resolvedEvents.AddRange(events);

            return(resolvedEvents);
        }