示例#1
0
        public ServiceDiscoveryRouterMiddleware(
            RequestDelegate next,
            ILogger <ServiceDiscoveryRouterMiddleware> logger,
            IOptions <ServiceDiscoveryRouterMiddlewareOptions> options)
        {
            EnsureArg.IsNotNull(next, nameof(next));
            EnsureArg.IsNotNull(logger, nameof(logger));

            this.next    = next;
            this.logger  = logger;
            this.options = options.Value ?? new ServiceDiscoveryRouterMiddlewareOptions();
        }
示例#2
0
        /// <summary>
        /// Enables the service discovery router.
        /// </summary>
        /// <param name="naosOptions"></param>
        /// <param name="options"></param>
        public static NaosApplicationContextOptions UseNaosServiceDiscoveryRouter(
            this NaosApplicationContextOptions naosOptions,
            ServiceDiscoveryRouterMiddlewareOptions options)
        {
            EnsureArg.IsNotNull(naosOptions, nameof(naosOptions));
            EnsureArg.IsNotNull(options, nameof(options));

#pragma warning disable CS0618 // Type or member is obsolete >> naosOptions.Context.Application.Map("/api/servicediscovery/router/proxy", async proxy => { proxy.UseProxy() } )
            naosOptions.Context.Application.RunProxy("/naos/servicediscovery/router/proxy", async context =>
            {
                var logger         = naosOptions.Context.Application.ApplicationServices.GetRequiredService <ILogger>();
                var registryClient = naosOptions.Context.Application.ApplicationServices.GetRequiredService <RouterContext>().RegistryClient;

                // read headers for service/tag
                var isFoundName = context.Request.Headers.TryGetValue(ServiceDiscoveryRouterHeaders.ServiceName, out var serviceName);
                var isFoundTag  = context.Request.Headers.TryGetValue(ServiceDiscoveryRouterHeaders.ServiceTag, out var serviceTag);

                if (!isFoundName && !isFoundTag)
                {
                    context.Response.StatusCode = 400;
                    throw new NaosException($"Router cannot find a service registration based on the provided information (serviceName={serviceName}, serviceTag={serviceTag})");
                    // = 400 bad request (router headers missing)
                }

                var registrations = await registryClient.RegistrationsAsync(serviceName, serviceTag).AnyContext();
                var registration  = registrations.FirstOrDefault(); // todo: do some kind random/roundrobin

                if (registration == null)
                {
                    context.Response.StatusCode = 502;
                    throw new NaosException($"Router cannot find a service registration based on the provided information (serviceName={serviceName}, serviceTag={serviceTag})");
                    // = 404? 502? https://errorcodespro.com/what-is-http-error-502-bad-gateway/
                }

                // TODO: how is api/registrations NOT forwarded? based on missing router headers?
                // TODO: round robin https://github.com/damianh/ProxyKit/blob/master/src/Recipes/05_RoundRobin.cs
                var upstreamHost = new Uri($"{registration.Address}:{registration.Port}");
                logger.LogInformation($"{{LogKey:l}} router {{Url}} >> {{Host}} (service={{ServiceName}}, tag={serviceTag})", LogKeys.ServiceDiscovery, context.Request.GetUri(), upstreamHost, registration.Name);
                return(await context
                       .ForwardTo(upstreamHost)
                       .Log(logger)
                       .CopyXForwardedHeaders() // copies the headers from the incoming requests
                       .AddXForwardedHeaders()  // adds the current proxy proto/host/for/pathbase to the X-Forwarded headers
                       .Send().AnyContext());
            });
#pragma warning restore CS0618                                                                  // Type or member is obsolete

            naosOptions.Context.Messages.Add("naos application builder: job scheduling added"); // TODO: list available commands/handlers

            //return app.UseMiddleware<ServiceDiscoveryRouterMiddleware>(Options.Create(options));
            return(naosOptions);
        }