示例#1
0
        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));
        }
示例#2
0
    /// <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));
    }
示例#3
0
 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);
         }
     });
 }
示例#4
0
    /// <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);
    }
示例#5
0
 /// <inheritdoc />
 public ISubscription Create(SubscriptionId subscriptionId, MicroserviceAddress producerMicroserviceAddress, ExecutionContext executionContext)
 => new Subscription(
     subscriptionId,
     producerMicroserviceAddress,
     executionContext,
     _subscriptionPolicies,
     _eventHorizonConnectionFactory,
     _streamProcessorFactory,
     _subscriptionPositions,
     _metrics,
     _processingMetrics,
     _loggerFactory.CreateLogger <Subscription>());
示例#6
0
    /// <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>()));
    }
示例#8
0
    /// <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);
    }
示例#10
0
    /// <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);
    }
示例#11
0
    /// <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));
    }
示例#12
0
    /// <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));
    }
示例#13
0
    /// <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);
        }
    }
示例#14
0
    /// <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());
    }
示例#15
0
    /// <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));
    }
示例#16
0
    /// <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));
    }
示例#17
0
    /// <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));
    }
示例#18
0
        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)));
        }
示例#19
0
 /// <inheritdoc />
 public Task <IEnumerable <EventType> > Discover(MicroserviceAddress runtime)
 => _client.GetAll(runtime);
示例#20
0
 /// <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);
示例#21
0
    /// <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);
        }
    }
示例#22
0
 bool TryGetMicroserviceAddress(Microservice producerMicroservice, out MicroserviceAddress microserviceAddress) =>
 _microservicesConfiguration.TryGetValue(producerMicroservice, out microserviceAddress);
示例#23
0
 /// <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);
示例#24
0
    /// <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 });
    }