/// <inheritdoc/> public override async Task Connect( IAsyncStreamReader <FilterClientToRuntimeMessage> runtimeStream, IServerStreamWriter <FilterRuntimeToClientMessage> clientStream, ServerCallContext context) { _logger.Debug("Connecting Unpartitioned Filter"); using var cts = CancellationTokenSource.CreateLinkedTokenSource(_hostApplicationLifetime.ApplicationStopping, context.CancellationToken); var cancellationToken = cts.Token; var dispatcher = _reverseCallDispatchers.GetFor <FilterClientToRuntimeMessage, FilterRuntimeToClientMessage, FilterRegistrationRequest, FilterRegistrationResponse, FilterEventRequest, FilterResponse>( runtimeStream, clientStream, context, _ => _.RegistrationRequest, (serverMessage, registrationResponse) => serverMessage.RegistrationResponse = registrationResponse, (serverMessage, request) => serverMessage.FilterRequest = request, _ => _.FilterResult, _ => _.CallContext, (request, context) => request.CallContext = context, _ => _.CallContext, (message, ping) => message.Ping = ping, message => message.Pong); if (await RejectIfNotReceivedArguments(dispatcher, cancellationToken).ConfigureAwait(false)) { return; } var arguments = dispatcher.Arguments; var executionContext = arguments.CallContext.ExecutionContext.ToExecutionContext(); _logger.Trace("Setting execution context{NewLine}{ExecutionContext}", System.Environment.NewLine, executionContext); _executionContextManager.CurrentFor(arguments.CallContext.ExecutionContext); var filterId = arguments.FilterId.To <StreamId>(); var scopeId = arguments.ScopeId.To <ScopeId>(); var sourceStreamId = StreamId.EventLog; if (await RejectIfInvalidFilterId(dispatcher, filterId, cancellationToken).ConfigureAwait(false)) { return; } var filterDefinition = new FilterDefinition(sourceStreamId, filterId, partitioned: false); await RegisterFilter( dispatcher, scopeId, filterDefinition, () => new FilterProcessor( scopeId, filterDefinition, dispatcher, _getEventsToStreamsWriter(), _loggerManager.CreateLogger <FilterProcessor>()), cancellationToken).ConfigureAwait(false); }
/// <inheritdoc/> public ICommandContext EstablishForCommand(CommandRequest command) { _logger.Debug("Establishing command context for command '{CommandType}' with correlation '{CorrelationId}'", command.Type, command.CorrelationId); if (!IsInContext(command)) { _executionContextManager.CurrentFor(_executionContextManager.Current.Tenant, command.CorrelationId); _currentContext.Value = _factory.Build(command); } else { _executionContextManager.CurrentFor(_currentContext.Value.ExecutionContext); } return(_currentContext.Value); }
/// <summary> /// /// </summary> /// <param name="queryRequest"></param> /// <returns></returns> public async Task <QueryResult> Execute(QueryRequest queryRequest) { QueryResult result = null; try { _executionContextManager.CurrentFor(TenantId.Development, Dolittle.Execution.CorrelationId.New(), ClaimsPrincipal.Current.ToClaims()); var queryType = _typeFinder.GetQueryTypeByName(queryRequest.GeneratedFrom); var query = _container.Get(queryType) as IQuery; PopulateProperties(queryRequest, queryType, query); _logger.Trace($"Executing runtime query coordinator"); result = await _queryCoordinator.Execute(query, new PagingInfo()); if (result.Success) { AddClientTypeInformation(result); } } catch (Exception ex) { _logger.Error(ex, $"Error executing query : '{queryRequest.NameOfQuery}'"); result = new QueryResult { Exception = ex, QueryName = queryRequest.NameOfQuery }; } return(result); }
/// <inheritdoc /> public void HandleWebhookPayload(ActivityPayload payload, Guid deliveryId) { IEnumerable <HandlerMethod> handlerMethods = _handlerRegistry.GetHandlersFor(payload.GetType()); if (handlerMethods.Any()) { // Figure out the execution context for this event var tenantId = _tenantMapper.GetTenantFor(payload.Installation.Id); if (tenantId == TenantId.Unknown) { _logger.Warning($"GitHub installation '{payload.Installation.Id}' is not mapped to a tenant. The webhook will be ignored."); return; } _executionContextManager.CurrentFor(tenantId, deliveryId); // Schedule the event for processing var scheduler = _schedulerFactory(); foreach (var handler in handlerMethods) { scheduler.QueueWebhookEventForHandling(new Webhook(handler, payload)); } } }
/// <inheritdoc /> public void Process(IPod pod) { _executionContextManager.CurrentFor(pod.Metadata.Tenant); if (pod.IsDeleted) { _logger.Information($"Build-pod '{pod.Metadata.ToString()}' is deleted."); return; } if (!pod.HasBuildContainerStatuses) { _logger.Information($"Build-pod '{pod.Metadata.ToString()}' has no statuses to process."); return; } if (pod.HasSucceeded) { _logger.Information($"Build-pod '{pod.Metadata.ToString()}' succeeded."); ProcessSteps(pod); pod.Delete(); return; } else if (pod.HasFailed) { _logger.Warning($"Build-pod '{pod.Metadata.ToString()}' failed."); pod.Delete(); return; } _logger.Information($"Build-pod '{pod.Metadata.ToString()}' still in progress."); ProcessSteps(pod); }
/// <summary> /// Processes the <see cref="CommittedEventStreamWithContext" /> /// </summary> /// <param name="committedEventStreamWithContext">The <see cref="CommittedEventStream" /> to process</param> protected virtual void ProcessStream(CommittedEventStreamWithContext committedEventStreamWithContext) { _executionContextManager.CurrentFor(committedEventStreamWithContext.Context); var committedEventStream = committedEventStreamWithContext.EventStream; _logger.Debug($"Processing stream {committedEventStream.Sequence} {committedEventStream.Id} {committedEventStream.CorrelationId}"); committedEventStream.Events.ForEach(e => Process(e.ToCommittedEventEnvelope(committedEventStream.Sequence), committedEventStreamWithContext.Context)); }
void ReportBuildResult(V1Pod pod, bool success) { TenantId tenantId = new Guid(pod.Metadata.Labels[PodLabels.Tenant]); ImprovementId improvementId = new Guid(pod.Metadata.Labels[PodLabels.Improvement]); _executionContextManager.CurrentFor(tenantId); var resultHandler = _improvementResultHandlerFactory(); if (success) { resultHandler.HandleSuccess(improvementId); } else { resultHandler.HandleFailure(improvementId); } }
/// <inheritdoc/> public void Perform(Action <TenantId> action) { var originalExecutionContext = _executionContextManager.Current; try { foreach (var tenant in _tenants.All.ToArray()) { _executionContextManager.CurrentFor(tenant); action(tenant); } } finally { _executionContextManager.CurrentFor(originalExecutionContext); } }
/// <summary> /// Middleware invocation method. /// </summary> /// <param name="context">Current <see cref="HttpContext"/>.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public Task InvokeAsync(HttpContext context) { var tenantIdHeader = _options.CurrentValue.TenantIdHeaderName; var tenantId = GetTenantIdFromHeaders(context, tenantIdHeader); _executionContextManager.CurrentFor(tenantId, CorrelationId.New()); return(_next.Invoke(context)); }
/// <inheritdoc/> public ExecutionContext ConfigureFor(TenantId tenantId, CorrelationId correlationId, Claims claims) { var executionEnvironment = EnvironmentUtilities.GetExecutionEnvironment(); var executionApplication = DeduceApplication(); var executionBoundedContext = DeduceBoundedContext(); _executionContextManager.SetConstants(executionApplication, executionBoundedContext, executionEnvironment); return(_executionContextManager.CurrentFor(tenantId, correlationId, claims ?? Dolittle.Security.Claims.Empty)); }
IEnumerable <Commits> GetCommits(IEnumerable <TenantOffset> tenantOffsets) { var commits = new List <Commits>(); Parallel.ForEach(tenantOffsets, (_) => { _executionContextManager.CurrentFor(_.Tenant); commits.Add(_unprocessedCommitFetcher.GetUnprocessedCommits(_.Offset)); }); return(commits); }
/// <summary> /// Initializes a new instance of the <see cref="BootProcedure"/> class. /// </summary> /// <param name="container">The <see cref="IContainer"/>.</param> /// <param name="executionContextManager">The <see cref="IExecutionContextManager"/> for managing <see cref="ExecutionContext"/>.</param> /// <param name="jsRuntime">The <see cref="IJSRuntime"/>.</param> public BootProcedure( IContainer container, IExecutionContextManager executionContextManager, IJSRuntime jsRuntime) { _jsRuntime = jsRuntime; executionContextManager.CurrentFor(TenantId.Development); _configurationFor = container.Get <IConfigurationFor <Configuration> >(); }
/// <inheritdoc/> public ExecutionContext ConfigureFor(TenantId tenantId, CorrelationId correlationId, Claims claims) { var executionEnvironment = DeduceEnvironment(); var executionApplication = DeduceApplication(); var executionBoundedContext = DeduceBoundedContext(); _executionContextManager.SetConstants(executionApplication, executionBoundedContext, executionEnvironment); return(_executionContextManager.CurrentFor(tenantId, correlationId, claims)); }
/// <summary> /// Set current execution context for a Protobuf <see cref="Execution.Contracts.ExecutionContext"/>. /// </summary> /// <param name="executionContextManager"><see cref="IExecutionContextManager"/> to extend.</param> /// <param name="executionContext"><see cref="Execution.Contracts.ExecutionContext"/> to set current.</param> public static void CurrentFor(this IExecutionContextManager executionContextManager, Execution.Contracts.ExecutionContext executionContext) { var microservice = executionContext.MicroserviceId.To <Microservice>(); var tenant = executionContext.TenantId.To <TenantId>(); var correlationId = executionContext.CorrelationId.To <CorrelationId>(); var claims = executionContext.Claims.ToClaims(); executionContextManager.CurrentFor( microservice, tenant, correlationId, claims); }
/// <inheritdoc/> public void Perform() { var environment = _executionContextManager.Current.Environment; _resourceConfiguration.ConfigureResourceTypes( _boundedContextConfiguration.Resources.ToDictionary( kvp => kvp.Key, kvp => environment == Environment.Production ? kvp.Value.Production : kvp.Value.Development)); _executionContextManager.SetConstants(_boundedContextConfiguration.BoundedContext, Version.NotSet, environment); _executionContextManager.CurrentFor(_boundedContextConfiguration.BoundedContext, _executionContextManager.Current.Tenant); HasPerformed = true; }
/// <inheritdoc/> public override async Task <Contracts.CommitEventsResponse> Commit(Contracts.CommitEventsRequest request, ServerCallContext context) { _executionContextManager.CurrentFor(request.CallContext.ExecutionContext); var response = new Contracts.CommitEventsResponse(); try { _logger.Debug("{eventsCount} Events received for committing", request.Events.Count); var events = request.Events.Select(_ => new UncommittedEvent(_.EventSourceId.To <EventSourceId>(), new Artifact(_.Artifact.Id.To <ArtifactId>(), _.Artifact.Generation), _.Public, _.Content)); var uncommittedEvents = new UncommittedEvents(new ReadOnlyCollection <UncommittedEvent>(events.ToList())); var committedEvents = await _eventStoreFactory().CommitEvents(uncommittedEvents, context.CancellationToken).ConfigureAwait(false); _logger.Debug("Events were successfully committed"); response.Events.AddRange(committedEvents.ToProtobuf()); } catch (Exception ex) { _logger.Warning(ex, "Error committing events"); response.Failure = GetFailureFromException(ex); } return(response); }
/// <inheritdoc/> public async Task <bool> ReceiveArguments(CancellationToken cancellationToken) { ThrowIfReceivingArguments(); lock (_receiveArgumentsLock) { ThrowIfReceivingArguments(); _receivingArguments = true; } if (await _clientStream.MoveNext(cancellationToken).ConfigureAwait(false)) { var arguments = _getConnectArguments(_clientStream.Current); if (arguments != null) { var callContext = _getArgumentsContext(arguments); if (callContext?.PingInterval == null) { _logger.Warning("Received arguments, but ping interval was not set"); return(false); } var interval = callContext.PingInterval.ToTimeSpan(); if (interval.TotalMilliseconds <= 0) { _logger.Warning("Received arguments, but ping interval is less than or equal to zero milliseconds"); return(false); } _pingInterval = callContext.PingInterval.ToTimeSpan(); if (callContext?.ExecutionContext != null) { _executionContextManager.CurrentFor(callContext.ExecutionContext.ToExecutionContext()); Arguments = arguments; return(true); } else { _logger.Warning("Received arguments, but call execution context was not set."); } } else { _logger.Warning("Received initial message from client, but arguments was not set."); } } return(false); }
/// <inheritdoc /> public IEnumerable <TenantOffset> Get(IEnumerable <TenantId> tenants, EventHorizonKey key) { var offsets = new List <TenantOffset>(); Parallel.ForEach(tenants, (tenant) => { _executionContextManager.CurrentFor(tenant); using (var geodesics = _getGeodesics()) { var offset = geodesics.GetOffset(key); offsets.Add(new TenantOffset(tenant, offset)); } }); return(offsets); }
void ProcessInParallel() { //_logger.Information("Process") Parallel.ForEach(_systemsThatKnowAboutEventProcessors.ToList(), (system) => { Parallel.ForEach(system.ToList(), (processor) => { Parallel.ForEach(_tenants.All, (t) => { _executionContextManager.CurrentFor(t, CorrelationId.New(), Claims.Empty); _processingHub.Register(new ScopedEventProcessor(t, processor, _getOffsetRepository, _getUnprocessedEventsFetcher, _logger)); }); }); }); }
public void Perform() { _tenants.All.ForEach(tenant => { Task.Factory.StartNew(() => { try { _contextManager.CurrentFor(tenant); _configurationManagerFactory().Start(); } catch (Exception e) { _logger.Error(e, $"Error while startig identity provider configuration manager for tenant '{tenant}'. No providers will be available for that tenant."); } }); }); }
/// <inheritdoc /> public void HandleWebhookPayload(ActivityPayload payload, Guid deliveryId) { if (_registeredHandlers.TryGetValue(payload.GetType(), out var handlers)) { // Figure out the execution context for this event var tenantId = _tenantMapper.GetTenantFor(payload.Installation); _executionContextManager.CurrentFor(tenantId, deliveryId); // Schedule the event for processing var scheduler = _schedulerFactory(); foreach (var handler in handlers) { scheduler.QueueWebhookEventForHandling(handler.Type, handler.Method, payload); } } }
/// <inheritdoc/> public QueryResult Execute(TenantId tenant, IQuery query) { _executionContextManager.CurrentFor(tenant); var instance = _container.Get(query.GetType()) as IQuery; foreach (var property in query.GetType().GetProperties()) { if (!property.Name.Equals("Query", StringComparison.InvariantCulture)) { property.SetValue(instance, property.GetValue(query)); } } return(_runtimeQueryCoordinator.Execute(instance, new PagingInfo { Number = 0, Size = int.MaxValue }).Result); }
public IActionResult SignUserInTo(HttpContext context, TenantId tenant, string redirectUri) { var authResult = context.AuthenticateAsync(Constants.ExternalCookieSchemeName).Result; if (authResult.Succeeded) { var userTenants = _mapper.GetTenantsFor(authResult.Principal); foreach (var userTenant in userTenants) { if (userTenant == tenant) { _manager.CurrentFor(tenant); return(SetTenantCredentialsFor(context, _userMapperFactory(), authResult.Principal, redirectUri)); } } } return(new UnauthorizedResult()); }
async Task OnReceivedRequest( Func <TRequest, CancellationToken, Task <TResponse> > callback, TRequest request, CancellationToken cancellationToken) { try { var requestContext = _getRequestContext(request); var callId = requestContext.CallId.To <ReverseCallId>(); TResponse response; try { _logger.Trace("Handling request with call '{CallId}'", callId); _executionContextManager.CurrentFor(requestContext.ExecutionContext); response = await callback(request, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { _logger.Warning(ex, "An error occurred while invoking request handler callback for request '{CallId}'", callId); return; } await _writeResponseSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { await WriteResponse(response, callId, cancellationToken).ConfigureAwait(false); } catch (Exception ex) { _logger.Warning(ex, "Error occurred while writing response for request '{CallId}'", callId); } finally { _writeResponseSemaphore.Release(); } } catch (Exception ex) { _logger.Warning(ex, "An error occurred while handling received request"); } }
/// <inheritdoc/> public async Task BindModelAsync(ModelBindingContext bindingContext) { var stream = bindingContext.HttpContext.Request.Body; try { using (var buffer = new MemoryStream()) { await stream.CopyToAsync(buffer); buffer.Position = 0L; using (var reader = new StreamReader(buffer)) { var json = await reader.ReadToEndAsync(); var commandRequestKeyValues = _serializer.GetKeyValuesFromJson(json); var correlationId = Guid.Parse(commandRequestKeyValues["correlationId"].ToString()); _executionContextManager.CurrentFor(TenantId.Unknown, correlationId); var content = _serializer.GetKeyValuesFromJson(commandRequestKeyValues["content"].ToString()); var commandRequest = new CommandRequest( Guid.Parse(commandRequestKeyValues["correlationId"].ToString()), Guid.Parse(commandRequestKeyValues["type"].ToString()), ArtifactGeneration.First, content.ToDictionary(keyValue => keyValue.Key.ToPascalCase(), keyValue => keyValue.Value) ); bindingContext.Result = ModelBindingResult.Success(commandRequest); } bindingContext.HttpContext.Request.Body = buffer; } } catch (Exception ex) { throw ex; } }
/// <inheritdoc/> public async Task <SubscriptionResponse> Subscribe(TenantId consumerTenant, Subscription subscription, CancellationToken cancellationToken) { _executionContextManager.CurrentFor(consumerTenant); _logger.Debug("Subscribing to events from {Partition} in {Stream} of {ProducerTenant} in {Microservice} for {ConsumerTenant} into {Scope}", subscription.Partition, subscription.Stream, subscription.Tenant, subscription.Microservice, consumerTenant, subscription.Scope); var response = await _client.SubscribeAsync( new Contracts.Subscription { CallContext = new Services.Contracts.CallRequestContext { HeadId = _head.Id.ToProtobuf(), ExecutionContext = _executionContextManager.Current.ToProtobuf(), }, PartitionId = subscription.Partition.ToProtobuf(), StreamId = subscription.Stream.ToProtobuf(), TenantId = subscription.Tenant.ToProtobuf(), MicroserviceId = subscription.Microservice.ToProtobuf(), ScopeId = subscription.Scope.ToProtobuf() }, cancellationToken : cancellationToken); return(new SubscriptionResponse(response.ConsentId, response.Failure)); }
void GatherAllEventProcessors() { _logger.Information("Gather all event processors"); _scheduler.PerformForEach(_systemsThatKnowAboutEventProcessors, (system) => { _logger.Information($"System that knows about event processors : {system.GetType().AssemblyQualifiedName}"); _scheduler.PerformForEach(system, (processor) => { _logger.Information($"Processor : {processor.GetType().AssemblyQualifiedName}"); _scheduler.PerformForEach(_tenants.All, (t) => { _logger.Information($"Register scoped event processor for tenant : {t}"); _executionContextManager.CurrentFor(t, CorrelationId.New(), Claims.Empty); _processingHub.Register(new ScopedEventProcessor(t, processor, _getOffsetRepository, _getUnprocessedEventsFetcher, _logger)); }); }); }); }
/// <summary> /// Injects an event /// </summary> public void InjectEvent(TenantId tenant, EventSourceId eventSourceId, IEvent @event) { _logger.Information($"Injecting event!"); _executionContextManager.CurrentFor(tenant); var executionContext = _executionContextManager.Current; using (var eventStore = _getEventStore()) { var artifact = _artifactTypeMap.GetArtifactFor(@event.GetType()); var eventSourceKey = new EventSourceKey(eventSourceId, artifact.Id); var version = eventStore.GetNextVersionFor(eventSourceKey); var uncommittedEventStream = new UncommittedEventStream( CommitId.New(), executionContext.CorrelationId, new VersionedEventSource(version, eventSourceKey), DateTimeOffset.Now, EventStream.From(new [] { new EventEnvelope( new EventMetadata( EventId.New(), new VersionedEventSource(version, eventSourceKey), executionContext.CorrelationId, artifact, DateTimeOffset.Now, executionContext ), @event.ToPropertyBag() ) }) ); _logger.Information("Commit events to store"); var committedEventStream = eventStore.Commit(uncommittedEventStream); _logger.Information("Process committed events"); _processingHub.Process(committedEventStream); } }
public void Replay <T>( IEnumerable <T> events, Func <T, Guid> getIdCallback, Action <IEventSource, T> eventSourceCallback = null) where T : IEvent { _executionContextManager.CurrentFor(TenantId.Unknown); events.ForEach(@event => { try { var eventSource = new ExternalSource(getIdCallback(@event)); eventSource.Apply(@event); if (eventSourceCallback != null) { eventSourceCallback(eventSource, @event); } _uncommittedEventStreamCoordinator.Commit(CorrelationId.New(), eventSource.UncommittedEvents); } catch (Exception exception) { _logger.Error(exception, "Problem applying event"); } }); }
/// <summary> /// Handle a command /// </summary> /// <param name="json">JSON representation of a <see cref="CommandRequest"/></param> /// <returns><see cref="CommandResult"/></returns> public CommandResult Handle(string json) { _logger.Information($"Handle : {json}"); var commandRequestKeyValues = _serializer.GetKeyValuesFromJson(json); var correlationId = Guid.Parse(commandRequestKeyValues["correlationId"].ToString()); _executionContextManager.CurrentFor(TenantId.Development, correlationId); var content = _serializer.GetKeyValuesFromJson(commandRequestKeyValues["content"].ToString()); var commandRequest = new CommandRequest( Guid.Parse(commandRequestKeyValues["correlationId"].ToString()), Guid.Parse(commandRequestKeyValues["type"].ToString()), ArtifactGeneration.First, content.ToDictionary(keyValue => keyValue.Key.ToPascalCase(), keyValue => keyValue.Value) ); var result = _commandCoordinator.Handle(commandRequest); return(result); }