From 50411d86660375adf05846bdad34afeed14a5c6a Mon Sep 17 00:00:00 2001 From: zhenlei520 Date: Wed, 7 Dec 2022 18:03:58 +0800 Subject: [PATCH] refactor: Refactor Caller.Dapr --- .../CallerOptionsExtensions.cs | 10 +- .../DefaultCallerProvider.cs | 29 +++++ .../ICallerProvider.cs | 15 +++ ...a.Contrib.Service.Caller.DaprClient.csproj | 1 + .../_Imports.cs | 2 + .../DefaultCallerProviderTest.cs | 117 ++++++++++++++++++ .../_Imports.cs | 3 + .../AutomaticCallerTest.cs | 14 +++ .../Callers/DaprCaller.cs | 2 + .../StringExtensions.cs | 4 +- .../Masa.Utils.Extensions.DotNet/_Imports.cs | 1 + 11 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/DefaultCallerProvider.cs create mode 100644 src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/ICallerProvider.cs create mode 100644 src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultCallerProviderTest.cs diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/CallerOptionsExtensions.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/CallerOptionsExtensions.cs index fd115e15f..b28284a50 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/CallerOptionsExtensions.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/CallerOptionsExtensions.cs @@ -25,17 +25,15 @@ public static DefaultDaprClientBuilder UseDapr(this CallerOptions callerOptions, builder.Configure?.Invoke(daprClientBuilder); }); + callerOptions.Services.TryAddSingleton(); callerOptions.Services.AddOptions(); AddCallerExtensions.AddCaller(callerOptions, name, serviceProvider => { - var daprOptions = serviceProvider.GetRequiredService>().CurrentValue; string appId = builder.AppId; - if (daprOptions.AppPort > 0 && daprOptions.IsIncompleteAppId()) - { - appId = $"{appId}{daprOptions.AppIdDelimiter}{daprOptions.AppIdSuffix ?? NetworkUtils.GetPhysicalAddress()}"; - } - var daprCaller = new DaprCaller(serviceProvider, name, appId); + var daprCaller = new DaprCaller(serviceProvider, + name, + serviceProvider.GetRequiredService().CompletionAppId(appId)); return daprCaller; }); return new DefaultDaprClientBuilder(callerOptions.Services, name); diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/DefaultCallerProvider.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/DefaultCallerProvider.cs new file mode 100644 index 000000000..479a075bc --- /dev/null +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/DefaultCallerProvider.cs @@ -0,0 +1,29 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Service.Caller.DaprClient; + +public class DefaultCallerProvider : ICallerProvider +{ + private readonly IOptionsMonitor _daprOptions; + private readonly IConfiguration? _configuration; + + public DefaultCallerProvider(IOptionsMonitor daprOptions, + IConfiguration? configuration = null, + IMasaConfiguration? masaConfiguration = null) + { + _daprOptions = daprOptions; + _configuration = masaConfiguration?.Local ?? configuration; + } + + public string CompletionAppId(string appId) + { + var daprOptions = _daprOptions.CurrentValue; + if (daprOptions.AppPort > 0 && daprOptions.IsIncompleteAppId()) + appId = $"{appId}{daprOptions.AppIdDelimiter}{daprOptions.AppIdSuffix ?? NetworkUtils.GetPhysicalAddress()}"; + var value = _configuration?.GetSection(appId).Value; + if (value.IsNullOrWhiteSpace()) return appId; + + return value; + } +} diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/ICallerProvider.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/ICallerProvider.cs new file mode 100644 index 000000000..f8c8cdcd6 --- /dev/null +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/ICallerProvider.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Masa.Contrib.Service.Caller.DaprClient; + +public interface ICallerProvider +{ + /// + /// According to the dapr appid obtained by the service id + /// when the dapr appid of the specified service does not exist in the configuration, return the service id as the dapr appid + /// + /// service appid + /// + string CompletionAppId(string appId); +} diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/Masa.Contrib.Service.Caller.DaprClient.csproj b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/Masa.Contrib.Service.Caller.DaprClient.csproj index 2caa74ecd..947f95999 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/Masa.Contrib.Service.Caller.DaprClient.csproj +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/Masa.Contrib.Service.Caller.DaprClient.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/_Imports.cs b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/_Imports.cs index 0e68630ec..27da6dd46 100644 --- a/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/_Imports.cs +++ b/src/Contrib/Service/Caller/Masa.Contrib.Service.Caller.DaprClient/_Imports.cs @@ -2,10 +2,12 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. global using Dapr.Client; +global using Masa.BuildingBlocks.Configuration; global using Masa.BuildingBlocks.Development.DaprStarter; global using Masa.BuildingBlocks.Service.Caller; global using Masa.BuildingBlocks.Service.Caller.Options; global using Masa.Contrib.Service.Caller.DaprClient.Options; +global using Microsoft.Extensions.Configuration; global using Microsoft.Extensions.DependencyInjection; global using Microsoft.Extensions.DependencyInjection.Extensions; global using Microsoft.Extensions.Logging; diff --git a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultCallerProviderTest.cs b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultCallerProviderTest.cs new file mode 100644 index 000000000..8955518d5 --- /dev/null +++ b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/DefaultCallerProviderTest.cs @@ -0,0 +1,117 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +using Microsoft.Extensions.Configuration; + +namespace Masa.Contrib.Service.Caller.Tests; + +[TestClass] +public class DefaultCallerProviderTest +{ + [DataTestMethod] + [DataRow(5000, "test", "appid", "appid-test")] + public void TestCompletionAppId(int appPort, string appIdSuffix, string appId, string expectedAppId) + { + var services = new ServiceCollection(); + services.Configure(options => + { + options.AppPort = (ushort)appPort; + options.AppIdSuffix = appIdSuffix; + }); + var serviceProvider = services.BuildServiceProvider(); + var daprOptions = serviceProvider.GetRequiredService>(); + + var callerProvider = new DefaultCallerProvider(daprOptions); + string actualAppId = callerProvider.CompletionAppId(appId); + Assert.AreEqual(expectedAppId, actualAppId); + } + + [TestMethod] + public void TestCompletionAppId2() + { + string appId = "appid"; + string expectedAppId = $"{appId}-{NetworkUtils.GetPhysicalAddress()}"; + var services = new ServiceCollection(); + services.Configure(options => + { + options.AppPort = 5000; + }); + var serviceProvider = services.BuildServiceProvider(); + var daprOptions = serviceProvider.GetRequiredService>(); + + var callerProvider = new DefaultCallerProvider(daprOptions); + string actualAppId = callerProvider.CompletionAppId(appId); + Assert.AreEqual(expectedAppId, actualAppId); + } + + [TestMethod] + public void TestCompletionAppId3() + { + string appId = "appid"; + string expectedAppId = $"{appId}-{Guid.NewGuid()}"; + var services = new ServiceCollection(); + services.Configure(options => + { + options.AppPort = 5000; + }); + Mock masaConfiguration = new(); + masaConfiguration.Setup(configuration => configuration.Local.GetSection($"{appId}-{NetworkUtils.GetPhysicalAddress()}").Value) + .Returns(() => expectedAppId); + Mock configuration = new(); + + var serviceProvider = services.BuildServiceProvider(); + var daprOptions = serviceProvider.GetRequiredService>(); + + var callerProvider = new DefaultCallerProvider(daprOptions, configuration.Object, masaConfiguration.Object); + string actualAppId = callerProvider.CompletionAppId(appId); + Assert.AreEqual(expectedAppId, actualAppId); + } + + [TestMethod] + public void TestCompletionAppId4() + { + string appId = "appid"; + var services = new ServiceCollection(); + services.Configure(options => + { + options.AppPort = 5000; + options.AppIdSuffix = "suffix"; + }); + string expectedAppId = $"{appId}-{Guid.NewGuid()}"; + + Mock masaConfiguration = new(); + masaConfiguration.Setup(configuration => configuration.Local.GetSection($"{appId}-suffix").Value) + .Returns(() => expectedAppId); + Mock configuration = new(); + + var serviceProvider = services.BuildServiceProvider(); + var daprOptions = serviceProvider.GetRequiredService>(); + + var callerProvider = new DefaultCallerProvider(daprOptions, configuration.Object, masaConfiguration.Object); + string actualAppId = callerProvider.CompletionAppId(appId); + Assert.AreEqual(expectedAppId, actualAppId); + } + + [TestMethod] + public void TestCompletionAppId5() + { + string appId = "appid"; + var services = new ServiceCollection(); + services.Configure(options => + { + options.AppPort = 5000; + options.AppIdSuffix = "suffix"; + }); + string expectedAppId = $"{appId}-{Guid.NewGuid()}"; + + Mock configuration = new(); + configuration.Setup(c => c.GetSection($"{appId}-suffix").Value).Returns(() => expectedAppId); + + var serviceProvider = services.BuildServiceProvider(); + var daprOptions = serviceProvider.GetRequiredService>(); + + var callerProvider = new DefaultCallerProvider(daprOptions, configuration.Object); + string actualAppId = callerProvider.CompletionAppId(appId); + Assert.AreEqual(expectedAppId, actualAppId); + } +} diff --git a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs index 6ef3ae1cd..0709e12b5 100644 --- a/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs +++ b/src/Contrib/Service/Caller/Tests/Masa.Contrib.Service.Caller.Tests/_Imports.cs @@ -1,6 +1,8 @@ // Copyright (c) MASA Stack All rights reserved. // Licensed under the MIT License. See LICENSE.txt in the project root for license information. +global using Masa.BuildingBlocks.Configuration; +global using Masa.BuildingBlocks.Development.DaprStarter; global using Masa.BuildingBlocks.Service.Caller; global using Masa.BuildingBlocks.Service.Caller.Options; global using Masa.Contrib.Service.Caller.DaprClient; @@ -17,6 +19,7 @@ global using Moq.Protected; global using System.Net; global using System.Net.Http.Json; +global using System.Net.NetworkInformation; global using System.Reflection; global using System.Runtime.ExceptionServices; global using System.Text; diff --git a/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/AutomaticCallerTest.cs b/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/AutomaticCallerTest.cs index 621ac7bfd..8a71c0bcc 100644 --- a/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/AutomaticCallerTest.cs +++ b/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/AutomaticCallerTest.cs @@ -32,6 +32,11 @@ public void TestDaprCallerReturnCallerProviderIsNotNull() var serviceProvider = _builder.Services.BuildServiceProvider(); var caller = serviceProvider.GetRequiredService(); Assert.IsTrue(caller.CallerProviderIsNotNull()); + + var callerClient = (Masa.Contrib.Service.Caller.DaprClient.DaprCaller)caller.GetCaller(); + var field = callerClient.GetType().GetField("AppId", BindingFlags.Instance | BindingFlags.NonPublic); + Assert.IsNotNull(field); + Assert.AreEqual("DaprCaller", field.GetValue(callerClient)); } [TestMethod] @@ -44,4 +49,13 @@ public void TestCustomDaprBaseReturnAppIdIsEqualUserService() var userCaller = serviceProvider.GetRequiredService(); Assert.IsTrue(roleCaller.GetAppId() == "User-Service" && userCaller.GetAppId() == "User-Service"); } + + [TestMethod] + public void TestCallerProvider() + { + _builder.Services.AddCaller(); + var serviceProvider = _builder.Services.BuildServiceProvider(); + var callerProvider = serviceProvider.GetService(); + Assert.IsNotNull(callerProvider); + } } diff --git a/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/Callers/DaprCaller.cs b/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/Callers/DaprCaller.cs index 81e897073..f329f62f7 100644 --- a/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/Callers/DaprCaller.cs +++ b/src/Contrib/Service/Caller/Tests/Scenes/Masa.Contrib.Service.Caller.AutomaticCaller.Tests/Callers/DaprCaller.cs @@ -13,4 +13,6 @@ public DaprCaller(IServiceProvider serviceProvider) : base(serviceProvider) protected override string AppId { get; set; } public bool CallerProviderIsNotNull() => Caller != null; + + public ICaller GetCaller() => Caller; } diff --git a/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/StringExtensions.cs b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/StringExtensions.cs index 0fb11522d..d7d538eb6 100644 --- a/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/StringExtensions.cs +++ b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/StringExtensions.cs @@ -7,10 +7,10 @@ namespace System; public static class StringExtensions { - public static bool IsNullOrWhiteSpace(this string? value) + public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? value) => string.IsNullOrWhiteSpace(value); - public static bool IsNullOrEmpty(this string? value) + public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value) => string.IsNullOrEmpty(value); public static void CheckIsNullOrWhiteSpace(this string? value, [CallerArgumentExpression("value")] string? paramName = null) diff --git a/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/_Imports.cs b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/_Imports.cs index 4ee8decdf..e206af5ad 100644 --- a/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/_Imports.cs +++ b/src/Utils/Extensions/Masa.Utils.Extensions.DotNet/_Imports.cs @@ -4,6 +4,7 @@ global using System.Collections; global using System.ComponentModel; global using System.Diagnostics; +global using System.Diagnostics.CodeAnalysis; global using System.Dynamic; global using System.Globalization; global using System.Reflection;