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(); }
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(); }
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 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")); }
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 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 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); }
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")); }
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 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); }
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")); }
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(); }
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); } }
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(); }
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]); }
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); }
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 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 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; } }
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; }
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); } }
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 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); } }
// 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); });
// 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)); }