コード例 #1
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();
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        public async Task PublishAsync_Check_MapStatuses()
        {
            // Arrange
            var healthService = new HealthServiceImpl();
            var publisher     = new GrpcHealthChecksPublisher(healthService);

            // Act
            HealthCheckResponse response;

            var report = new HealthReport(
                new Dictionary <string, HealthReportEntry>
            {
                [nameof(HealthStatus.Healthy)]   = new HealthReportEntry(HealthStatus.Healthy, "Description!", TimeSpan.Zero, exception: null, data: null),
                [nameof(HealthStatus.Degraded)]  = new HealthReportEntry(HealthStatus.Degraded, "Description!", TimeSpan.Zero, exception: null, data: null),
                [nameof(HealthStatus.Unhealthy)] = new HealthReportEntry(HealthStatus.Unhealthy, "Description!", TimeSpan.Zero, exception: null, data: null)
            },
                TimeSpan.Zero);
            await publisher.PublishAsync(report, CancellationToken.None);

            // Assert
            response = await healthService.Check(new HealthCheckRequest { Service = nameof(HealthStatus.Healthy) }, context : null);

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, response.Status);

            response = await healthService.Check(new HealthCheckRequest { Service = nameof(HealthStatus.Degraded) }, context : null);

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, response.Status);

            response = await healthService.Check(new HealthCheckRequest { Service = nameof(HealthStatus.Unhealthy) }, context : null);

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, response.Status);
        }
コード例 #4
0
        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();
        }
コード例 #5
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();
        }
コード例 #6
0
        public async Task PublishAsync_Check_ChangingStatus()
        {
            // Arrange
            var healthService = new HealthServiceImpl();
            var publisher     = new GrpcHealthChecksPublisher(healthService);

            HealthCheckResponse response;

            // Act 1
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => healthService.Check(new HealthCheckRequest {
                Service = ""
            }, context: null));

            // Assert 1
            Assert.AreEqual(StatusCode.NotFound, ex.StatusCode);

            // Act 2
            var report = CreateSimpleHealthReport(HealthStatus.Healthy);
            await publisher.PublishAsync(report, CancellationToken.None);

            response = await healthService.Check(new HealthCheckRequest { Service = "" }, context : null);

            // Assert 2
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, response.Status);

            // Act 3
            report = CreateSimpleHealthReport(HealthStatus.Unhealthy);
            await publisher.PublishAsync(report, CancellationToken.None);

            response = await healthService.Check(new HealthCheckRequest { Service = "" }, context : null);

            // Act 3
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, response.Status);
        }
コード例 #7
0
ファイル: GrpcServer.cs プロジェクト: MirzaMerdovic/GrpcHost
 public GrpcServer(HealthServiceImpl healthService, GlobalInterceptor globalInterceptor, ILogger logger, IOptions <HostOptions> options, MethodRegistry methodRegistry)
 {
     _healthService     = healthService ?? throw new ArgumentNullException(nameof(healthService));
     _globalInterceptor = globalInterceptor ?? throw new ArgumentNullException(nameof(globalInterceptor));
     _logger            = logger ?? throw new ArgumentNullException(nameof(logger));
     _options           = options.Value ?? throw new ArgumentNullException(nameof(options));
     _methodRegistry    = methodRegistry ?? throw new ArgumentNullException(nameof(methodRegistry));
 }
コード例 #8
0
        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));
        }
コード例 #9
0
        private static GrpcHealthChecksPublisher CreatePublisher(HealthServiceImpl healthService, Action <GrpcHealthChecksOptions>?configureOptions = null)
        {
            var options = new GrpcHealthChecksOptions();

            options.Services.MapService("", r => true);
            configureOptions?.Invoke(options);
            return(new GrpcHealthChecksPublisher(healthService, Options.Create(options)));
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: ProSuite/ProSuite
        private static Grpc.Core.Server StartServer([NotNull] MicroserverArguments arguments,
                                                    out IServiceHealth health)
        {
            // TODO: Move to ProSuite
            var healthService = new HealthServiceImpl();

            health = null;             // new ServiceHealth(healthService);

            int maxThreadCount = arguments.MaxParallel;

            if (maxThreadCount <= 0)
            {
                maxThreadCount = Environment.ProcessorCount - 1;
            }

            var taskScheduler = new StaTaskScheduler(maxThreadCount);

            var removeOverlapsServiceImpl = new RemoveOverlapsGrpcImpl(taskScheduler)
            {
                //Health = health
            };

            var advancedReshapeServiceImpl = new AdvancedReshapeGrpcImpl(taskScheduler);
            var changeAlongServiceImpl     = new ChangeAlongGrpcImpl(taskScheduler);

            //health.SetStatus(removeOverlapsServiceImpl.GetType(), true);

            ServerCredentials serverCredentials =
                GrpcServerUtils.GetServerCredentials(arguments.Certificate,
                                                     arguments.PrivateKeyFile);

            var oneGb = (int)Math.Pow(1024, 3);

            IList <ChannelOption> channelOptions = GrpcServerUtils.CreateChannelOptions(oneGb);

            var server =
                new Grpc.Core.Server(channelOptions)
            {
                Services =
                {
                    RemoveOverlapsGrpc.BindService(removeOverlapsServiceImpl),
                    ReshapeGrpc.BindService(advancedReshapeServiceImpl),
                    ChangeAlongGrpc.BindService(changeAlongServiceImpl)
                    //Health.BindService(healthService)
                },
                Ports =
                {
                    new ServerPort(arguments.HostName, arguments.Port, serverCredentials)
                }
            };

            server.Start();

            _msg.InfoFormat("Service is listening on host {0}, port {1}.", arguments.HostName,
                            arguments.Port);

            return(server);
        }
コード例 #11
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));
        }
コード例 #12
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);
        }
コード例 #13
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"));
        }
コード例 #14
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]);
        }
コード例 #15
0
        /// <summary>
        /// Starts the grpc server, binds the <see cref="QualityVerificationGrpcImpl"/> together
        /// with the <see cref="IServiceHealth"/> implementation and returns a handle for both.
        /// </summary>
        /// <param name="arguments">The microserver command line / config arguments.</param>
        /// <param name="inputsFactoryMethod">The factory method that creates the
        /// <see cref="IBackgroundVerificationInputs"/> instance. If no factory is proveded, only
        /// stand-alone verification (such as XML) can be used.</param>
        /// <param name="checkout3dAnalyst"></param>
        /// <param name="markUnhealthyOnExceptions"></param>
        /// <returns></returns>
        public static StartedGrpcServer StartVerificationServer(
            [NotNull] MicroserverArguments arguments,
            [CanBeNull]
            Func <VerificationRequest, IBackgroundVerificationInputs> inputsFactoryMethod,
            bool checkout3dAnalyst,
            bool markUnhealthyOnExceptions)
        {
            var healthService = new HealthServiceImpl();

            IServiceHealth health = new ServiceHealth(healthService);

            var wuVerificationServiceImpl =
                new QualityVerificationGrpcImpl(inputsFactoryMethod,
                                                arguments.MaxParallel)
            {
                Checkout3DAnalyst = checkout3dAnalyst
            };

            if (markUnhealthyOnExceptions)
            {
                wuVerificationServiceImpl.Health = health;
            }

            health.SetStatus(wuVerificationServiceImpl.GetType(), true);

            ServerCredentials serverCredentials =
                GrpcServerUtils.GetServerCredentials(arguments.Certificate,
                                                     arguments.PrivateKeyFile,
                                                     arguments.EnforceMutualTls);

            var oneGb = (int)Math.Pow(1024, 3);

            IList <ChannelOption> channelOptions = GrpcServerUtils.CreateChannelOptions(oneGb);

            var server =
                new Grpc.Core.Server(channelOptions)
            {
                Services =
                {
                    QualityVerificationGrpc.BindService(wuVerificationServiceImpl),
                    Health.BindService(healthService)
                },
                Ports =
                {
                    new ServerPort(arguments.HostName, arguments.Port, serverCredentials)
                }
            };

            server.Start();

            _msg.InfoFormat("Service is listening on host {0}, port {1}.", arguments.HostName,
                            arguments.Port);

            return(new StartedGrpcServer(server, health));
        }
コード例 #16
0
        public async Task PublishAsync_Watch_ChangingStatus()
        {
            // Arrange
            var healthService     = new HealthServiceImpl();
            var publisher         = new GrpcHealthChecksPublisher(healthService);
            var responseStream    = new TestServerStreamWriter <HealthCheckResponse>();
            var cts               = new CancellationTokenSource();
            var serverCallContext = new TestServerCallContext(DateTime.MinValue, cts.Token);

            // Act 1
            var call = healthService.Watch(new HealthCheckRequest {
                Service = ""
            }, responseStream, serverCallContext);

            // Assert 1
            await TestHelpers.AssertIsTrueRetryAsync(() => responseStream.Responses.Count == 1, "Unexpected response count.");

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.ServiceUnknown, responseStream.Responses.Last().Status);

            // Act 2
            await publisher.PublishAsync(CreateSimpleHealthReport(HealthStatus.Healthy), CancellationToken.None);

            // Assert 2
            await TestHelpers.AssertIsTrueRetryAsync(() => responseStream.Responses.Count == 2, "Unexpected response count.");

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, responseStream.Responses.Last().Status);

            // Act 3
            await publisher.PublishAsync(CreateSimpleHealthReport(HealthStatus.Degraded), CancellationToken.None);

            // Act 3
            await TestHelpers.AssertIsTrueRetryAsync(() => responseStream.Responses.Count == 2, "Unexpected response count.");

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, responseStream.Responses.Last().Status);

            // Act 4
            await publisher.PublishAsync(CreateSimpleHealthReport(HealthStatus.Unhealthy), CancellationToken.None);

            // Act 4
            await TestHelpers.AssertIsTrueRetryAsync(() => responseStream.Responses.Count == 3, "Unexpected response count.");

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, responseStream.Responses.Last().Status);

            // End call
            cts.Cancel();
            await call.DefaultTimeout();

            // Act 4
            await publisher.PublishAsync(CreateSimpleHealthReport(HealthStatus.Healthy), CancellationToken.None);

            // Act 4
            await TestHelpers.AssertIsTrueRetryAsync(() => responseStream.Responses.Count == 3, "Unexpected response count.");

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, responseStream.Responses.Last().Status);
        }
コード例 #17
0
        public async Task PublishAsync_CheckWithFilter_ChangingStatusBasedOnFilter()
        {
            // Arrange
            var healthService = new HealthServiceImpl();
            var publisher     = CreatePublisher(
                healthService,
                o =>
            {
                o.Services.MapService("", result => !result.Tags.Contains("exclude"));
            });

            HealthCheckResponse response;

            // Act 1
            var ex = await ExceptionAssert.ThrowsAsync <RpcException>(() => healthService.Check(new HealthCheckRequest {
                Service = ""
            }, context: null));

            // Assert 1
            Assert.AreEqual(StatusCode.NotFound, ex.StatusCode);

            // Act 2
            var report = CreateSimpleHealthReport(
                new HealthResult("", HealthStatus.Healthy),
                new HealthResult("other", HealthStatus.Healthy, new[] { "exclude" }));
            await publisher.PublishAsync(report, CancellationToken.None);

            response = await healthService.Check(new HealthCheckRequest { Service = "" }, context : null);

            // Assert 2
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, response.Status);

            // Act 3
            report = CreateSimpleHealthReport(
                new HealthResult("", HealthStatus.Healthy),
                new HealthResult("other", HealthStatus.Unhealthy, new[] { "exclude" }));
            await publisher.PublishAsync(report, CancellationToken.None);

            response = await healthService.Check(new HealthCheckRequest { Service = "" }, context : null);

            // Act 3
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving, response.Status);

            // Act 4
            report = CreateSimpleHealthReport(
                new HealthResult("", HealthStatus.Unhealthy),
                new HealthResult("other", HealthStatus.Unhealthy, new[] { "exclude" }));
            await publisher.PublishAsync(report, CancellationToken.None);

            response = await healthService.Check(new HealthCheckRequest { Service = "" }, context : null);

            // Act 4
            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.NotServing, response.Status);
        }
コード例 #18
0
        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", ""));
        }
コード例 #19
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"));
        }
コード例 #20
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"));
        }
コード例 #21
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);
        }
コード例 #22
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", ""));
        }
コード例 #23
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"));
        }
コード例 #24
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"));
        }
コード例 #25
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"));
        }
コード例 #26
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"));
        }
コード例 #27
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"));
        }
コード例 #28
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"));
        }
コード例 #29
0
        private static Grpc.Core.Server StartGrpcServer(
            MicroserverArguments arguments,
            [NotNull] QualityVerificationGrpcImpl verificationServiceImpl,
            [NotNull] HealthServiceImpl healthService,
            [NotNull] LoadReportingGrpcImpl loadReporting)
        {
            var services = new List <ServerServiceDefinition>(
                new[]
            {
                QualityVerificationGrpc.BindService(verificationServiceImpl),
                Health.BindService(healthService),
                LoadReportingGrpc.BindService(loadReporting)
            });

            return(StartGrpcServer(services, arguments));
        }
コード例 #30
0
        public void CanSetEmptyServiceNameHealth()
        {
            HealthServiceImpl healthImpl = new HealthServiceImpl();

            IServiceHealth health = new ServiceHealth(healthImpl);

            health.SetStatus(string.Empty, true);

            Task <HealthCheckResponse> response = healthImpl.Check(
                new HealthCheckRequest(), null);

            Assert.AreEqual(HealthCheckResponse.Types.ServingStatus.Serving,
                            response.Result.Status);

            Assert.IsFalse(health.IsAnyServiceUnhealthy());
        }
コード例 #31
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);
            }
        }
コード例 #32
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));
        }
コード例 #33
0
        public PluginServer(string listeningHost, int listeningPort, int appProtoVersion,
                            ITLSConfig tlsConfig = null)
        {
            ListeningHost      = listeningHost;
            ListeningPort      = listeningPort;
            AppProtocolVersion = appProtoVersion;

            _server      = new Server();
            _health      = new HealthServiceImpl();
            _serverCreds = tlsConfig == null
                ? ServerCredentials.Insecure
                : TLSConfig.ToCredentials(tlsConfig);

            _serverPort = new ServerPort(ListeningHost, ListeningPort, _serverCreds);
            Server.Ports.Add(_serverPort);
            Server.Services.Add(Grpc.Health.V1.Health.BindService(_health));

            // Based on:
            //  https://github.com/hashicorp/go-plugin/blob/f444068e8f5a19853177f7aa0aea7e7d95b5b528/server.go#L257
            //  https://github.com/hashicorp/go-plugin/blob/f444068e8f5a19853177f7aa0aea7e7d95b5b528/server.go#L327
            if (tlsConfig != null)
            {
                _ServerCertificate = Convert.ToBase64String(tlsConfig.ServerCertRaw);
                _HandshakeInfo     = string.Join("|",
                                                 CoreProtocolVersion,
                                                 AppProtocolVersion,
                                                 NetworkType,
                                                 NetworkAddres,
                                                 ConnectionProtocol,
                                                 _ServerCertificate
                                                 );
            }
            else
            {
                _HandshakeInfo = string.Join("|",
                                             CoreProtocolVersion,
                                             AppProtocolVersion,
                                             NetworkType,
                                             NetworkAddres,
                                             ConnectionProtocol
                                             );
            }
        }
コード例 #34
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;
        }
コード例 #35
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;
        }
コード例 #36
0
        /// <summary>
        /// Starts the grpc server, binds the <see cref="QualityVerificationGrpcImpl"/> together
        /// with the <see cref="IServiceHealth"/> implementation and returns a handle for both.
        /// </summary>
        /// <param name="arguments">The microserver command line / config arguments.</param>
        /// <param name="inputsFactory">The factory method that creates the
        /// <see cref="IBackgroundVerificationInputs"/> instance. If no factory is proveded, only
        /// stand-alone verification (such as XML) can be used.</param>
        /// <param name="markUnhealthyOnExceptions"></param>
        /// <returns></returns>
        public static StartedGrpcServer <QualityVerificationGrpcImpl> StartVerificationServer(
            [NotNull] MicroserverArguments arguments,
            [CanBeNull] Func <VerificationRequest, IBackgroundVerificationInputs> inputsFactory,
            bool markUnhealthyOnExceptions)
        {
            var healthService = new HealthServiceImpl();

            IServiceHealth health = new ServiceHealth(healthService);

            LoadReportingGrpcImpl loadReporting = new LoadReportingGrpcImpl();

            ServiceLoad serviceLoad = new ServiceLoad(arguments.MaxParallel);

            loadReporting.AllowMonitoring(nameof(QualityVerificationGrpc), serviceLoad);

            var verificationServiceImpl =
                new QualityVerificationGrpcImpl(inputsFactory,
                                                arguments.MaxParallel)
            {
                CurrentLoad = serviceLoad
            };

            if (markUnhealthyOnExceptions)
            {
                verificationServiceImpl.Health = health;
            }

            health.SetStatus(verificationServiceImpl.GetType(), true);

            Grpc.Core.Server server =
                StartGrpcServer(arguments, verificationServiceImpl, healthService, loadReporting);

            _msg.InfoFormat("Service is listening on host {0}, port {1}.", arguments.HostName,
                            arguments.Port);

            return(new StartedGrpcServer <QualityVerificationGrpcImpl>(
                       server, verificationServiceImpl, health));
        }
コード例 #37
0
 private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string service)
 {
     return impl.Check(new HealthCheckRequest { Service = service }, null).Result.Status;
 }
コード例 #38
0
        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));
        }
コード例 #39
0
 private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string host, string service)
 {
     return impl.Check(null, HealthCheckRequest.CreateBuilder().SetHost(host).SetService(service).Build()).Result.Status;
 }