/// <summary>
 /// Converts an <see cref="EventProcessorId" /> into its <see cref="BsonDocument" /> representation
 /// </summary>
 /// <param name="id">The <see cref="EventProcessorId" /></param>
 /// <returns>A <see cref="BsonDocument" /> representation of the <see cref="EventProcessorId" /></returns>
 public static BsonDocument AsBson(this EventProcessorId id)
 {
     return(new BsonDocument(new Dictionary <string, object>
     {
         { Constants.ID, id.Value }
     }));
 }
Beispiel #2
0
        Try <StreamProcessor> TryRegisterFilterStreamProcessor <TFilterDefinition>(
            ScopeId scopeId,
            EventProcessorId eventHandlerId,
            Func <IFilterProcessor <TypeFilterWithEventSourcePartitionDefinition> > getFilterProcessor,
            CancellationToken cancellationToken)
            where TFilterDefinition : IFilterDefinition
        {
            _logger.Debug("Registering stream processor for Filter '{Filter}' on Event Log", eventHandlerId);
            try
            {
                return(_streamProcessors.TryRegister(
                           scopeId,
                           eventHandlerId,
                           new EventLogStreamDefinition(),
                           getFilterProcessor,
                           cancellationToken,
                           out var outputtedFilterStreamProcessor), outputtedFilterStreamProcessor);
            }
            catch (Exception ex)
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    _logger.Warning(
                        ex,
                        "Error occurred while trying to register stream processor for Filter '{Filter}'",
                        eventHandlerId);
                }

                return(ex);
            }
        }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EventProcessor"/> class.
 /// </summary>
 /// <param name="scope">The <see cref="ScopeId" />.</param>
 /// <param name="id">The <see cref="EventProcessorId" />.</param>
 /// <param name="dispatcher"><see cref="ReverseCallDispatcherType"/> dispatcher.</param>
 /// <param name="logger">The <see cref="ILogger" />.</param>
 public EventProcessor(ScopeId scope, EventProcessorId id, ReverseCallDispatcherType dispatcher, ILogger logger)
 {
     Scope       = scope;
     Identifier  = id;
     _dispatcher = dispatcher;
     _logger     = logger;
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="eventProcessorId"></param>
 /// <param name="committedEventVersion"></param>
 /// <param name="partitionKey"></param>
 /// <returns></returns>
 public static Offset From(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion, string partitionKey)
 {
     return(new Offset {
         Id = eventProcessorId.ToString(), Major = committedEventVersion.Major, Minor = committedEventVersion.Minor,
         Revision = committedEventVersion.Revision, PartitionKey = partitionKey
     });
 }
        /// <summary>
        /// Builds a <see cref="FilterDefinition{BsonDocument}" /> corresponding to the <see cref="EventProcessorId" /> supplied
        /// </summary>
        /// <param name="id">A <see cref="EventProcessorId" /></param>
        /// <returns>A <see cref="FilterDefinition{BsonDocument}" /> corresponding to the <see cref="EventProcessorId" /></returns>
        public static FilterDefinition <BsonDocument> ToFilter(this EventProcessorId id)
        {
            var builder = Builders <BsonDocument> .Filter;
            var filter  = builder.Eq(Constants.ID, id.Value);

            return(filter);
        }
 Persistence.Offset GetOffset(EventProcessorId id)
 {
     using (var es = _database.GetContext())
     {
         return(es.Offsets.SingleOrDefault(_ => _.Id == id.ToString()));
     }
 }
Beispiel #7
0
        Try <StreamProcessor> TryRegisterEventProcessorStreamProcessor(
            ScopeId scopeId,
            EventProcessorId eventHandlerId,
            IStreamDefinition streamDefinition,
            Func <IEventProcessor> getEventProcessor,
            CancellationToken cancellationToken)
        {
            _logger.Debug("Registering stream processor for Event Processor '{EventProcessor}' on Stream '{SourceStream}'", eventHandlerId, streamDefinition.StreamId);
            try
            {
                return(_streamProcessors.TryRegister(
                           scopeId,
                           eventHandlerId,
                           streamDefinition,
                           getEventProcessor,
                           cancellationToken,
                           out var outputtedEventProcessorStreamProcessor), outputtedEventProcessorStreamProcessor);
            }
            catch (Exception ex)
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    _logger.Warning(
                        ex,
                        "Error occurred while trying to register stream processor for Event Processor '{EventProcessor}'",
                        eventHandlerId);
                }

                return(ex);
            }
        }
 /// <inheritdoc />
 public void Set(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion)
 {
     _connection.AppendToStreamAsync(
         GetStreamForEventProcessorId(eventProcessorId),
         ExpectedVersion.Any,
         CreateCommittedEventVersionEvent(committedEventVersion)
         ).Wait();
 }
        /// <inheritdoc />
        public void Set(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion)
        {
            var versionBson = committedEventVersion.AsBson();

            versionBson.Add(Constants.ID, eventProcessorId.Value);
            _offsets.ReplaceOne(eventProcessorId.ToFilter(), versionBson, new UpdateOptions {
                IsUpsert = true
            });
        }
        /// <inheritdoc />
        public CommittedEventVersion Get(EventProcessorId eventProcessorId)
        {
            var result = _connection.ReadEventAsync(GetStreamForEventProcessorId(eventProcessorId), StreamPosition.End, true).Result;

            if (result.Event.HasValue)
            {
                return(_serializer.FromJsonBytes <CommittedEventVersion>(result.Event.Value.Event.Data));
            }
            return(CommittedEventVersion.None);
        }
        /// <inheritdoc />
        public CommittedEventVersion Get(EventProcessorId eventProcessorId)
        {
            var version = GetOffset(eventProcessorId);

            if (version == null)
            {
                return(CommittedEventVersion.None);
            }

            return(version.ToCommittedEventVersion());
        }
        /// <inheritdoc />
        public CommittedEventVersion Get(EventProcessorId eventProcessorId)
        {
            var version = _offsets.Find(eventProcessorId.ToFilter()).SingleOrDefault();

            if (version == null)
            {
                return(CommittedEventVersion.None);
            }

            return(version.ToCommittedEventVersion());
        }
Beispiel #13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EventProcessor"/> class.
 /// </summary>
 /// <param name="scope">The <see cref="ScopeId" />.</param>
 /// <param name="id">The <see cref="EventProcessorId" />.</param>
 /// <param name="dispatcher"><see cref="IReverseCallDispatcher{TClientMessage, TServerMessage, TConnectArguments, TConnectResponse, TRequest, TResponse}"/> dispatcher.</param>
 /// <param name="logger">The <see cref="ILogger" />.</param>
 public EventProcessor(
     ScopeId scope,
     EventProcessorId id,
     IReverseCallDispatcher <EventHandlerClientToRuntimeMessage, EventHandlerRuntimeToClientMessage, EventHandlerRegistrationRequest, EventHandlerRegistrationResponse, HandleEventRequest, EventHandlerResponse> dispatcher,
     ILogger logger)
 {
     Scope             = scope;
     Identifier        = id;
     _dispatcher       = dispatcher;
     _logger           = logger;
     _logMessagePrefix = $"Event Processor '{Identifier}'";
 }
 /// <inheritdoc />
 public void Set(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion)
 {
     using (var es = _database.GetContext())
     {
         //TODO: this can be optimized so that the update is the thing we expect most and the insert is the edge case
         var commandText = "INSERT OR REPLACE INTO Offsets (Id, Major, Minor, Revision) VALUES (@Id,@Major,@Minor,@Revision);";
         var id          = new SqliteParameter("@Id", eventProcessorId.Value.ToString());
         var major       = new SqliteParameter("@Major", committedEventVersion.Major);
         var minor       = new SqliteParameter("@Minor", committedEventVersion.Minor);
         var revision    = new SqliteParameter("@Revision", committedEventVersion.Revision);
         es.Database.ExecuteSqlCommand(commandText, id, major, minor, revision);
     }
 }
 /// <summary>
 /// Initializes a new instance of <see cref="ProcessMethodEventProcessor"/>
 /// </summary>
 /// <param name="objectFactory"><see cref="IObjectFactory"/> for going between <see cref="PropertyBag"/> and instances of types</param>
 /// <param name="container"><see cref="IContainer"/> to use for getting instances of <see cref="ICanProcessEvents"/> implementation</param>
 /// <param name="identifier"><see cref="EventProcessorId"/> that uniquely identifies the <see cref="ProcessMethodEventProcessor"/></param>
 /// <param name="eventIdentifier"><see cref="Artifact">Identifier</see> for identifying the <see cref="IEvent"/></param>
 /// <param name="eventType"><see cref="Type"/> type of <see cref="IEvent"/>></param>
 /// <param name="methodInfo"><see cref="MethodInfo"/> for the actual process method</param>
 /// <param name="logger"></param>
 public ProcessMethodEventProcessor(
     IObjectFactory objectFactory,
     IContainer container,
     EventProcessorId identifier,
     Artifact eventIdentifier,
     Type eventType,
     MethodInfo methodInfo,
     ILogger logger)
 {
     Identifier = identifier;
     Event      = eventIdentifier;
     _logger    = logger;
     _logger.Trace($"ProcessMethodEventProcessor for '{eventIdentifier}' exists on type '{methodInfo}'");
     _invoker = GetProcessorMethodInvokerFor(methodInfo, eventType, objectFactory, container, logger);
 }
        async Task SetAsync(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion)
        {
            var offset = Offset.From(eventProcessorId, committedEventVersion, _config.BasePartitionKey);

            try
            {
                var result = await _config.Client.UpsertDocumentAsync(_config.OffsetsUri, offset, new RequestOptions { PartitionKey = new PartitionKey(_config.BasePartitionKey) });

                _logger.Debug(ResponseMetadata.FromOffset("Setting Offset", result)?.ToString());
            }
            catch (DocumentClientException ex)
            {
                throw new EventStorePersistenceError("Error", ex);
            }
        }
Beispiel #17
0
    async Task <bool> RejectIfInvalidFilterId <TClientMessage, TConnectRequest, TResponse>(
        IReverseCallDispatcher <TClientMessage, FilterRuntimeToClientMessage, TConnectRequest, FilterRegistrationResponse, FilterEventRequest, TResponse> dispatcher,
        EventProcessorId filterId,
        CancellationToken cancellationToken)
        where TClientMessage : IMessage, new()
        where TConnectRequest : class
        where TResponse : class
    {
        StreamId filterStream = filterId.Value;

        if (filterStream.IsNonWriteable)
        {
            _logger.FilterIsInvalid(filterStream);
            var failure = new Failure(FiltersFailures.CannotRegisterFilterOnNonWriteableStream, $"Filter Id: '{filterId.Value}' is an invalid Stream Id");
            await WriteFailedRegistrationResponse(dispatcher, failure, cancellationToken).ConfigureAwait(false);

            return(true);
        }

        return(false);
    }
Beispiel #18
0
    public void IterationSetup()
    {
        _stopStreamProcessorSource = new CancellationTokenSource();
        var numEventsProcessed = 0;

        _streamProcessorsToRun = Enumerable.Range(0, EventHandlerFilters).Select(_ =>
        {
            var eventHandlerId = new EventProcessorId(Guid.NewGuid());
            return(_streamProcessors.TryCreateAndRegister(
                       ScopeId.Default,
                       eventHandlerId,
                       new EventLogStreamDefinition(),
                       tenant => new TypeFilterWithEventSourcePartition(
                           ScopeId.Default,
                           new TypeFilterWithEventSourcePartitionDefinition(StreamId.EventLog, eventHandlerId.Value, _eventTypes, Partitioned),
                           GetEventWriterForTenant(tenant),
                           _loggerFactor.CreateLogger <TypeFilterWithEventSourcePartition>()),
                       Runtime.CreateExecutionContextFor("e3921d20-da26-422e-bf13-e959a5f505ef"),
                       _stopStreamProcessorSource.Token).Result);
        }).ToArray();

        IWriteEventsToStreams GetEventWriterForTenant(TenantId tenant)
        {
            var writer        = _getEventsToStreamsWriter(tenant);
            var wrappedWriter = new Mock <IWriteEventsToStreams>();

            wrappedWriter
            .Setup(_ => _.Write(It.IsAny <CommittedEvent>(), It.IsAny <ScopeId>(), It.IsAny <StreamId>(), Moq.It.IsAny <PartitionId>(), Moq.It.IsAny <CancellationToken>()))
            .Returns <CommittedEvent, ScopeId, StreamId, PartitionId, CancellationToken>(async(@event, scope, stream, partition, cancellation) =>
            {
                Interlocked.Add(ref numEventsProcessed, 1);
                await writer.Write(@event, scope, stream, partition, cancellation).ConfigureAwait(false);
                if (numEventsProcessed == NumberEventsToProcess)
                {
                    _stopStreamProcessorSource.Cancel();
                }
            });
            return(wrappedWriter.Object);
        }
    }
Beispiel #19
0
        /// <inheritdoc />
        public bool TryRegister(
            ScopeId scopeId,
            EventProcessorId eventProcessorId,
            IStreamDefinition streamDefinition,
            Func <IEventProcessor> getEventProcessor,
            CancellationToken cancellationToken,
            out StreamProcessor streamProcessor)
        {
            streamProcessor = default;
            var streamProcessorId = new StreamProcessorId(scopeId, eventProcessorId, streamDefinition.StreamId);

            if (_streamProcessors.ContainsKey(streamProcessorId))
            {
                _logger.Warning("Stream Processor with Id: '{streamProcessorId}' already registered", streamProcessorId);
                return(false);
            }

            streamProcessor = new StreamProcessor(
                streamProcessorId,
                _onAllTenants,
                streamDefinition,
                getEventProcessor,
                () => Unregister(streamProcessorId),
                _getScopedStreamProcessorsCreator,
                _executionContextManager,
                _loggerManager.CreateLogger <StreamProcessor>(),
                cancellationToken);
            if (!_streamProcessors.TryAdd(streamProcessorId, streamProcessor))
            {
                _logger.Warning("Stream Processor with Id: '{StreamProcessorId}' already registered", streamProcessorId);
                streamProcessor = default;
                return(false);
            }

            _logger.Trace("Stream Processor with Id: '{StreamProcessorId}' registered", streamProcessorId);
            return(true);
        }
 /// <inheritdoc />
 public CommittedEventVersion Get(EventProcessorId eventProcessorId)
 {
     return(_lastProcessed.TryGetValue(eventProcessorId, out CommittedEventVersion lastProcessedVersion) ? lastProcessedVersion : CommittedEventVersion.None);
 }
    /// <inheritdoc/>
    public override Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, string failureReason, uint retryCount, ExecutionContext executionContext, CancellationToken cancellationToken)
    {
        if ([email protected])
        {
            return(Task.FromResult <IFilterResult>(new SuccessfulFiltering(false, PartitionId.None)));
        }
        var request = new FilterEventRequest
        {
            Event   = @event.ToProtobuf(),
            ScopeId = Scope.ToProtobuf(),
            RetryProcessingState = new RetryProcessingState {
                FailureReason = failureReason, RetryCount = retryCount
            }
        };

        return(Filter(request, executionContext, cancellationToken));
    }
    /// <inheritdoc/>
    public override Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, ExecutionContext executionContext, CancellationToken cancellationToken)
    {
        if ([email protected])
        {
            return(Task.FromResult <IFilterResult>(new SuccessfulFiltering(false, PartitionId.None)));
        }
        var request = new FilterEventRequest
        {
            Event   = @event.ToProtobuf(),
            ScopeId = Scope.ToProtobuf()
        };

        return(Filter(request, executionContext, cancellationToken));
    }
Beispiel #23
0
 /// <inheritdoc/>
 public abstract Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, string failureReason, uint retryCount, CancellationToken cancellationToken);
Beispiel #24
0
 /// <inheritdoc/>
 public abstract Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, CancellationToken cancellationToken);
Beispiel #25
0
 internal static partial void ConnectingEventHandlerWithId(this ILogger logger, EventProcessorId eventHandler);
Beispiel #26
0
        /// <inheritdoc/>
        public override Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, string failureReason, uint retryCount, CancellationToken cancellationToken)
        {
            _logger.Debug(
                "Filter event that occurred @ {Occurred} to public events stream '{TargetStream}' again for the {RetryCount}. time because: {FailureReason}",
                @event.Occurred,
                Definition.TargetStream,
                retryCount,
                failureReason);
            if ([email protected])
            {
                return(Task.FromResult <IFilterResult>(new SuccessfulFiltering(false, Guid.Empty)));
            }
            var request = new FilterEventRequest
            {
                Event   = @event.ToProtobuf(),
                ScopeId = Scope.ToProtobuf(),
                RetryProcessingState = new RetryProcessingState {
                    FailureReason = failureReason, RetryCount = retryCount
                }
            };

            return(Filter(request, cancellationToken));
        }
Beispiel #27
0
        /// <inheritdoc/>
        public override Task <IFilterResult> Filter(CommittedEvent @event, PartitionId partitionId, EventProcessorId eventProcessorId, CancellationToken cancellationToken)
        {
            _logger.Debug(
                "Filter event that occurred @ {Occurred} to public events stream '{TargetStream}'",
                @event.Occurred,
                Definition.TargetStream);
            if ([email protected])
            {
                return(Task.FromResult <IFilterResult>(new SuccessfulFiltering(false, Guid.Empty)));
            }
            var request = new FilterEventRequest
            {
                Event   = @event.ToProtobuf(),
                ScopeId = Scope.ToProtobuf()
            };

            return(Filter(request, cancellationToken));
        }
 /// <inheritdoc />
 public void Set(EventProcessorId eventProcessorId, CommittedEventVersion committedEventVersion)
 {
     _lastProcessed.AddOrUpdate(eventProcessorId, committedEventVersion, (id, v) => committedEventVersion);
     _logger.Information($"Saving event processor offset");
     _jsRuntime.Invoke($"{_globalObject}.save", eventProcessorId, committedEventVersion);
 }
 public EventProcessorOffset(EventProcessorId eventProcessorId, CommittedEventVersion content)
 {
     EventProcessorId = eventProcessorId;
     Content          = content;
 }
Beispiel #30
0
        public static Mock <IEventProcessor> an_event_processor_mock(Artifact artifact, EventProcessorId id)
        {
            var mock = new Mock <IEventProcessor>();

            mock.SetupGet(_ => _.Event).Returns(artifact);
            mock.SetupGet(_ => _.Identifier).Returns(id);
            return(mock);
        }