Skip to content

Commit

Permalink
Update Discovery documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
bart-vmware committed Oct 7, 2024
1 parent fc96828 commit 5f9afde
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 31 deletions.
22 changes: 11 additions & 11 deletions api/v4/discovery/discovering-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<OrderModel?> GetOrderByIdAsync(
Expand All @@ -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();
Expand All @@ -38,7 +38,7 @@ builder.Services.AddHttpClient<OrderService>().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}")]
Expand All @@ -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());
```

Expand All @@ -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<OrderModel?> GetOrderByIdAsync(
Expand All @@ -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<ServiceInstancesResolver>();
builder.Services.AddSingleton<ILoadBalancer, RandomLoadBalancer>();
builder.Services.AddSingleton<DiscoveryHttpClientHandler>();
Expand All @@ -95,7 +95,7 @@ builder.Services.AddSingleton<FortuneService>();
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();

Expand Down Expand Up @@ -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
{
Expand All @@ -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<OrderService>().AddServiceDiscovery<RoundRobinLoadBalancer>();
```

Expand All @@ -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<Uri> ResolveServiceInstanceAsync(Uri requestUri,
Expand All @@ -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<ServiceInstancesResolver>();
builder.Services.AddSingleton<ChooseFirstLoadBalancer>();

Expand Down
2 changes: 1 addition & 1 deletion api/v4/discovery/hashicorp-consul.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions api/v4/discovery/initialize-discovery-client.md
Original file line number Diff line number Diff line change
@@ -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:

Expand All @@ -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 |

Expand All @@ -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.
Expand All @@ -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
Expand Down
31 changes: 16 additions & 15 deletions api/v4/discovery/netflix-eureka.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<EurekaApplicationInfoManager>();
appManager.UpdateInstance(newStatus: null, newOverriddenStatus: null,
newMetadata: new Dictionary<string, string?>(appManager.Instance.Metadata)
Expand Down Expand Up @@ -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<HttpResponseMessage> 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<ExtraRequestHeaderDelegatingHandler>();

Expand All @@ -254,6 +246,15 @@ builder.Services.Configure<HttpClientFactoryOptions>("Eureka", options =>
handlerBuilder.Services.GetRequiredService<ExtraRequestHeadersDelegatingHandler>()));
});

public sealed class ExtraRequestHeaderDelegatingHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("X-Example", "ExampleValue");
return base.SendAsync(request, cancellationToken);
}
}
```

> [!NOTE]
Expand Down

0 comments on commit 5f9afde

Please sign in to comment.