async Task <bool> Subscribe( IReverseCallClient <EventHorizonConsumerToProducerMessage, EventHorizonProducerToConsumerMessage, ConsumerSubscriptionRequest, Contracts.SubscriptionResponse, ConsumerRequest, ConsumerResponse> reverseCallClient, SubscriptionId subscriptionId, MicroserviceAddress microserviceAddress, CancellationToken cancellationToken) { _logger.Debug( "Tenant '{ConsumerTenantId}' is subscribing to events from tenant '{ProducerTenantId}' in microservice '{ProducerMicroserviceId}' on address '{Host}:{Port}'", subscriptionId.ConsumerTenantId, subscriptionId.ProducerTenantId, subscriptionId.ProducerMicroserviceId, microserviceAddress.Host, microserviceAddress.Port); var tryGetStreamProcessorState = await _streamProcessorStates.TryGetFor(subscriptionId, cancellationToken).ConfigureAwait(false); var publicEventsPosition = tryGetStreamProcessorState.Result?.Position ?? StreamPosition.Start; return(await reverseCallClient.Connect( new ConsumerSubscriptionRequest { PartitionId = subscriptionId.PartitionId.ToProtobuf(), StreamId = subscriptionId.StreamId.ToProtobuf(), StreamPosition = publicEventsPosition.Value, TenantId = subscriptionId.ProducerTenantId.ToProtobuf() }, cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc /> public async Task <Try <ProjectionIdentifierAndScope> > Resolve(MicroserviceAddress runtime, string identifierOrAlias, ScopeId scope = null) { var projections = await _client.GetAll(runtime).ConfigureAwait(false); var matchesWithoutScope = projections.Where(projection => projection.HasAlias ? projection.Alias.Value == identifierOrAlias : projection.Id.ToString() == identifierOrAlias ).ToList(); if (matchesWithoutScope.Count == 1) { return(new ProjectionIdentifierAndScope(matchesWithoutScope[0].Id, matchesWithoutScope[0].Scope)); } scope ??= ScopeId.Default; var matchesWithScope = matchesWithoutScope.Where(projection => projection.Scope == scope).ToList(); if (matchesWithScope.Count == 1) { return(new ProjectionIdentifierAndScope(matchesWithScope[0].Id, matchesWithScope[0].Scope)); } if (matchesWithoutScope.Count > 1) { return(new MultipleProjectionsWithIdentifierOrAliasInScope(identifierOrAlias, scope, matchesWithoutScope.Count)); } return(new NoProjectionWithIdentifierOrAliasInScope(identifierOrAlias, scope)); }
void StartProcessingEventHorizon( ConsentId consentId, SubscriptionId subscriptionId, MicroserviceAddress microserviceAddress, IReverseCallClient <EventHorizonConsumerToProducerMessage, EventHorizonProducerToConsumerMessage, ConsumerSubscriptionRequest, Contracts.SubscriptionResponse, ConsumerRequest, ConsumerResponse> reverseCallClient) { Task.Run(async() => { try { await ReadEventsFromEventHorizon(consentId, subscriptionId, reverseCallClient).ConfigureAwait(false); throw new Todo(); // TODO: This is a hack to get the policy going. Remove this when we can have policies on return values } catch (Exception ex) { _logger.Debug(ex, "Reconnecting to event horizon with subscription {subscriptionId}", subscriptionId); await _policy.Execute( async _ => { reverseCallClient = CreateClient(microserviceAddress, _cancellationToken); var receivedResponse = await Subscribe(reverseCallClient, subscriptionId, microserviceAddress, _cancellationToken).ConfigureAwait(false); var response = HandleSubscriptionResponse(receivedResponse, reverseCallClient.ConnectResponse, subscriptionId); if (!response.Success) { throw new Todo(); // TODO: This is a hack to get the policy going. Remove this when we can have policies on return values } await ReadEventsFromEventHorizon(response.ConsentId, subscriptionId, reverseCallClient).ConfigureAwait(false); throw new Todo(); // TODO: This is a hack to get the policy going. Remove this when we can have policies on return values }, _cancellationToken).ConfigureAwait(false); } }); }
/// <inheritdoc /> public T CreateClientFor <T>(MicroserviceAddress address) where T : ClientBase <T> { var constructor = typeof(T).GetConstructor(new[] { typeof(ChannelBase) }); ThrowIfMissingExpectedConstructorClientType(typeof(T), constructor); return(constructor !.Invoke(new object[] { GrpcChannel.ForAddress($"http://{address.Host}:{address.Port}") }) as T); }
/// <inheritdoc /> public ISubscription Create(SubscriptionId subscriptionId, MicroserviceAddress producerMicroserviceAddress, ExecutionContext executionContext) => new Subscription( subscriptionId, producerMicroserviceAddress, executionContext, _subscriptionPolicies, _eventHorizonConnectionFactory, _streamProcessorFactory, _subscriptionPositions, _metrics, _processingMetrics, _loggerFactory.CreateLogger <Subscription>());
/// <inheritdoc /> public async Task <IEnumerable <Dolittle.Runtime.Events.EventType> > GetAll(MicroserviceAddress runtime) { var client = _clients.CreateClientFor <EventTypesClient>(runtime); var request = new GetAllRequest(); var response = await client.GetAllAsync(request); if (response.Failure is not null) { throw new GetAllFailed(response.Failure.Reason); } return(response.EventTypes.Select(FromProtobuf)); }
/// <inheritdoc/> public IEventHorizonConnection Create(MicroserviceAddress connectionAddress, ExecutionContext executionContext) { var client = _reverseCallClients.GetFor( new EventHorizonProtocol(), connectionAddress.Host, connectionAddress.Port, TimeSpan.FromSeconds(10)); return(new EventHorizonConnection( executionContext, client, _metrics, _loggerFactory.CreateLogger <EventHorizonConnection>())); }
/// <inheritdoc /> public async Task <IEnumerable <EventHandlerStatus> > GetAll(MicroserviceAddress runtime, TenantId tenant = null) { var client = _clients.CreateClientFor <EventHandlersClient>(runtime); var request = new GetAllRequest { TenantId = tenant?.ToProtobuf() }; var response = await client.GetAllAsync(request); if (response.Failure != null) { throw new GetAllEventHandlersFailed(response.Failure.Reason); } return(response.EventHandlers.Select(CreateEventHandlerStatus)); }
/// <inheritdoc /> public async Task <EventHandlerId> ResolveId(MicroserviceAddress runtime, EventHandlerIdOrAlias idOrAlias) { if (!idOrAlias.IsAlias) { return(idOrAlias.Id); } var statuses = await _managementClient.GetAll(runtime).ConfigureAwait(false); var status = statuses.FirstOrDefault(_ => WithAlias(_, idOrAlias)); if (status == default) { throw new NoEventHandlerWithId(idOrAlias.Alias); } return(status.Id); }
/// <inheritdoc /> public async Task <ArtifactId> ResolveId(MicroserviceAddress runtime, AggregateRootIdOrAlias idOrAlias) { if (!idOrAlias.IsAlias) { return(idOrAlias.Id); } var aggregateRoots = await _managementClient.GetAll(runtime).ConfigureAwait(false); var aggregateRoot = aggregateRoots.FirstOrDefault(_ => WithAlias(_, idOrAlias)); if (aggregateRoot == default) { throw new NoAggregateRootWithId(idOrAlias.Alias); } return(aggregateRoot.AggregateRoot.Identifier.Id); }
/// <inheritdoc /> public async Task <IEnumerable <AggregateRootWithTenantScopedInstances> > GetAll(MicroserviceAddress runtime, TenantId tenant = null) { var client = _clients.CreateClientFor <AggregateRootsClient>(runtime); var request = new GetAllRequest { TenantId = tenant?.ToProtobuf() }; var response = await client.GetAllAsync(request); if (response.Failure is not null) { throw new GetAllFailed(response.Failure.Reason); } return(response.AggregateRoots.Select(FromProtobuf)); }
/// <inheritdoc /> public async Task <Try <AggregateRootWithTenantScopedInstances> > Get(MicroserviceAddress runtime, ArtifactId aggregateRootId, TenantId tenant = null) { var client = _clients.CreateClientFor <AggregateRootsClient>(runtime); var request = new GetOneRequest() { TenantId = tenant?.ToProtobuf(), AggregateRootId = aggregateRootId.ToProtobuf() }; var response = await client.GetOneAsync(request); if (response.Failure is not null) { return(new GetOneFailed(response.Failure.Reason)); } return(FromProtobuf(response.AggregateRoot)); }
/// <inheritdoc /> public async Task ReprocessAllEvents(EventHandlerId eventHandler, MicroserviceAddress runtime) { var client = _clients.CreateClientFor <EventHandlersClient>(runtime); var request = new ReprocessAllEventsRequest { ScopeId = eventHandler.Scope.ToProtobuf(), EventHandlerId = eventHandler.EventHandler.ToProtobuf(), }; var response = await client.ReprocessAllEventsAsync(request); if (response.Failure != null) { throw new ReprocessAllEventsFailed(response.Failure.Reason); } }
/// <inheritdoc /> public async Task <Try> Replay(MicroserviceAddress runtime, ScopeId scope, ProjectionId projection, TenantId tenant = null) { var client = _clients.CreateClientFor <ProjectionsClient>(runtime); var request = new ReplayProjectionRequest { ScopeId = scope.ToProtobuf(), ProjectionId = projection.ToProtobuf(), TenantId = tenant?.ToProtobuf(), }; var response = await client.ReplayAsync(request); if (response.Failure != null) { return(new ReplayProjectionFailed(scope, projection, response.Failure.Reason)); } return(Try.Succeeded()); }
/// <inheritdoc /> public async Task <Try <ProjectionStatus> > Get(MicroserviceAddress runtime, ScopeId scope, ProjectionId projection, TenantId tenant = null) { var client = _clients.CreateClientFor <ProjectionsClient>(runtime); var request = new GetOneProjectionRequest { ScopeId = scope.ToProtobuf(), ProjectionId = projection.ToProtobuf(), TenantId = tenant?.ToProtobuf() }; var response = await client.GetOneAsync(request); if (response.Failure != null) { return(new GetOneProjectionFailed(scope, projection, response.Failure.Reason)); } return(CreateProjectionStatus(response.Projection)); }
/// <inheritdoc /> public async Task <Try <EventHandlerStatus> > Get(MicroserviceAddress runtime, EventHandlerId eventHandler, TenantId tenant = null) { var client = _clients.CreateClientFor <EventHandlersClient>(runtime); var request = new GetOneRequest { EventHandlerId = eventHandler.EventHandler.ToProtobuf(), ScopeId = eventHandler.Scope.ToProtobuf(), TenantId = tenant?.ToProtobuf() }; var response = await client.GetOneAsync(request); if (response.Failure != null) { throw new GetOneEventHandlerFailed(eventHandler, response.Failure.Reason); } return(CreateEventHandlerStatus(response.EventHandlers)); }
/// <inheritdoc /> public async Task <CommittedAggregateEvents> GetEvents(MicroserviceAddress runtime, ArtifactId aggregateRootId, EventSourceId eventSourceId, TenantId tenant = null) { var client = _clients.CreateClientFor <AggregateRootsClient>(runtime); var request = new GetEventsRequest() { TenantId = tenant?.ToProtobuf(), Aggregate = new Aggregate { AggregateRootId = aggregateRootId.ToProtobuf(), EventSourceId = eventSourceId } }; var response = await client.GetEventsAsync(request); if (response.Failure is not null) { throw new GetEventsFailed(response.Failure.Reason); } return(FromProtobuf(response.Events)); }
IReverseCallClient <EventHorizonConsumerToProducerMessage, EventHorizonProducerToConsumerMessage, ConsumerSubscriptionRequest, Contracts.SubscriptionResponse, ConsumerRequest, ConsumerResponse> CreateClient( MicroserviceAddress microserviceAddress, CancellationToken cancellationToken) { var client = _clientManager.Get <Contracts.Consumer.ConsumerClient>( microserviceAddress.Host, microserviceAddress.Port); return(_reverseCallClients.GetFor <EventHorizonConsumerToProducerMessage, EventHorizonProducerToConsumerMessage, ConsumerSubscriptionRequest, Contracts.SubscriptionResponse, ConsumerRequest, ConsumerResponse>( () => client.Subscribe(cancellationToken: cancellationToken), (message, arguments) => message.SubscriptionRequest = arguments, message => message.SubscriptionResponse, message => message.Request, (message, response) => message.Response = response, (arguments, context) => arguments.CallContext = context, request => request.CallContext, (response, context) => response.CallContext = context, message => message.Ping, (message, pong) => message.Pong = pong, TimeSpan.FromSeconds(7))); }
/// <inheritdoc /> public Task <IEnumerable <EventType> > Discover(MicroserviceAddress runtime) => _client.GetAll(runtime);
/// <summary> /// Gets the Aggregate Root id. /// </summary> /// <param name="runtime">The Runtime microservice address.</param> /// <param name="idOrAlias">The AggregateRootId Id or Alias.</param> /// <returns>A <see cref="Task{TResult}"/> that, when resolved, returns the <see cref="ArtifactId"/>.</returns> protected Task <ArtifactId> GetAggregateRootId(MicroserviceAddress runtime, AggregateRootIdOrAlias idOrAlias) => _aggregateRootIdResolver.ResolveId(runtime, idOrAlias);
/// <inheritdoc /> public async Task ReprocessEventsFrom(EventHandlerId eventHandler, TenantId tenant, StreamPosition position, MicroserviceAddress runtime) { var client = _clients.CreateClientFor <EventHandlersClient>(runtime); var request = new ReprocessEventsFromRequest { ScopeId = eventHandler.Scope.ToProtobuf(), EventHandlerId = eventHandler.EventHandler.ToProtobuf(), TenantId = tenant.ToProtobuf(), StreamPosition = position, }; var response = await client.ReprocessEventsFromAsync(request); if (response.Failure != null) { throw new ReprocessEventsFromFailed(response.Failure.Reason); } }
bool TryGetMicroserviceAddress(Microservice producerMicroservice, out MicroserviceAddress microserviceAddress) => _microservicesConfiguration.TryGetValue(producerMicroservice, out microserviceAddress);
/// <summary> /// Gets the <see cref="EventHandlerId"/>. /// </summary> /// <param name="runtime">The Runtime microservice address.</param> /// <param name="idOrAlias">The Event Handler Id or Alias.</param> /// <returns>A <see cref="Task{TResult}"/> that, when resolved, returns the <see cref="EventHandlerId"/>.</returns> protected Task <EventHandlerId> GetEventHandlerId(MicroserviceAddress runtime, EventHandlerIdOrAlias idOrAlias) => _eventHandlerIdResolver.ResolveId(runtime, idOrAlias);
/// <inheritdoc /> public async Task <IEnumerable <NamedRuntimeAddress> > GetAvailableRuntimeAddresses(MicroserviceAddress argument = null) { if (argument == null) { var results = await Task.WhenAll(_addressProviders.Select(_ => _.Discover())); return(results.SelectMany(_ => _)); } var address = new NamedRuntimeAddress( MicroserviceName.NotSet, string.IsNullOrWhiteSpace(argument.Host) ? DefaultRuntimeHost : argument.Host, argument.Port == 0 ? new EndpointsConfiguration().Management.Port : argument.Port); return(new[] { address }); }