diff --git a/Masa.Contrib.sln b/Masa.Contrib.sln index 916526334..8854ccb52 100644 --- a/Masa.Contrib.sln +++ b/Masa.Contrib.sln @@ -302,6 +302,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BasicAbility", "BasicAbilit EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.BuildingBlocks.BasicAbility.Scheduler", "src\BuildingBlocks\MASA.BuildingBlocks\src\BasicAbility\Masa.BuildingBlocks.BasicAbility.Scheduler\Masa.BuildingBlocks.BasicAbility.Scheduler.csproj", "{0EB0CB69-4C44-4462-A92A-A9B9FDA171DE}" EndProject + +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.BasicAbility.Scheduler.Tests", "test\Masa.Contrib.BasicAbility.Scheduler.Tests\Masa.Contrib.BasicAbility.Scheduler.Tests.csproj", "{5980D054-E2F3-4143-93D1-01993A955AE7}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Contrib.BasicAbility.Scheduler", "src\BasicAbility\Masa.Contrib.BasicAbility.Scheduler\Masa.Contrib.BasicAbility.Scheduler.csproj", "{8D84666E-C79E-4D49-B73D-360E62D312EF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1230,6 +1235,38 @@ Global {789ABED5-7C94-4F6F-ADCA-E97F3DFC9479}.Release|Any CPU.Build.0 = Release|Any CPU {789ABED5-7C94-4F6F-ADCA-E97F3DFC9479}.Release|x64.ActiveCfg = Release|Any CPU {789ABED5-7C94-4F6F-ADCA-E97F3DFC9479}.Release|x64.Build.0 = Release|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Debug|x64.ActiveCfg = Debug|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Debug|x64.Build.0 = Debug|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Release|Any CPU.Build.0 = Release|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Release|x64.ActiveCfg = Release|Any CPU + {D91C3145-C31C-4301-A493-96F94C903CF2}.Release|x64.Build.0 = Release|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Debug|x64.ActiveCfg = Debug|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Debug|x64.Build.0 = Debug|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Release|Any CPU.Build.0 = Release|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Release|x64.ActiveCfg = Release|Any CPU + {FD35BEFA-512C-4483-B5C0-ADCA35680315}.Release|x64.Build.0 = Release|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Debug|x64.ActiveCfg = Debug|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Debug|x64.Build.0 = Debug|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Release|Any CPU.Build.0 = Release|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Release|x64.ActiveCfg = Release|Any CPU + {5980D054-E2F3-4143-93D1-01993A955AE7}.Release|x64.Build.0 = Release|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Debug|x64.Build.0 = Debug|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Release|Any CPU.Build.0 = Release|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Release|x64.ActiveCfg = Release|Any CPU + {8D84666E-C79E-4D49-B73D-360E62D312EF}.Release|x64.Build.0 = Release|Any CPU {981E883E-CCDC-400B-8FB1-76E1E65C32AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {981E883E-CCDC-400B-8FB1-76E1E65C32AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {981E883E-CCDC-400B-8FB1-76E1E65C32AF}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -1393,6 +1430,8 @@ Global {FF3FD53D-D23E-48AC-98B6-3B028B4DE8AF} = {0D34A7F0-DC77-4789-A136-93089CBD15C3} {83FA668F-C838-4883-996D-AF2ECF00FDF8} = {5DFAF4A2-ECB5-46E4-904D-1EA5F48B2D48} {789ABED5-7C94-4F6F-ADCA-E97F3DFC9479} = {38E6C400-90C0-493E-9266-C1602E229F1B} + {5980D054-E2F3-4143-93D1-01993A955AE7} = {38E6C400-90C0-493E-9266-C1602E229F1B} + {8D84666E-C79E-4D49-B73D-360E62D312EF} = {5DFAF4A2-ECB5-46E4-904D-1EA5F48B2D48} {981E883E-CCDC-400B-8FB1-76E1E65C32AF} = {0D34A7F0-DC77-4789-A136-93089CBD15C3} {0D34A7F0-DC77-4789-A136-93089CBD15C3} = {DC578D74-98F0-4F19-A230-CFA8DAEE0AF1} {0EB0CB69-4C44-4462-A92A-A9B9FDA171DE} = {0D34A7F0-DC77-4789-A136-93089CBD15C3} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Constants.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Constants.cs new file mode 100644 index 000000000..de50d9580 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Constants.cs @@ -0,0 +1,10 @@ +// 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.BasicAbility.Scheduler; + +internal class Constants +{ + internal const string DEFAULT_CLIENT_NAME = "masa.contrib.basicability.scheduler"; + internal const string ENVIRONMENT_KEY = "env_key"; +} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Masa.Contrib.BasicAbility.Scheduler.csproj b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Masa.Contrib.BasicAbility.Scheduler.csproj new file mode 100644 index 000000000..013e83a80 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Masa.Contrib.BasicAbility.Scheduler.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/SchedulerClient.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/SchedulerClient.cs new file mode 100644 index 000000000..658cc2755 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/SchedulerClient.cs @@ -0,0 +1,17 @@ +// 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.BasicAbility.Scheduler; + +public class SchedulerClient : ISchedulerClient +{ + public ISchedulerJobService SchedulerJobService { get; } + + public ISchedulerTaskService SchedulerTaskService { get; } + + public SchedulerClient(ICallerProvider callerProvider, ILoggerFactory? loggerFactory = null) + { + SchedulerJobService = new SchedulerJobService(callerProvider, loggerFactory); + SchedulerTaskService = new SchedulerTaskService(callerProvider, loggerFactory); + } +} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/ServiceCollectionExtensions.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/ServiceCollectionExtensions.cs new file mode 100644 index 000000000..813475a11 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/ServiceCollectionExtensions.cs @@ -0,0 +1,51 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the MIT License. See LICENSE.txt in the project root for license information. + +namespace Microsoft.Extensions.DependencyInjection; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddSchedulerClient(this IServiceCollection services, string schedulerServiceBaseAddress) + { + if (string.IsNullOrWhiteSpace(schedulerServiceBaseAddress)) + { + throw new ArgumentNullException(nameof(schedulerServiceBaseAddress)); + } + + services.AddSingleton(); + return services.AddSchedulerClient(callerOptions => + { + callerOptions.UseHttpClient(builder => + { + builder.Name = DEFAULT_CLIENT_NAME; + builder.Configure = opt => opt.BaseAddress = new Uri(schedulerServiceBaseAddress); + }); + }); + } + + public static IServiceCollection AddSchedulerClient(this IServiceCollection services, Action callerOptions) + { + ArgumentNullException.ThrowIfNull(callerOptions, nameof(callerOptions)); + + if (services.Any(service => service.ImplementationType == typeof(SchedulerProvider))) + return services; + + services.AddSingleton(); + services.AddHttpContextAccessor(); + services.AddCaller(callerOptions); + + services.AddScoped(serviceProvider => + { + var callProvider = serviceProvider.GetRequiredService().CreateClient(DEFAULT_CLIENT_NAME); + var loggerFactory = serviceProvider.GetService(); + var schedulerClient = new SchedulerClient(callProvider, loggerFactory); + return schedulerClient; + }); + + return services; + } + + private class SchedulerProvider + { + } +} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerJobService.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerJobService.cs new file mode 100644 index 000000000..2c194bc34 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerJobService.cs @@ -0,0 +1,123 @@ +// 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.BasicAbility.Scheduler.Services; + +public class SchedulerJobService : ISchedulerJobService +{ + const string API = "/api/scheduler-job"; + + readonly ICallerProvider _callerProvider; + readonly ILogger? _logger; + + public SchedulerJobService(ICallerProvider callerProvider, ILoggerFactory? loggerFactory = null) + { + _callerProvider = callerProvider; + _logger = loggerFactory?.CreateLogger(); + } + + public async Task AddbAsync(AddSchedulerJobRequest request) + { + if (string.IsNullOrWhiteSpace(request.ProjectIdentity)) + { + throw new ArgumentNullException(nameof(request.ProjectIdentity)); + } + + switch (request.JobType) + { + case BuildingBlocks.BasicAbility.Scheduler.Enum.JobTypes.JobApp: + ArgumentNullException.ThrowIfNull(request.JobAppConfig, nameof(request.JobAppConfig)); + break; + case BuildingBlocks.BasicAbility.Scheduler.Enum.JobTypes.Http: + ArgumentNullException.ThrowIfNull(request.HttpConfig, nameof(request.HttpConfig)); + break; + case BuildingBlocks.BasicAbility.Scheduler.Enum.JobTypes.DaprServiceInvocation: + ArgumentNullException.ThrowIfNull(request.DaprServiceInvocationConfig, nameof(request.DaprServiceInvocationConfig)); + break; + } + + try + { + var requestUri = $"{API}/addSchedulerJobBySdk"; + return await _callerProvider.PostAsync(requestUri, request); + } + catch (Exception ex) + { + _logger?.LogError(ex, "AddSchedulerJobAsync Error"); + return Guid.Empty; + } + + } + + public async Task DisableAsync(BaseSchedulerJobRequest request) + { + try + { + var requestData = new ChangeEnabledStatusRequest() + { + JobId = request.JobId, + OperatorId = request.OperatorId, + Enabled = false + }; + var requestUri = $"{API}/changeEnableStatus"; + await _callerProvider.PutAsync(requestUri, requestData); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "DisableSchedulerJob Error"); + return false; + } + } + + public async Task EnableAsync(BaseSchedulerJobRequest request) + { + try + { + var requestData = new ChangeEnabledStatusRequest() + { + JobId = request.JobId, + OperatorId = request.OperatorId, + Enabled = true + }; + var requestUri = $"{API}/changeEnableStatus"; + await _callerProvider.PutAsync(requestUri, requestData); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "EnableSchedulerJob Error"); + return false; + } + } + + public async Task RemoveAsync(BaseSchedulerJobRequest request) + { + try + { + var requestUri = $"{API}"; + await _callerProvider.DeleteAsync(requestUri, request); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "RemoveSchedulerJobAsync Error"); + return false; + } + } + + public async Task StartAsync(BaseSchedulerJobRequest request) + { + try + { + var requestUri = $"{API}/startJob"; + await _callerProvider.PutAsync(requestUri, request); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "StartSchedulerJobAsync Error"); + return false; + } + } +} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerTaskService.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerTaskService.cs new file mode 100644 index 000000000..29806b4d5 --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/Services/SchedulerTaskService.cs @@ -0,0 +1,55 @@ +// 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.BasicAbility.Scheduler.Services; + +public class SchedulerTaskService : ISchedulerTaskService +{ + const string API = "/api/scheduler-task"; + + readonly ICallerProvider _callerProvider; + readonly ILogger? _logger; + + public SchedulerTaskService(ICallerProvider callerProvider, ILoggerFactory? loggerFactory) + { + _callerProvider = callerProvider; + _logger = loggerFactory?.CreateLogger(); + } + + public async Task StopAsync(BaseSchedulerTaskRequest request) + { + try + { + var requestUri = $"{API}/stop"; + await _callerProvider.PutAsync(requestUri, request); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "StopSchedulerTaskAsync Error"); + return false; + } + } + + public async Task StartAsync(BaseSchedulerTaskRequest request) + { + try + { + var requestData = new StartSchedulerTaskRequest() + { + TaskId = request.TaskId, + OperatorId = request.OperatorId, + IsManual = true + }; + + var requestUri = $"{API}/start"; + await _callerProvider.PutAsync(requestUri, requestData); + return true; + } + catch (Exception ex) + { + _logger?.LogError(ex, "StopSchedulerTaskAsync Error"); + return false; + } + } +} diff --git a/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/_Imports.cs b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/_Imports.cs new file mode 100644 index 000000000..cb3f0e0ed --- /dev/null +++ b/src/BasicAbility/Masa.Contrib.BasicAbility.Scheduler/_Imports.cs @@ -0,0 +1,13 @@ +// 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.BasicAbility.Scheduler; +global using Masa.BuildingBlocks.BasicAbility.Scheduler.Request; +global using Masa.BuildingBlocks.BasicAbility.Scheduler.Service; +global using Masa.BuildingBlocks.Identity.IdentityModel; +global using Masa.Contrib.BasicAbility.Scheduler; +global using Masa.Contrib.BasicAbility.Scheduler.Services; +global using Masa.Utils.Caller.Core; +global using Masa.Utils.Caller.HttpClient; +global using Microsoft.Extensions.Logging; +global using static Masa.Contrib.BasicAbility.Scheduler.Constants; diff --git a/src/BuildingBlocks/MASA.BuildingBlocks b/src/BuildingBlocks/MASA.BuildingBlocks index 61fe682cc..c19f0f87f 160000 --- a/src/BuildingBlocks/MASA.BuildingBlocks +++ b/src/BuildingBlocks/MASA.BuildingBlocks @@ -1 +1 @@ -Subproject commit 61fe682cc794cc826d7301800043e037b14d0e6a +Subproject commit c19f0f87fb185a12bae9b238f82d68c4f91cdb02 diff --git a/test/Masa.Contrib.BasicAbility.Scheduler.Tests/Masa.Contrib.BasicAbility.Scheduler.Tests.csproj b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/Masa.Contrib.BasicAbility.Scheduler.Tests.csproj new file mode 100644 index 000000000..01624c4f7 --- /dev/null +++ b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/Masa.Contrib.BasicAbility.Scheduler.Tests.csproj @@ -0,0 +1,26 @@ + + + + net6.0 + enable + + false + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerClientTest.cs b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerClientTest.cs new file mode 100644 index 000000000..46959a645 --- /dev/null +++ b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerClientTest.cs @@ -0,0 +1,52 @@ +// 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.BasicAbility.Scheduler.Tests; + +[TestClass] +public class SchedulerClientTest +{ + [TestMethod] + public void TestAddSchedulerClientByOptions() + { + var services = new ServiceCollection(); + + services.AddSchedulerClient(option => + { + option.UseHttpClient(builder => + { + builder.Name = "masa.contrib.basicability.scheduler"; + builder.Configure = opt => opt.BaseAddress = new Uri("https://github.com"); + }); + }); + + var schedulerClient = services.BuildServiceProvider().GetService(); + Assert.IsNotNull(schedulerClient); + } + + [TestMethod] + public void TestAddSchedulerClient() + { + var services = new ServiceCollection(); + services.AddSchedulerClient("https://github.com"); + var schedulerClient = services.BuildServiceProvider().GetService(); + Assert.IsNotNull(schedulerClient); + } + + [TestMethod] + public void TestAddSchedulerClientShouldThrowArgumentNullException() + { + var services = new ServiceCollection(); + + Assert.ThrowsException(() => services.AddSchedulerClient("")); + } + + [TestMethod] + public void TestAddSchedulerClientShouldThrowArgumentNullException2() + { + var services = new ServiceCollection(); + + Assert.ThrowsException(() => services.AddSchedulerClient(callerOptions: null!)); + } + +} diff --git a/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerJobServiceTest.cs b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerJobServiceTest.cs new file mode 100644 index 000000000..26720937a --- /dev/null +++ b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerJobServiceTest.cs @@ -0,0 +1,302 @@ +// 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.BasicAbility.Scheduler.Tests; + +[TestClass] +public class SchedulerJobServiceTest +{ + const string API = "/api/scheduler-job"; + + [TestMethod] + public async Task TestAddSchedulerHttpJobAsync() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.Http, + ProjectIdentity = "MASA_MC", + CronExpression = "", + HttpConfig = new SchedulerJobHttpConfig() + { + RequestUrl = "www.baidu.com", + HttpVerifyType = HttpVerifyTypes.CustomStatusCode, + HttpBody = "", + HttpHeaders = new List>() + { + new KeyValuePair("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36") + }, + HttpMethod = HttpMethods.GET, + VerifyContent = "200", + HttpParameters = new List>() + { + new KeyValuePair("ie", "utf-8"), + } + }, + OperatorId = Guid.NewGuid(), + Description = "Test", + FailedRetryCount = 0, + FailedRetryInterval = 0, + IsAlertException = false, + RunTimeoutSecond = 30, + RunTimeoutStrategy = RunTimeoutStrategyTypes.IgnoreTimeout, + ScheduleBlockStrategy = ScheduleBlockStrategyTypes.Parallel, + ScheduleExpiredStrategy = ScheduleExpiredStrategyTypes.Ignore + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.AddbAsync(requestData); + callerProvider.Verify(provider => provider.PostAsync(requestUri, requestData, default), Times.Once); + + Assert.AreNotEqual(Guid.Empty, result); + } + + [TestMethod] + public async Task TestAddSchedulerJobApp() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.JobApp, + ProjectIdentity = "MASA_MC", + CronExpression = "", + JobAppConfig = new SchedulerJobAppConfig() + { + JobAppIdentity = "MASA_MC_SERVICE", + JobEntryAssembly = "Masa.Test.Job", + JobEntryMethod = "TestRunJob", + JobParams = "1;2;3", + Version = "" + }, + OperatorId = Guid.NewGuid(), + Description = "Test", + FailedRetryCount = 0, + FailedRetryInterval = 0, + IsAlertException = false, + RunTimeoutSecond = 30, + RunTimeoutStrategy = RunTimeoutStrategyTypes.IgnoreTimeout, + ScheduleBlockStrategy = ScheduleBlockStrategyTypes.Parallel, + ScheduleExpiredStrategy = ScheduleExpiredStrategyTypes.Ignore + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.AddbAsync(requestData); + callerProvider.Verify(provider => provider.PostAsync(requestUri, requestData, default), Times.Once); + + Assert.AreNotEqual(Guid.Empty, result); + } + + [TestMethod] + public async Task TestAddSchedulerDaprServiceInvocationJob() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.DaprServiceInvocation, + ProjectIdentity = "MASA_MC", + CronExpression = "", + DaprServiceInvocationConfig = new SchedulerJobDaprServiceInvocationConfig() + { + DaprServiceIdentity = "MASA_MC_DAPR_SERVICE", + Data = "Test", + HttpMethod = HttpMethods.POST, + MethodName = "TestMethod" + }, + OperatorId = Guid.NewGuid(), + Description = "Test", + FailedRetryCount = 0, + FailedRetryInterval = 0, + IsAlertException = false, + RunTimeoutSecond = 30, + RunTimeoutStrategy = RunTimeoutStrategyTypes.IgnoreTimeout, + ScheduleBlockStrategy = ScheduleBlockStrategyTypes.Parallel, + ScheduleExpiredStrategy = ScheduleExpiredStrategyTypes.Ignore + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.AddbAsync(requestData); + callerProvider.Verify(provider => provider.PostAsync(requestUri, requestData, default), Times.Once); + + Assert.AreNotEqual(Guid.Empty, result); + } + + [TestMethod] + public async Task TestAddSchedulerJobArgumentNullException() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.Http, + CronExpression = "", + HttpConfig = new SchedulerJobHttpConfig() + { + RequestUrl = "www.baidu.com", + HttpVerifyType = HttpVerifyTypes.CustomStatusCode, + HttpBody = "", + HttpHeaders = new List>() + { + new KeyValuePair("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36") + }, + HttpMethod = HttpMethods.GET, + VerifyContent = "200", + HttpParameters = new List>() + { + new KeyValuePair("ie", "utf-8"), + } + }, + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + await Assert.ThrowsExceptionAsync(async () => await schedulerClient.SchedulerJobService.AddbAsync(requestData)); + } + + [TestMethod] + public async Task TestAddSchedulerHttpJobArgumentNullException() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.Http, + CronExpression = "", + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + await Assert.ThrowsExceptionAsync(async () => await schedulerClient.SchedulerJobService.AddbAsync(requestData)); + } + + [TestMethod] + public async Task TestAddSchedulerJobAppArgumentNullException() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.JobApp, + CronExpression = "", + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + await Assert.ThrowsExceptionAsync(async () => await schedulerClient.SchedulerJobService.AddbAsync(requestData)); + } + + [TestMethod] + public async Task TestAddSchedulerDaprInvocationJobArgumentNullException() + { + var requestData = new AddSchedulerJobRequest() + { + Name = "TestJob", + JobType = JobTypes.DaprServiceInvocation, + CronExpression = "", + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/addSchedulerJobBySdk"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PostAsync(requestUri, requestData, default)).ReturnsAsync(Guid.NewGuid()).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + await Assert.ThrowsExceptionAsync(async () => await schedulerClient.SchedulerJobService.AddbAsync(requestData)); + } + + [TestMethod] + public async Task TestRemoveSchedulerJobAsync() + { + var requestData = new BaseSchedulerJobRequest() + { + JobId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.DeleteAsync(API, requestData, true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.RemoveAsync(requestData); + callerProvider.Verify(provider => provider.DeleteAsync(API, requestData, true, default), Times.Once); + + Assert.IsTrue(result); + } + + [TestMethod] + public async Task TestStartSchedulerJobAsync() + { + var requestData = new BaseSchedulerJobRequest() + { + JobId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/startJob"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PutAsync(requestUri, requestData, true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.StartAsync(requestData); + callerProvider.Verify(provider => provider.PutAsync(requestUri, requestData, true, default), Times.Once); + Assert.IsTrue(result); + } + + [TestMethod] + public async Task TestEnableSchedulerJob() + { + var requestData = new BaseSchedulerJobRequest() + { + JobId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/changeEnableStatus"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PutAsync(requestUri, It.IsAny(), true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.EnableAsync(requestData); + callerProvider.Verify(provider => provider.PutAsync(requestUri, It.IsAny(), true, default), Times.Once); + Assert.IsTrue(result); + } + + [TestMethod] + public async Task TestDisableSchedulerJob() + { + var requestData = new BaseSchedulerJobRequest() + { + JobId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/changeEnableStatus"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PutAsync(requestUri, It.IsAny(), true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerJobService.DisableAsync(requestData); + callerProvider.Verify(provider => provider.PutAsync(requestUri, It.IsAny(), true, default), Times.Once); + Assert.IsTrue(result); + } +} diff --git a/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerTaskServiceTest.cs b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerTaskServiceTest.cs new file mode 100644 index 000000000..a18086153 --- /dev/null +++ b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/SchedulerTaskServiceTest.cs @@ -0,0 +1,48 @@ +// 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.BasicAbility.Scheduler.Tests; + +[TestClass] +public class SchedulerTaskServiceTest +{ + const string API = "/api/scheduler-task"; + + [TestMethod] + public async Task TestStopSchedulerTaskAsync() + { + var requestData = new BaseSchedulerTaskRequest() + { + TaskId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/stop"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PutAsync(requestUri, requestData, true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerTaskService.StopAsync(requestData); + callerProvider.Verify(provider => provider.PutAsync(requestUri, requestData, true, default), Times.Once); + Assert.IsTrue(result); + } + + [TestMethod] + public async Task TestStartSchedulerTaskAsync() + { + var request = new BaseSchedulerTaskRequest() + { + TaskId = Guid.NewGuid(), + OperatorId = Guid.NewGuid() + }; + + var requestUri = $"{API}/start"; + var callerProvider = new Mock(); + var loggerFactory = new Mock(); + callerProvider.Setup(provider => provider.PutAsync(requestUri, It.IsAny(), true, default)).Verifiable(); + var schedulerClient = new SchedulerClient(callerProvider.Object, loggerFactory.Object); + var result = await schedulerClient.SchedulerTaskService.StartAsync(request); + callerProvider.Verify(provider => provider.PutAsync(requestUri, It.IsAny(), true, default), Times.Once); + Assert.IsTrue(result); + } +} diff --git a/test/Masa.Contrib.BasicAbility.Scheduler.Tests/_Imports.cs b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/_Imports.cs new file mode 100644 index 000000000..a2ca75efd --- /dev/null +++ b/test/Masa.Contrib.BasicAbility.Scheduler.Tests/_Imports.cs @@ -0,0 +1,16 @@ +// 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.BasicAbility.Scheduler; +global using Masa.BuildingBlocks.BasicAbility.Scheduler.Enum; +global using Masa.BuildingBlocks.BasicAbility.Scheduler.Model; +global using Masa.BuildingBlocks.BasicAbility.Scheduler.Request; +global using Masa.Utils.Caller.Core; +global using Masa.Utils.Caller.HttpClient; +global using Microsoft.Extensions.DependencyInjection; +global using Microsoft.Extensions.Logging; +global using Microsoft.VisualStudio.TestTools.UnitTesting; +global using Moq; +global using System; +global using System.Collections.Generic; +global using System.Threading.Tasks;