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(); }
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)); }
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); }
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(); }
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(); }
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); }
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)); }
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)); }
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))); }
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); }
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)); }
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); }
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 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]); }
/// <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)); }
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); }
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); }
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 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")); }
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")); }
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); }
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")); }
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")); }
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")); }
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")); }
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)); }
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()); }
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); } }
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)); }
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 ); } }
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; }
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; }
/// <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)); }
private static HealthCheckResponse.Types.ServingStatus GetStatusHelper(HealthServiceImpl impl, string service) { return impl.Check(new HealthCheckRequest { Service = service }, null).Result.Status; }
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)); }
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; }