Skip to content

Commit

Permalink
Microsoft.Extensions.ServiceDiscovery support (#317)
Browse files Browse the repository at this point in the history
* Microsoft.Extensions.ServiceDiscovery  support

* comment fix

* comment fix
  • Loading branch information
ZUOXIANGE authored Sep 20, 2024
1 parent 59b02d3 commit 60de3cb
Show file tree
Hide file tree
Showing 11 changed files with 433 additions and 8 deletions.
11 changes: 9 additions & 2 deletions nacos-sdk-csharp.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
# Visual Studio Version 17
VisualStudioVersion = 17.11.35303.130
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C473C3A7-1B44-4E1F-83C0-745AD0566FE9}"
EndProject
Expand Down Expand Up @@ -47,6 +47,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.zh-cn.md = README.zh-cn.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nacos.Microsoft.Extensions.ServiceDiscovery", "src\Nacos.Microsoft.Extensions.ServiceDiscovery\Nacos.Microsoft.Extensions.ServiceDiscovery.csproj", "{46FDA099-A266-4E7B-9B5B-496575A54CCD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -109,6 +111,10 @@ Global
{CA0A661F-01D5-4DF7-9CD0-0399F89A8D47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA0A661F-01D5-4DF7-9CD0-0399F89A8D47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA0A661F-01D5-4DF7-9CD0-0399F89A8D47}.Release|Any CPU.Build.0 = Release|Any CPU
{46FDA099-A266-4E7B-9B5B-496575A54CCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46FDA099-A266-4E7B-9B5B-496575A54CCD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46FDA099-A266-4E7B-9B5B-496575A54CCD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46FDA099-A266-4E7B-9B5B-496575A54CCD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -128,6 +134,7 @@ Global
{CEE5E43E-F4E1-4E46-9B41-ABCBECDDEA63} = {CFFCAA8B-3562-420B-AA8B-C525CC1ECD78}
{7C20F5FB-33D4-460A-86F4-FC42122FA543} = {C473C3A7-1B44-4E1F-83C0-745AD0566FE9}
{CA0A661F-01D5-4DF7-9CD0-0399F89A8D47} = {25B1A184-1541-4F4E-A151-24A47CC08F34}
{46FDA099-A266-4E7B-9B5B-496575A54CCD} = {C473C3A7-1B44-4E1F-83C0-745AD0566FE9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A1C5215E-0E70-4C04-B21E-5209BCF32472}
Expand Down
3 changes: 2 additions & 1 deletion samples/App3/App3.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Nacos.AspNetCore\Nacos.AspNetCore.csproj" />
<ProjectReference Include="..\..\src\Nacos.Microsoft.Extensions.ServiceDiscovery\Nacos.Microsoft.Extensions.ServiceDiscovery.csproj" />
</ItemGroup>
</Project>
15 changes: 14 additions & 1 deletion samples/App3/Controllers/NamingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
public class NamingController : ControllerBase
{
private readonly Nacos.V2.INacosNamingService _client;
private readonly IHttpClientFactory _httpClientFactory;

public NamingController(Nacos.V2.INacosNamingService client)
public NamingController(Nacos.V2.INacosNamingService client, IHttpClientFactory httpClientFactory)
{
_client = client;
_httpClientFactory = httpClientFactory;
}

// GET n/g
Expand Down Expand Up @@ -102,6 +104,17 @@ public async Task<string> GetServicesOfServer()
return res ?? "GetServicesOfServer";
}

// GET n/sd
[HttpGet("sd")]
public async Task<string> ServiceDiscovery()
{
var client = _httpClientFactory.CreateClient("app1");
var response = await client.GetAsync("/api/values").ConfigureAwait(false);
var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

return res;
}

// GET n/sub
[HttpGet("sub")]
public async Task<string> Subscribe()
Expand Down
24 changes: 20 additions & 4 deletions samples/App3/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@
x.Namespace = "cs";
});

// Microsoft.Extensions.ServiceDiscovery
builder.Services.AddServiceDiscovery(o =>
{
o.RefreshPeriod = TimeSpan.FromSeconds(60);
})
.AddConfigurationServiceEndpointProvider()
.AddNacosSrvServiceEndpointProvider();

builder.Services.ConfigureHttpClientDefaults(static http =>
{
http.AddServiceDiscovery();
});

// 使用IHttpClientFactory
builder.Services.AddHttpClient("app1", cfg =>
{
cfg.BaseAddress = new Uri("http://app1");
});

builder.Services.AddControllers();

var app = builder.Build();
Expand All @@ -46,9 +65,6 @@

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.MapControllers();

app.Run("http://*:9632");
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="../../build/version.props" />

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>nacos-sdk-csharp.Extensions.ServiceDiscovery</PackageId>
<VersionPrefix>$(NugetVersion)</VersionPrefix>
<VersionSuffix></VersionSuffix>
<Authors>nacos-sdk-csharp Contributors</Authors>
<Description>nacos csharp sdk</Description>
<PackageTags>nacos,csharp,sdk,servicediscovery</PackageTags>
<PackageProjectUrl>https://github.com/nacos-group/nacos-sdk-csharp</PackageProjectUrl>
<RepositoryUrl>https://github.com/nacos-group/nacos-sdk-csharp</RepositoryUrl>
<ProjectUrl>https://github.com/nacos-group/nacos-sdk-csharp</ProjectUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReleaseNotes>
</PackageReleaseNotes>
</PropertyGroup>

<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

<ItemGroup>
<None Include="../../LICENSE" Pack="true" Visible="false" PackagePath="" />
<None Include="README.md" Pack="true" Visible="false" PackagePath="" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="8.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Nacos\Nacos.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma warning disable SA1200
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.ServiceDiscovery;
#pragma warning restore SA1200

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.Hosting;

public static class NacosServiceDiscoveryExtensions
{
public static IServiceCollection AddNacosSrvServiceEndpointProvider(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);

services.AddServiceDiscoveryCore();
services.AddSingleton<IServiceEndpointProviderFactory, NacosServiceEndPointProviderFactory>();
return services;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma warning disable SA1200
using Nacos.Microsoft.Extensions.ServiceDiscovery;
using System.Net;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.ServiceDiscovery;
using Nacos.V2;
#pragma warning restore SA1200

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.Hosting;

/// <summary>
/// NacosServiceEndpointProvider
/// </summary>
/// <param name="query">query</param>
/// <param name="hostName">hostName</param>
/// <param name="options">options</param>
/// <param name="logger">logger</param>
/// <param name="namingService">namingService</param>
/// <param name="timeProvider">timeProvider</param>
internal sealed partial class NacosServiceEndpointProvider(
ServiceEndpointQuery query,
string hostName,
IOptionsMonitor<NacosServiceEndpointProviderOptions> options,
ILogger<NacosServiceEndpointProvider> logger,
INacosNamingService namingService,
TimeProvider timeProvider) : NacosServiceEndpointProviderBase(query, logger, timeProvider), IHostNameFeature
{
protected override double RetryBackOffFactor => options.CurrentValue.RetryBackOffFactor;

protected override TimeSpan MinRetryPeriod => options.CurrentValue.MinRetryPeriod;

protected override TimeSpan MaxRetryPeriod => options.CurrentValue.MaxRetryPeriod;

protected override TimeSpan DefaultRefreshPeriod => options.CurrentValue.DefaultRefreshPeriod;

string IHostNameFeature.HostName => hostName;

/// <inheritdoc/>
public override string ToString() => "Nacos";

protected override async Task ResolveAsyncCore()
{
var endpoints = new List<ServiceEndpoint>();
var ttl = DefaultRefreshPeriod;
Log.AddressQuery(logger, ServiceName, hostName);
var selectInstances = await namingService.SelectInstances(hostName, true).ConfigureAwait(false);
foreach (var instance in selectInstances)
{
var ipAddress = new IPAddress(instance.Ip.Split('.').Select(a => Convert.ToByte(a)).ToArray());
var ipPoint = new IPEndPoint(ipAddress, instance.Port);
var serviceEndpoint = ServiceEndpoint.Create(ipPoint);
serviceEndpoint.Features.Set<IServiceEndpointProvider>(this);
if (options.CurrentValue.ShouldApplyHostNameMetadata(serviceEndpoint))
{
serviceEndpoint.Features.Set<IHostNameFeature>(this);
}

endpoints.Add(serviceEndpoint);
}

if (endpoints.Count == 0)
{
throw new InvalidOperationException($"No records were found for service '{ServiceName}' ( name: '{hostName}').");
}

SetResult(endpoints, ttl);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma warning disable SA1200
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.ServiceDiscovery;
using Nacos.Microsoft.Extensions.ServiceDiscovery;
using Nacos.V2;
#pragma warning restore SA1200

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.Hosting;

/// <summary>
/// NacosServiceEndPointProviderFactory
/// </summary>
/// <param name="options">options</param>
/// <param name="logger">logger</param>
/// <param name="timeProvider">timeProvider</param>
/// <param name="namingService">nacos namingService</param>
internal sealed partial class NacosServiceEndPointProviderFactory(
IOptionsMonitor<NacosServiceEndpointProviderOptions> options,
ILogger<NacosServiceEndpointProvider> logger,
TimeProvider timeProvider,
INacosNamingService namingService) : IServiceEndpointProviderFactory
{
/// <summary>
/// Tries to create an <see cref="T:Microsoft.Extensions.ServiceDiscovery.IServiceEndpointProvider" /> instance for the specified <paramref name="query" />.
/// </summary>
/// <param name="query">The service to create the provider for.</param>
/// <param name="provider">The provider.</param>
/// <returns><see langword="true" /> if the provider was created, <see langword="false" /> otherwise.</returns>
public bool TryCreateProvider(ServiceEndpointQuery query, [NotNullWhen(true)] out IServiceEndpointProvider? provider)
{
provider = new NacosServiceEndpointProvider(query, query.ServiceName, options, logger, namingService, timeProvider);

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma warning disable SA1200
using Microsoft.Extensions.Logging;
#pragma warning restore SA1200

namespace Nacos.Microsoft.Extensions.ServiceDiscovery;

/// <summary>
/// log base
/// </summary>
internal partial class NacosServiceEndpointProviderBase
{
/// <summary>
/// log
/// </summary>
internal static partial class Log
{
[LoggerMessage(1, LogLevel.Trace, "Resolving endpoints for service '{ServiceName}' using host lookup for name '{RecordName}'.", EventName = "AddressQuery")]
public static partial void AddressQuery(ILogger logger, string serviceName, string recordName);

[LoggerMessage(2, LogLevel.Debug, "Skipping endpoint resolution for service '{ServiceName}': '{Reason}'.", EventName = "SkippedResolution")]
public static partial void SkippedResolution(ILogger logger, string serviceName, string reason);
}
}
Loading

0 comments on commit 60de3cb

Please sign in to comment.