public static void Main(string[] args)
        {
            var healthService = new HealthServiceImpl();

            //set the status for all services
            healthService.SetStatus(NotServingService, ServingStatus.NotServing);
            healthService.SetStatus(AvailableService, ServingStatus.Serving);
            healthService.SetStatus(UnknownStatusService, ServingStatus.Unknown);

            //set a status for the overall server health using empty string as the service name
            healthService.SetStatus(string.Empty, ServingStatus.Serving);

            //configure and lanch the grpc service
            var server = new Server
            {
                Services =
                {
                    Health.BindService(healthService)
                },
                Ports = { { GrpcHost, GrpcPort, ServerCredentials.Insecure } }
            };

            server.Start();

            BuildWebHost(args).Run();
        }
示例#2
0
        private static void RunServer(Options options)
        {
            var hostName = options.Hostname ?? Dns.GetHostName();

            var serviceDescriptors = new [] { Dlink.Descriptor, Health.Descriptor, ServerReflection.Descriptor };
            var greeterImpl        = new DlinkImpl(hostName);
            var healthServiceImpl  = new HealthServiceImpl();
            var reflectionImpl     = new ReflectionServiceImpl(serviceDescriptors);

            Server server = new Server
            {
                Services = { Dlink.BindService(greeterImpl), Health.BindService(healthServiceImpl), ServerReflection.BindService(reflectionImpl) },
                Ports    = { new ServerPort("[::]", options.Port, ServerCredentials.Insecure) }
            };

            server.Start();

            // Mark all services as healthy.
            foreach (var serviceDescriptor in serviceDescriptors)
            {
                healthServiceImpl.SetStatus(serviceDescriptor.FullName, HealthCheckResponse.Types.ServingStatus.Serving);
            }
            // Mark overall server status as healthy.
            healthServiceImpl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);

            Console.WriteLine("Dlink server listening on port " + options.Port);
            Console.WriteLine("Press any key to stop the server...");
            Console.ReadKey();

            server.ShutdownAsync().Wait();
        }
示例#3
0
        public void NullsRejected()
        {
            var impl = new HealthServiceImpl();
            Assert.Throws(typeof(NullReferenceException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
            Assert.Throws(typeof(NullReferenceException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));

            Assert.Throws(typeof(NullReferenceException), () => impl.ClearStatus(null, ""));
            Assert.Throws(typeof(NullReferenceException), () => impl.ClearStatus("", null));
        }
示例#4
0
        private Server StartLoadBalancerService([NotNull] ServiceRegistry serviceRegistry,
                                                [NotNull] LoadBalancerConfig loadBalancerConfig)
        {
            ServerCredentials serverCredentials =
                GrpcServerUtils.GetServerCredentials(loadBalancerConfig.Certificate,
                                                     loadBalancerConfig.PrivateKeyFile,
                                                     loadBalancerConfig.EnforceMutualTls);

            var serviceDiscoveryGrpcImpl = new ServiceDiscoveryGrpcImpl(serviceRegistry)
            {
                RemoveUnhealthyServices           = !_keyValueStoreIsLocal,
                WorkerResponseTimeoutSeconds      = loadBalancerConfig.ServiceResponseTimeoutSeconds,
                RecentlyUsedServiceTimeoutSeconds = loadBalancerConfig.RecentlyUsedTimeoutSeconds
            };

            var health = new HealthServiceImpl();

            serviceDiscoveryGrpcImpl.Health = health;

            // General status:
            health.SetStatus(string.Empty, HealthCheckResponse.Types.ServingStatus.Serving);

            // Specifically the LB service:
            health.SetStatus(serviceDiscoveryGrpcImpl.ServiceName,
                             HealthCheckResponse.Types.ServingStatus.Serving);

            _logger.LogInformation("Starting load-balancer service at {host}:{port}",
                                   loadBalancerConfig.HostName, loadBalancerConfig.Port);

            var server =
                new Server
            {
                Services =
                {
                    ServiceDiscoveryGrpc.BindService(serviceDiscoveryGrpcImpl),
                    Health.BindService(health)
                },
                Ports =
                {
                    new ServerPort(loadBalancerConfig.HostName, loadBalancerConfig.Port,
                                   serverCredentials)
                }
            };

            server.Start();

            string protocol = serverCredentials == ServerCredentials.Insecure
                                ? "http"
                                : "https";

            _logger.LogInformation(
                "Load balancer service is serving at {protocol}://{host}:{port}",
                protocol, loadBalancerConfig.HostName, loadBalancerConfig.Port);

            return(server);
        }
示例#5
0
        public void ClearAll()
        {
            var impl = new HealthServiceImpl();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);

            impl.ClearAll();
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, ""));
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "grpc.test.TestService"));
        }
        public void NullsRejected()
        {
            var impl = new HealthServiceImpl();

            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, "", HealthCheckResponse.Types.ServingStatus.SERVING));
            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus("", null, HealthCheckResponse.Types.ServingStatus.SERVING));

            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null, ""));
            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus("", null));
        }
        public void ClearAll()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);

            impl.ClearAll();
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "", ""));
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "virtual-host", ""));
        }
        public void ClearAll()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Unknown);

            impl.ClearAll();
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, ""));
            Assert.Throws(typeof(RpcException), () => GetStatusHelper(impl, "grpc.test.TestService"));
        }
示例#9
0
        public void ClearStatus()
        {
            var impl = new HealthServiceImpl();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.UNKNOWN);

            impl.ClearStatus("");

            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, ""));
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "grpc.test.TestService"));
        }
示例#10
0
        public void ClearStatus()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);

            impl.ClearStatus("", "");

            Assert.Throws(Is.TypeOf(typeof(RpcException)).And.Property("Status").Property("StatusCode").EqualTo(StatusCode.NotFound), () => GetStatusHelper(impl, "", ""));
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));
        }
        public void ClearStatus()
        {
            var impl = new HealthServiceImpl();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Unknown);

            impl.ClearStatus("");

            var ex = Assert.Throws<RpcException>(() => GetStatusHelper(impl, ""));
            Assert.AreEqual(StatusCode.NotFound, ex.Status.StatusCode);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Unknown, GetStatusHelper(impl, "grpc.test.TestService"));
        }
示例#12
0
        public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
        {
            // for every registered health check
            foreach (var entry in report.Entries)
            {
                var status = entry.Value.Status;
                _healthService.SetStatus(entry.Key, ResolveStatus(status));
            }

            _healthService.SetStatus(string.Empty, HealthCheckResponse.Types.ServingStatus.Serving);

            return(Task.CompletedTask);
        }
示例#13
0
        public void ClearStatus()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Unknown);

            impl.ClearStatus("");

            var ex = Assert.Throws <RpcException>(() => GetStatusHelper(impl, ""));

            Assert.AreEqual(StatusCode.NotFound, ex.Status.StatusCode);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Unknown, GetStatusHelper(impl, "grpc.test.TestService"));
        }
        public void SetStatus()
        {
            var impl = new HealthServiceImpl();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NotServing);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Unknown);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Unknown, GetStatusHelper(impl, ""));

            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, GetStatusHelper(impl, "grpc.test.TestService"));
        }
示例#15
0
        public void SetStatus()
        {
            var impl = new HealthServiceImpl();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, ""));

            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "grpc.test.TestService"));
        }
        private static void RegisterHealthCheck(Server server, string serviceName)
        {
            var healthImplementation = new HealthServiceImpl();

            healthImplementation.SetStatus(serviceName, HealthCheckResponse.Types.ServingStatus.Serving);
            server.Services.Add(Health.BindService(healthImplementation));
        }
示例#17
0
        public void SetStatus()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NotServing);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, GetStatusHelper(impl, ""));

            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Unknown);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Unknown, GetStatusHelper(impl, ""));

            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, GetStatusHelper(impl, "grpc.test.TestService"));
        }
        public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
        {
            foreach (var registration in _options.Services)
            {
                var filteredResults = report.Entries
                                      .Select(entry => new HealthResult(entry.Key, entry.Value.Tags, entry.Value.Status, entry.Value.Description, entry.Value.Duration, entry.Value.Exception, entry.Value.Data))
                                      .Where(registration.Predicate);

                var resolvedStatus = HealthCheckResponse.Types.ServingStatus.Unknown;
                foreach (var result in filteredResults)
                {
                    if (result.Status == HealthStatus.Unhealthy)
                    {
                        resolvedStatus = HealthCheckResponse.Types.ServingStatus.NotServing;

                        // No point continuing to check statuses.
                        break;
                    }

                    resolvedStatus = HealthCheckResponse.Types.ServingStatus.Serving;
                }

                _healthService.SetStatus(registration.Name, resolvedStatus);
            }

            return(Task.CompletedTask);
        }
示例#19
0
        public void SetStatus()
        {
            var impl = new HealthServiceImpl();

            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "", ""));

            impl.SetStatus("", "", HealthCheckResponse.Types.ServingStatus.NOT_SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NOT_SERVING, GetStatusHelper(impl, "", ""));

            impl.SetStatus("virtual-host", "", HealthCheckResponse.Types.ServingStatus.UNKNOWN);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.UNKNOWN, GetStatusHelper(impl, "virtual-host", ""));

            impl.SetStatus("virtual-host", "grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.SERVING);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.SERVING, GetStatusHelper(impl, "virtual-host", "grpc.test.TestService"));
        }
示例#20
0
        public static void Start(IConfigurationRoot config)
        {
            var builder = new ContainerBuilder();

            builder.RegisterInstance(config).As <IConfigurationRoot>();
            //builder.RegisterInstance(new DataContext(config)).As<IDataContext>();
            //builder.RegisterAssemblyTypes(typeof(IDataContext).GetTypeInfo().Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();

            _container = builder.Build();
            var servercert     = File.ReadAllText(@"server.crt");
            var serverkey      = File.ReadAllText(@"server.key");
            var keypair        = new KeyCertificatePair(servercert, serverkey);
            var sslCredentials = new SslServerCredentials(new List <KeyCertificatePair>()
            {
                keypair
            });
            var healthService = new HealthServiceImpl();

            _server = new Grpc.Core.Server
            {
                Services = { MsgService.BindService(new MsgServiceImpl()), Grpc.Health.V1.Health.BindService(healthService) },
                Ports    = { new ServerPort("0.0.0.0", 9007, sslCredentials) }
            };
            _server.Start();
            healthService.SetStatus("Demo", Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.Serving);
            _server.ShutdownTask.Wait();
        }
示例#21
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                var health = await _healthCheckService.CheckHealthAsync(stoppingToken);

                _healthService.SetStatus("Greeting", health.Status == HealthStatus.Healthy
                    ? Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.Serving
                    : Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.NotServing);

                _healthService.SetStatus("", health.Status == HealthStatus.Healthy
                    ? Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.Serving
                    : Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.NotServing);

                await Task.Delay(TimeSpan.FromSeconds(15), stoppingToken);
            }
        }
示例#22
0
        public new void Start()
        {
            Ports.Add(_options.Host, _options.Port, ServerCredentials.Insecure);
            _healthService.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);

            foreach (IMethodContext context in _methodRegistry.RegisteredMethods)
            {
                foreach (var(methodName, definition) in context.GetDefinitions())
                {
                    Services.Add(definition.Intercept(_globalInterceptor));
                    _logger.LogDebug("Method {grpc-diag-method} registered.", methodName);
                    _healthService.SetStatus(context.GetServiceName(), HealthCheckResponse.Types.ServingStatus.Serving);
                }
            }

            Services.Add(GrpcHealth.BindService(_healthService));

            base.Start();
        }
示例#23
0
        public async Task Watch_ExceedMaximumCapacitySize_DiscardOldValues()
        {
            var cts     = new CancellationTokenSource();
            var context = new TestServerCallContext(cts.Token);
            var writer  = new TestResponseStreamWriter(started: false);

            var impl     = new HealthServiceImpl();
            var callTask = impl.Watch(new HealthCheckRequest {
                Service = ""
            }, writer, context);

            // Write new statuses. Only last statuses will be returned when we read them from watch writer
            for (var i = 0; i < HealthServiceImpl.MaxStatusBufferSize * 2; i++)
            {
                // These statuses aren't "valid" but it is useful for testing to have an incrementing number
                impl.SetStatus("", (HealthCheckResponse.Types.ServingStatus)i + 10);
            }

            // Start reading responses now that statuses have been queued up
            // This is to keep the test non-flakey
            writer.Start();

            // Read messages in a background task
            var statuses         = new List <HealthCheckResponse.Types.ServingStatus>();
            var readStatusesTask = Task.Run(async() => {
                while (await writer.WrittenMessagesReader.WaitToReadAsync())
                {
                    if (writer.WrittenMessagesReader.TryRead(out var response))
                    {
                        statuses.Add(response.Status);
                    }
                }
            });

            // Tell server we're done watching and it can write what it has left and then exit
            cts.Cancel();
            await callTask;

            // Ensure we've read all the queued statuses
            writer.Complete();
            await readStatusesTask;

            // Collection will contain initial written message (ServiceUnknown) plus 5 queued messages
            Assert.AreEqual(HealthServiceImpl.MaxStatusBufferSize + 1, statuses.Count);

            // Initial written message
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, statuses[0]);

            // Last 5 queued messages
            Assert.AreEqual((HealthCheckResponse.Types.ServingStatus) 15, statuses[statuses.Count - 5]);
            Assert.AreEqual((HealthCheckResponse.Types.ServingStatus) 16, statuses[statuses.Count - 4]);
            Assert.AreEqual((HealthCheckResponse.Types.ServingStatus) 17, statuses[statuses.Count - 3]);
            Assert.AreEqual((HealthCheckResponse.Types.ServingStatus) 18, statuses[statuses.Count - 2]);
            Assert.AreEqual((HealthCheckResponse.Types.ServingStatus) 19, statuses[statuses.Count - 1]);
        }
示例#24
0
        public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
        {
            foreach (var entry in report.Entries)
            {
                var status = entry.Value.Status;

                _healthService.SetStatus(entry.Key, ResolveStatus(status));
            }

            return(Task.CompletedTask);
        }
示例#25
0
        static async Task Main(string[] args)
        {
            if (!TryGetArguments(args, out int port, out int secondsUntilUnhealthy,
                                 out int currentRequests))
            {
                return;
            }

            // The health service every serious grpc server has:
            var healthService = new HealthServiceImpl();

            healthService.SetStatus(_serviceName, HealthCheckResponse.Types.ServingStatus.Serving);

            // The load reporting service required for Quaestor load-balancer:
            LoadReportingGrpcImpl loadReporter = new LoadReportingGrpcImpl();

            // Use Load.StartRequest(); at the beginning
            // and Load.StartRequest(); at the end of a request
            // or assign a known load rate using Load.KnownLoadRate
            Load = new ServiceLoad
            {
                ProcessCapacity     = 1,
                CurrentProcessCount = currentRequests,
                ServerUtilization   = 0.12345
            };

            loadReporter.AllowMonitoring("Worker", Load);

            var server =
                new Server
            {
                Services =
                {
                    // YourGrpc.BindService(yourActualServiceImpl),
                    Health.BindService(healthService),
                    LoadReportingGrpc.BindService(loadReporter)
                },
                Ports =
                {
                    new ServerPort("localhost", port, ServerCredentials.Insecure)
                }
            };

            server.Start();

            if (secondsUntilUnhealthy > 0)
            {
                await SetUnhealthyAfter(secondsUntilUnhealthy, healthService);
            }

            Console.WriteLine("Press any key to finish.");
            Console.ReadKey(true);
        }
示例#26
0
        public async Task Watch()
        {
            var cts     = new CancellationTokenSource();
            var context = new TestServerCallContext(cts.Token);
            var writer  = new TestResponseStreamWriter();

            var impl     = new HealthServiceImpl();
            var callTask = impl.Watch(new HealthCheckRequest {
                Service = ""
            }, writer, context);

            // Calling Watch on a service that doesn't have a value set will initially return ServiceUnknown
            var nextWriteTask = writer.WrittenMessagesReader.ReadAsync();

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask).Status);

            nextWriteTask = writer.WrittenMessagesReader.ReadAsync();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, (await nextWriteTask).Status);

            nextWriteTask = writer.WrittenMessagesReader.ReadAsync();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.NotServing);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, (await nextWriteTask).Status);

            nextWriteTask = writer.WrittenMessagesReader.ReadAsync();
            impl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Unknown);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Unknown, (await nextWriteTask).Status);

            // Setting status for a different service name will not update Watch results
            nextWriteTask = writer.WrittenMessagesReader.ReadAsync();
            impl.SetStatus("grpc.test.TestService", HealthCheckResponse.Types.ServingStatus.Serving);
            Assert.IsFalse(nextWriteTask.IsCompleted);

            impl.ClearStatus("");
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask).Status);

            Assert.IsFalse(callTask.IsCompleted);
            cts.Cancel();
            await callTask;
        }
示例#27
0
        public void SetStatus(string serviceName, bool serving)
        {
            var status = serving
                                             ? HealthCheckResponse.Types.ServingStatus.Serving
                                             : HealthCheckResponse.Types.ServingStatus.NotServing;

            _health.SetStatus(serviceName, status);

            if (status == HealthCheckResponse.Types.ServingStatus.NotServing)
            {
                _isUnhealthy = true;
            }
        }
示例#28
0
        public async Task Watch_MultipleWatchesForDifferentServices()
        {
            var cts     = new CancellationTokenSource();
            var context = new TestServerCallContext(cts.Token);
            var writer1 = new TestResponseStreamWriter();
            var writer2 = new TestResponseStreamWriter();

            var impl      = new HealthServiceImpl();
            var callTask1 = impl.Watch(new HealthCheckRequest {
                Service = "One"
            }, writer1, context);
            var callTask2 = impl.Watch(new HealthCheckRequest {
                Service = "Two"
            }, writer2, context);

            // Calling Watch on a service that doesn't have a value set will initially return ServiceUnknown
            var nextWriteTask1 = writer1.WrittenMessagesReader.ReadAsync();
            var nextWriteTask2 = writer2.WrittenMessagesReader.ReadAsync();

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask1).Status);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask2).Status);

            nextWriteTask1 = writer1.WrittenMessagesReader.ReadAsync();
            nextWriteTask2 = writer2.WrittenMessagesReader.ReadAsync();
            impl.SetStatus("One", HealthCheckResponse.Types.ServingStatus.Serving);
            impl.SetStatus("Two", HealthCheckResponse.Types.ServingStatus.NotServing);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, (await nextWriteTask1).Status);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, (await nextWriteTask2).Status);

            nextWriteTask1 = writer1.WrittenMessagesReader.ReadAsync();
            nextWriteTask2 = writer2.WrittenMessagesReader.ReadAsync();
            impl.ClearAll();
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask1).Status);
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, (await nextWriteTask2).Status);

            cts.Cancel();
            await callTask1;
            await callTask2;
        }
示例#29
0
        protected override async Task ExecuteAsync(CancellationToken cancellationToken)
        {
            var r = new Random();

            while (!cancellationToken.IsCancellationRequested)
            {
                var randomeValue = r.Next(100);
                // You can add other Health Checks here if you are using an external API to verify if it is running.

                //Set status for Service 1
                var serviceStatus = randomeValue % 2 == 0 ? HealthCheckResponse.Types.ServingStatus.Serving :
                                    HealthCheckResponse.Types.ServingStatus.NotServing;
                _healthService.SetStatus(ServiceName, serviceStatus);

                await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken);
            }
        }
示例#30
0
        private static async Task SetUnhealthyAfter(int seconds, HealthServiceImpl healthService)
        {
            Console.WriteLine($"Running service in healthy mode for {seconds}s...");

            await Task.Delay(TimeSpan.FromSeconds(seconds));

            Console.WriteLine("Setting service to NOT_SERVING.");

            healthService.SetStatus(_serviceName,
                                    HealthCheckResponse.Types.ServingStatus.NotServing);

            bool exit = ExitWhenUnhealthy();

            if (exit)
            {
                Environment.Exit(42);
            }
        }
示例#31
0
        public IRpcHost Build()
        {
            var healthService = new HealthServiceImpl();

            healthService.SetStatus(RpcConfigInformation.RpcHealthCheckPath, HealthCheckResponse.Types.ServingStatus.Serving);
            var server = new GrpcCoreServer {
                Ports =
                {
                    new ServerPort("0.0.0.0", this._options.Port, ServerCredentials.Insecure)
                },
                Services =
                {
                    Health.BindService(healthService),
                    this._builder.Build()
                }
            };

            return(new GrpcHost(server));
        }
示例#32
0
        public static void Main(string[] args)
        {
            var server = new Server
            {
                Services = { Greeter.BindService(new GreeterImpl()).Intercept(new LogInterceptor()) },
                Ports    = { new ServerPort(Host, Port, ServerCredentials.Insecure) }
            };

            var healthImpl = new HealthServiceImpl();

            healthImpl.SetStatus(Greeter.Descriptor.FullName, HealthCheckResponse.Types.ServingStatus.Serving);
            server.Services.Add(Health.BindService(healthImpl));

            server.Start();

            Console.WriteLine("Server listening on port " + Port);
            Console.WriteLine("Press any key to shutdown server...");
            Console.ReadKey();

            server.ShutdownAsync().Wait();

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
        private void StartAndRegisterServices(string hostName, int startPort)
        {
            for (int port = startPort; port < startPort + _serviceCount; port++)
            {
                var healthService = new HealthServiceImpl();

                healthService.SetStatus(_serviceName,
                                        HealthCheckResponse.Types.ServingStatus.Serving);

                var         loadReportingService = new LoadReportingGrpcImpl();
                ServiceLoad serviceLoad          = new ServiceLoad(3);

                loadReportingService.AllowMonitoring(_serviceName, serviceLoad);

                var server =
                    new Server
                {
                    Services =
                    {
                        Health.BindService(healthService),
                        LoadReportingGrpc.BindService(loadReportingService)
                    },
                    Ports =
                    {
                        new ServerPort(hostName, port, ServerCredentials.Insecure)
                    }
                };

                server.Start();

                _serviceLoadByLocation.Add(new ServiceLocation(_serviceName, hostName, port, false),
                                           serviceLoad);

                _serviceRegistry.Ensure(_serviceName, hostName, port, false);
            }
        }
示例#34
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddGrpc(options =>
            {
                options.EnableDetailedErrors = true;
            })
            .AddServiceOptions <GreeterService>(options =>
            {
                options.MaxSendMessageSize    = 64 * 1024;
                options.MaxReceiveMessageSize = 64 * 1024;
            })
            .AddServiceOptions <CompressionService>(options =>
            {
                options.ResponseCompressionAlgorithm = "gzip";
            });
            services.AddHttpContextAccessor();

            services
            .AddGrpcClient <Greeter.GreeterClient>((s, o) => { o.Address = GetCurrentAddress(s); })
            .ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
                ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
            })
            .EnableCallContextPropagation();

            services.AddAuthorization(options =>
            {
                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
                {
                    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                    policy.RequireClaim(ClaimTypes.Name);
                });
            });
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters =
                    new TokenValidationParameters
                {
                    ValidateAudience = false,
                    ValidateIssuer   = false,
                    ValidateActor    = false,
                    ValidateLifetime = true,
                    IssuerSigningKey = SecurityKey
                };
            });

            services.AddCors(o =>
            {
                o.AddPolicy("FunctionalTests", builder =>
                {
                    builder.AllowAnyOrigin();
                    builder.AllowAnyMethod();
                    builder.AllowAnyHeader();
                    builder.WithExposedHeaders("Grpc-Status", "Grpc-Message", "Grpc-Encoding", "Grpc-Accept-Encoding");
                });
            });

            services.AddScoped <IncrementingCounter>();

            services.AddSingleton <SingletonValueProvider>();
            services.AddTransient <TransientValueProvider>();
            services.AddScoped <ScopedValueProvider>();

            // When the site is run from the test project these types will be injected
            // This will add a default types if the site is run standalone
            services.TryAddSingleton <DynamicEndpointDataSource>();
            services.TryAddEnumerable(ServiceDescriptor.Singleton <IServiceMethodProvider <DynamicService>, DynamicServiceModelProvider>());

            // Add a Singleton service
            services.AddSingleton <SingletonCounterService>();

            services.AddSingleton <HealthServiceImpl>(s =>
            {
                var service = new HealthServiceImpl();
                service.SetStatus("", Grpc.Health.V1.HealthCheckResponse.Types.ServingStatus.Serving);
                return(service);
            });
示例#35
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            // AutoMapper provides this extension method, which accepts 1-N references to an assembly. AutoMapper then
            // uses reflection to scan the assemblies for any classes that extend `Profile`. All we need to do
            // is tell AutoMapper which assemblies contain profiles and it will wire everything else up for us.
            services.AddAutoMapper(Assembly.GetExecutingAssembly());

            // This will add the our gRPC interceptors to all gRPC services. Interceptors
            // are similar to http middleware (in fact, they're implemented with some of the same code
            // in C#), but are used in a slightly different way since they act on the gRPC layer, not the HTTP layer.
            services.AddGrpc(options =>
            {
                options.EnableDetailedErrors = true;

                // This interceptor logs the request headers of incoming requests.
                options.Interceptors.Add <RequestLoggingGrpcServerInterceptor>();
            });

            // Instantiate a singleton instance of the Grpc health check service. The gRPC health check service is an
            // optional service that gRPC servers can run which report on the health of the server. If your application has
            // the ability and need to report when it's in an unhealthy but still running state, you can implement overrides
            // for the health service endpoints to report the status as needed. By default, the service will be set to Serving,
            // and as long as your service is available no other work needs to be done for that status to continue to be reported.
            //
            // Note that unlike other services, this service is registered as an object *instance* rather than a type.
            // The result is that the provided object will be used as the singleton for all dependents of the type of the object.
            // This pattern is required at times but should only be used when necessary.
            var healthService = new HealthServiceImpl();

            healthService.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving);
            services.AddSingleton(healthService);

            // The reflection service acts as a reporting endpoint which will use reflection to identify all gRPC services that
            // are running on this server and provide a gRPC service that can report on this information. This can be very helpful
            // as it allows various gRPC tools to act as clients and learn about what services are available.
            // Tools such as BloomRPC can also make use of this information to provide skeleton requests, making the service easier to consume.
            var reflectionServiceImpl = new ReflectionServiceImpl(
                new List <Google.Protobuf.Reflection.ServiceDescriptor>
            {
                Health.Descriptor
            }
                );

            services.AddSingleton(reflectionServiceImpl);

            // This extension method registers the feature management systems classes with the service provider, including
            // `IFeatureManager` which application code can depend on to provide information about what features are enabled.
            services.AddFeatureManagement(Configuration);

            services.AddOptions <V2RepositorySettings>()
            .Bind(Configuration.GetSection("V2RepositorySettings"))
            .ValidateDataAnnotations();

            // Here, we make use of the feature management system to determine which repository implementation should be used
            // at runtime. We register a singleton of each repository (since they hold data in memory as a mock "database"),
            // then map their shared interface to a delegate which extracts the feature manager from the provider to determine
            // which concrete type the interface should map to for the given request. By making the interface scoped, we
            // ensure that if the feature flag ever changes, the repository will be recreated with the new backing implementation
            // for each request.
            services.AddScoped <WeatherForecastRepository>();
            services.AddScoped <WeatherForecastRepositoryV2>();
            services.AddScoped <IWeatherForecastRepository>(provider =>
            {
                var featureManager = provider.GetRequiredService <IFeatureManager>();

                // Normally you should avoid calling `.Result` on a Task<T> object, but we have no choice here as the delegate
                // we're using to make use of the feature flag is not asynchronous. Thankfully, this blocking call will only occur
                // once at startup.
                if (featureManager.IsEnabledAsync(nameof(FeatureFlags.UseExperimentalRepository)).Result)
                {
                    return(provider.GetRequiredService <WeatherForecastRepositoryV2>());
                }

                return(provider.GetRequiredService <WeatherForecastRepository>());
            });

            // The feature management system also allows applications to implement the `IDisabledFeaturesHandler` to register
            // for notifications when callers attempt to access a feature that is blocked.
            services.AddSingleton <IDisabledFeaturesHandler, DisabledFeatureLoggingHandler>();
        }
        public void NullsRejected()
        {
            var impl = new HealthServiceImpl();
            Assert.Throws(typeof(ArgumentNullException), () => impl.SetStatus(null, HealthCheckResponse.Types.ServingStatus.Serving));

            Assert.Throws(typeof(ArgumentNullException), () => impl.ClearStatus(null));
        }