From 5f9afde3717220b19f2a5da9145d4310b888af4b Mon Sep 17 00:00:00 2001 From: Bart Koelman <104792814+bart-vmware@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:39:29 +0200 Subject: [PATCH] Update Discovery documentation --- api/v4/discovery/discovering-services.md | 22 ++++++------- api/v4/discovery/hashicorp-consul.md | 2 +- .../discovery/initialize-discovery-client.md | 8 ++--- api/v4/discovery/netflix-eureka.md | 31 ++++++++++--------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/api/v4/discovery/discovering-services.md b/api/v4/discovery/discovering-services.md index e942934..cb36e8c 100644 --- a/api/v4/discovery/discovering-services.md +++ b/api/v4/discovery/discovering-services.md @@ -14,7 +14,7 @@ extension method from the `Steeltoe.Discovery.HttpClients` NuGet package to acti > which uses randomized selection of service instances. For example, consider the following typed client: -```c# +```csharp public sealed class OrderService(HttpClient httpClient) { public async Task GetOrderByIdAsync( @@ -29,7 +29,7 @@ public sealed class OrderService(HttpClient httpClient) This typed client can be configured to use service discovery. Add the following code to `Program.cs` to rewrite the `https://ordering-api` part to a service instance obtained from Eureka. -```c# +```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddEurekaDiscoveryClient(); @@ -38,7 +38,7 @@ builder.Services.AddHttpClient().AddServiceDiscovery(); With the above code in place, you can inject `OrderService` in your MVC controller, for example: -```c# +```csharp public sealed class OrdersController(OrderService orderService) : Controller { [HttpGet("{orderId}")] @@ -58,7 +58,7 @@ which intercepts requests and rewrites the scheme/host/port with the values obta To use service discovery for *all* `HttpClient` instances, use the following code: -```c# +```csharp builder.Services.ConfigureHttpClientDefaults(clientBuilder => clientBuilder.AddServiceDiscovery()); ``` @@ -68,7 +68,7 @@ Another way to use service discovery is to use the Steeltoe `DiscoveryHttpClient The variant of `OrderService` below creates a new `HttpClient` from the injected handler: -```c# +```csharp public sealed class OrderService(DiscoveryHttpClientHandler handler) { public async Task GetOrderByIdAsync( @@ -83,7 +83,7 @@ public sealed class OrderService(DiscoveryHttpClientHandler handler) To register the handler, add the following code to `Program.cs`: -```c# +```csharp builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -95,7 +95,7 @@ builder.Services.AddSingleton(); In the event the provided HTTP support does not serve your needs, you can always make lookups directly against the registered collection of `IDiscoveryClient`s, for example: -```c# +```csharp var builder = WebApplication.CreateBuilder(args); builder.Services.AddEurekaDiscoveryClient(); @@ -133,7 +133,7 @@ which is useful for discovery clients that do not provide their own caching (suc To activate caching, use the code below: -```c# +```csharp builder.Services.AddDistributedMemoryCache(); builder.Services.AddSingleton(new DistributedCacheEntryOptions { @@ -156,7 +156,7 @@ by discovery clients for the given friendly name. To use this load balancer in service discovery, pass it to the `AddServiceDiscovery()` method: -```c# +```csharp builder.Services.AddHttpClient().AddServiceDiscovery(); ``` @@ -170,7 +170,7 @@ If the provided load balancer implementations do not suit your needs, you can cr The following example shows a load balancer that always returns the first service instance: -```c# +```csharp public sealed class ChooseFirstLoadBalancer(ServiceInstancesResolver resolver) : ILoadBalancer { public async Task ResolveServiceInstanceAsync(Uri requestUri, @@ -192,7 +192,7 @@ public sealed class ChooseFirstLoadBalancer(ServiceInstancesResolver resolver) : A custom load balancer needs to be added to the service container manually, because Steeltoe can't know its lifetime. Add the following code to `Program.cs` to activate the custom load balancer defined above: -```c# +```csharp builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/api/v4/discovery/hashicorp-consul.md b/api/v4/discovery/hashicorp-consul.md index 9539a9d..a1e021f 100644 --- a/api/v4/discovery/hashicorp-consul.md +++ b/api/v4/discovery/hashicorp-consul.md @@ -11,7 +11,7 @@ The client fetches no service registrations until asked for, and doesn't cache t To use this discovery client, add a NuGet package reference to `Steeltoe.Discovery.Consul` and initialize it from your `Program.cs`: -```c# +```csharp var builder = WebApplication.CreateBuilder(args); // Steeltoe: Add service discovery client for Consul. diff --git a/api/v4/discovery/initialize-discovery-client.md b/api/v4/discovery/initialize-discovery-client.md index 4d071d2..18a08b3 100644 --- a/api/v4/discovery/initialize-discovery-client.md +++ b/api/v4/discovery/initialize-discovery-client.md @@ -1,7 +1,7 @@ # Discovery clients This section describes how to activate the Steeltoe discovery client(s), which is a prerequisite for resolving friendly names. -Your app can use multiple clients but is limited to a single instance per type. +Your app can use multiple clients, but is limited to a single instance per server type. Fundamentally, several things need to happen: @@ -17,7 +17,7 @@ Each package also includes all the relevant dependencies. | Package | Description | | --- | --- | -| `Steeltoe.Discovery.Configuration` | Register/query app instances stored in .NET configuration | +| `Steeltoe.Discovery.Configuration` | Query app instances stored in .NET configuration | | `Steeltoe.Discovery.Consul` | Use [HashiCorp Consul](https://www.consul.io/) server | | `Steeltoe.Discovery.Eureka` | Use [Spring Cloud Eureka](https://projects.spring.io/spring-cloud/docs/1.0.3/spring-cloud.html#spring-cloud-eureka-server) server | @@ -26,7 +26,7 @@ Each package also includes all the relevant dependencies. After installing the NuGet package(s), the next step is to add the Steeltoe discovery client(s) to the service container. Update your `Program.cs` as shown below: -```c# +```csharp var builder = WebApplication.CreateBuilder(args); // Steeltoe: Add service discovery clients for Consul, Eureka, and/or configuration-based. @@ -38,7 +38,7 @@ var app = builder.Build(); ``` > [!TIP] -> Alternatively, `builder.AddSteeltoe();` (Steeltoe Bootstrap Auto Configuration) can be used, which uses reflection to determine +> Alternatively, `builder.AddSteeltoe()` (Steeltoe Bootstrap Auto Configuration) can be used, which uses reflection to determine > which discovery assemblies are loaded, adding the appropriate clients automatically. ## Client configuration diff --git a/api/v4/discovery/netflix-eureka.md b/api/v4/discovery/netflix-eureka.md index fe3c04d..95c41e7 100644 --- a/api/v4/discovery/netflix-eureka.md +++ b/api/v4/discovery/netflix-eureka.md @@ -10,7 +10,7 @@ sending periodic heartbeats to the Eureka server, and also periodically fetching To use this discovery client, add a NuGet package reference to `Steeltoe.Discovery.Eureka` and initialize it from your `Program.cs`: -```c# +```csharp var builder = WebApplication.CreateBuilder(args); // Steeltoe: Add service discovery client for Eureka. @@ -185,7 +185,7 @@ You can add additional metadata to instance registrations by using the configura The key/value pairs you supply there are added to the service registration and become accessible in remote clients. When the metadata varies over time, depending on contextual information, it can be updated from code as well: -```c# +```csharp var appManager = app.Services.GetRequiredService(); appManager.UpdateInstance(newStatus: null, newOverriddenStatus: null, newMetadata: new Dictionary(appManager.Instance.Metadata) @@ -226,24 +226,16 @@ or: > [!NOTE] > To support certificate rotation, the configuration keys and the files on disk are automatically monitored for changes. +> [!TIP] +> A single certificate can be shared with both Config Server and Eureka, by using the key "Certificates" instead of "Certificates:Eureka". + ### Using custom HTTP headers -The communication with Eureka server uses the `HttpClientFactory` [pattern](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests), +The communication with Eureka server uses the `HttpClientFactory` [pattern](https://learn.microsoft.com/dotnet/architecture/microservices/implement-resilient-applications/use-httpclientfactory-to-implement-resilient-http-requests), which makes it aware of DNS changes over time and enables to tweak the handler pipeline. To send a custom HTTP header with every request, create a `DelegatingHandler` and add it to the pipeline: -```c# -public sealed class ExtraRequestHeaderDelegatingHandler : DelegatingHandler -{ - protected override Task SendAsync( - HttpRequestMessage request, CancellationToken cancellationToken) - { - request.Headers.Add("X-Example", "ExampleValue"); - return base.SendAsync(request, cancellationToken); - } -} - -// In Program.cs: +```csharp builder.Services.AddEurekaDiscoveryClient(); builder.Services.AddTransient(); @@ -254,6 +246,15 @@ builder.Services.Configure("Eureka", options => handlerBuilder.Services.GetRequiredService())); }); +public sealed class ExtraRequestHeaderDelegatingHandler : DelegatingHandler +{ + protected override Task SendAsync( + HttpRequestMessage request, CancellationToken cancellationToken) + { + request.Headers.Add("X-Example", "ExampleValue"); + return base.SendAsync(request, cancellationToken); + } +} ``` > [!NOTE]