From 3bbda03834c56c0190fdc745aca1835984f10283 Mon Sep 17 00:00:00 2001 From: John Lambert Date: Tue, 3 Dec 2024 12:49:36 -0500 Subject: [PATCH] remove assessment (#550) --- Serval.sln | 7 - .../Serval.ApiServer/Serval.ApiServer.csproj | 1 - src/Serval/src/Serval.ApiServer/Startup.cs | 10 - src/Serval/src/Serval.ApiServer/Usings.cs | 1 - .../appsettings.Development.json | 6 +- .../src/Serval.ApiServer/appsettings.json | 4 +- .../Configuration/AssessmentOptions.cs | 14 - .../IEndpointRouteBuilderExtensions.cs | 11 - ...iatorRegistrationConfiguratorExtensions.cs | 12 - ...IMemoryDataAccessConfiguratorExtensions.cs | 14 - .../IMongoDataAccessConfiguratorExtensions.cs | 42 - .../Configuration/IServalBuilderExtensions.cs | 35 - .../Consumers/DataFileDeletedConsumer.cs | 11 - .../Contracts/AssessmentCorpusConfigDto.cs | 19 - .../Contracts/AssessmentCorpusDto.cs | 9 - .../AssessmentCorpusFileConfigDto.cs | 8 - .../Contracts/AssessmentCorpusFileDto.cs | 7 - .../Contracts/AssessmentEngineConfigDto.cs | 24 - .../Contracts/AssessmentEngineDto.cs | 11 - .../Contracts/AssessmentJobConfigDto.cs | 15 - .../Contracts/AssessmentJobDto.cs | 27 - .../Contracts/AssessmentResultDto.cs | 9 - .../AssessmentEnginesController.cs | 673 ----- .../src/Serval.Assessment/Models/Corpus.cs | 8 - .../Serval.Assessment/Models/CorpusFile.cs | 9 - .../src/Serval.Assessment/Models/Engine.cs | 12 - .../src/Serval.Assessment/Models/Job.cs | 16 - .../src/Serval.Assessment/Models/Result.cs | 13 - .../Serval.Assessment.csproj | 27 - .../Services/AssessmentPlatformServiceV1.cs | 257 -- .../Services/EngineService.cs | 239 -- .../Services/IEngineService.cs | 22 - .../Serval.Assessment/Services/IJobService.cs | 13 - .../Services/IResultService.cs | 11 - .../Serval.Assessment/Services/JobService.cs | 62 - .../Services/ResultService.cs | 17 - src/Serval/src/Serval.Assessment/Usings.cs | 32 - src/Serval/src/Serval.Client/Client.g.cs | 2258 +---------------- .../Protos/serval/assessment/v1/engine.proto | 62 - .../serval/assessment/v1/platform.proto | 51 - .../Contracts/AssessmentJobFinished.cs | 11 - .../Contracts/AssessmentJobFinishedDto.cs | 10 - .../Contracts/AssessmentJobStarted.cs | 8 - .../Contracts/AssessmentJobStartedDto.cs | 7 - .../Serval.Shared/Controllers/Endpoints.cs | 5 - .../src/Serval.Shared/Controllers/Scopes.cs | 9 - ...iatorRegistrationConfiguratorExtensions.cs | 2 - .../AssessmentJobFinishedConsumer.cs | 36 - .../Consumers/AssessmentJobStartedConsumer.cs | 33 - .../Serval.Webhooks/Contracts/WebhookEvent.cs | 3 - .../AssessmentEngineTests.cs | 223 -- 51 files changed, 37 insertions(+), 4389 deletions(-) delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/AssessmentOptions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/IEndpointRouteBuilderExtensions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/IMediatorRegistrationConfiguratorExtensions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/IMemoryDataAccessConfiguratorExtensions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/IMongoDataAccessConfiguratorExtensions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Configuration/IServalBuilderExtensions.cs delete mode 100644 src/Serval/src/Serval.Assessment/Consumers/DataFileDeletedConsumer.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusConfigDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileConfigDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineConfigDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentJobConfigDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentJobDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Contracts/AssessmentResultDto.cs delete mode 100644 src/Serval/src/Serval.Assessment/Controllers/AssessmentEnginesController.cs delete mode 100644 src/Serval/src/Serval.Assessment/Models/Corpus.cs delete mode 100644 src/Serval/src/Serval.Assessment/Models/CorpusFile.cs delete mode 100644 src/Serval/src/Serval.Assessment/Models/Engine.cs delete mode 100644 src/Serval/src/Serval.Assessment/Models/Job.cs delete mode 100644 src/Serval/src/Serval.Assessment/Models/Result.cs delete mode 100644 src/Serval/src/Serval.Assessment/Serval.Assessment.csproj delete mode 100644 src/Serval/src/Serval.Assessment/Services/AssessmentPlatformServiceV1.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/EngineService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/IEngineService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/IJobService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/IResultService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/JobService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Services/ResultService.cs delete mode 100644 src/Serval/src/Serval.Assessment/Usings.cs delete mode 100644 src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/engine.proto delete mode 100644 src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/platform.proto delete mode 100644 src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinished.cs delete mode 100644 src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinishedDto.cs delete mode 100644 src/Serval/src/Serval.Shared/Contracts/AssessmentJobStarted.cs delete mode 100644 src/Serval/src/Serval.Shared/Contracts/AssessmentJobStartedDto.cs delete mode 100644 src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobFinishedConsumer.cs delete mode 100644 src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobStartedConsumer.cs delete mode 100644 src/Serval/test/Serval.ApiServer.IntegrationTests/AssessmentEngineTests.cs diff --git a/Serval.sln b/Serval.sln index 12c0aaaf..9698e63e 100644 --- a/Serval.sln +++ b/Serval.sln @@ -78,8 +78,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serval.Machine.JobServer", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serval.Machine.Shared.Tests", "src\Machine\test\Serval.Machine.Shared.Tests\Serval.Machine.Shared.Tests.csproj", "{B0D23A55-AB09-4C2C-B309-F4BEB3BC968D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serval.Assessment", "src\Serval\src\Serval.Assessment\Serval.Assessment.csproj", "{10657805-48F1-4205-B8F5-79447F6EF620}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceToolkit", "ServiceToolkit", "{EA69B41C-49EF-4017-A687-44B9DF37FF98}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C3A14577-A654-4604-818C-4E683DD45A51}" @@ -176,10 +174,6 @@ Global {B0D23A55-AB09-4C2C-B309-F4BEB3BC968D}.Debug|Any CPU.Build.0 = Debug|Any CPU {B0D23A55-AB09-4C2C-B309-F4BEB3BC968D}.Release|Any CPU.ActiveCfg = Release|Any CPU {B0D23A55-AB09-4C2C-B309-F4BEB3BC968D}.Release|Any CPU.Build.0 = Release|Any CPU - {10657805-48F1-4205-B8F5-79447F6EF620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10657805-48F1-4205-B8F5-79447F6EF620}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10657805-48F1-4205-B8F5-79447F6EF620}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10657805-48F1-4205-B8F5-79447F6EF620}.Release|Any CPU.Build.0 = Release|Any CPU {0E40F959-C641-40A2-9750-B17A4F9F9E55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0E40F959-C641-40A2-9750-B17A4F9F9E55}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E40F959-C641-40A2-9750-B17A4F9F9E55}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -220,7 +214,6 @@ Global {C02494FB-663E-4430-9F2D-41F1A740B271} = {D808D2BE-ED26-4E60-A409-AE58F7C1CB8F} {BC766753-E560-4ADF-9923-C7A96076EA47} = {D808D2BE-ED26-4E60-A409-AE58F7C1CB8F} {B0D23A55-AB09-4C2C-B309-F4BEB3BC968D} = {40C225C2-1EEF-4D1D-9D14-1CBB86C8A1CB} - {10657805-48F1-4205-B8F5-79447F6EF620} = {25CDB05B-4E24-4A6E-933E-1E0BEC97D74D} {C3A14577-A654-4604-818C-4E683DD45A51} = {EA69B41C-49EF-4017-A687-44B9DF37FF98} {0E40F959-C641-40A2-9750-B17A4F9F9E55} = {C3A14577-A654-4604-818C-4E683DD45A51} {1DB5E6D1-17A8-4FF2-B90A-C5DFBEF63126} = {EA69B41C-49EF-4017-A687-44B9DF37FF98} diff --git a/src/Serval/src/Serval.ApiServer/Serval.ApiServer.csproj b/src/Serval/src/Serval.ApiServer/Serval.ApiServer.csproj index 3ea7d09f..f60385bd 100644 --- a/src/Serval/src/Serval.ApiServer/Serval.ApiServer.csproj +++ b/src/Serval/src/Serval.ApiServer/Serval.ApiServer.csproj @@ -44,7 +44,6 @@ - diff --git a/src/Serval/src/Serval.ApiServer/Startup.cs b/src/Serval/src/Serval.ApiServer/Startup.cs index d4c5a3cd..2f6e7549 100644 --- a/src/Serval/src/Serval.ApiServer/Startup.cs +++ b/src/Serval/src/Serval.ApiServer/Startup.cs @@ -79,12 +79,10 @@ public void ConfigureServices(IServiceCollection services) .AddMongoDataAccess(cfg => { cfg.AddTranslationRepositories(); - cfg.AddAssessmentRepositories(); cfg.AddDataFilesRepositories(); cfg.AddWebhooksRepositories(); }) .AddTranslation() - .AddAssessment() .AddDataFiles() .AddWebhooks(); services.AddTransient(); @@ -112,7 +110,6 @@ public void ConfigureServices(IServiceCollection services) services.AddMediator(cfg => { cfg.AddTranslationConsumers(); - cfg.AddAssessmentConsumers(); cfg.AddDataFilesConsumers(); cfg.AddWebhooksConsumers(); }); @@ -150,12 +147,6 @@ public void ConfigureServices(IServiceCollection services) o.Version = version.Major + "." + version.Minor; var featureManager = sp.GetRequiredService(); - if (!featureManager.IsEnabledAsync("Assessment").WaitAndUnwrapException()) - { - o.AddOperationFilter(ctxt => - !(ctxt.ControllerType.Namespace?.StartsWith("Serval.Assessment") ?? true) - ); - } o.SchemaSettings.SchemaNameGenerator = new ServalSchemaNameGenerator(); o.UseControllerSummaryAsTagDescription = true; @@ -231,7 +222,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { x.MapControllers(); x.MapServalTranslationServices(); - x.MapServalAssessmentServices(); x.MapHangfireDashboard(); }); diff --git a/src/Serval/src/Serval.ApiServer/Usings.cs b/src/Serval/src/Serval.ApiServer/Usings.cs index 13f508d8..941afefa 100644 --- a/src/Serval/src/Serval.ApiServer/Usings.cs +++ b/src/Serval/src/Serval.ApiServer/Usings.cs @@ -17,7 +17,6 @@ global using Microsoft.Extensions.Diagnostics.HealthChecks; global using Microsoft.FeatureManagement; global using Microsoft.IdentityModel.Tokens; -global using Nito.AsyncEx.Synchronous; global using NJsonSchema; global using NJsonSchema.Generation; global using NSwag; diff --git a/src/Serval/src/Serval.ApiServer/appsettings.Development.json b/src/Serval/src/Serval.ApiServer/appsettings.Development.json index 8a5d5cd6..0910ceed 100644 --- a/src/Serval/src/Serval.ApiServer/appsettings.Development.json +++ b/src/Serval/src/Serval.ApiServer/appsettings.Development.json @@ -4,9 +4,7 @@ "Protocols": "Http2" } }, - "FeatureManagement": { - "Assessment": true - }, + "FeatureManagement": {}, "ConnectionStrings": { "Mongo": "mongodb://localhost:27017/serval", "Hangfire": "mongodb://localhost:27017/serval_jobs" @@ -33,4 +31,4 @@ "Microsoft.AspNetCore": "Warning" } } -} +} \ No newline at end of file diff --git a/src/Serval/src/Serval.ApiServer/appsettings.json b/src/Serval/src/Serval.ApiServer/appsettings.json index 496183ef..a5ebabde 100644 --- a/src/Serval/src/Serval.ApiServer/appsettings.json +++ b/src/Serval/src/Serval.ApiServer/appsettings.json @@ -1,8 +1,6 @@ { "AllowedHosts": "*", - "FeatureManagement": { - "Assessment": false - }, + "FeatureManagement": {}, "Auth": { "Domain": "sil-appbuilder.auth0.com", "Audience": "https://serval-api.org/" diff --git a/src/Serval/src/Serval.Assessment/Configuration/AssessmentOptions.cs b/src/Serval/src/Serval.Assessment/Configuration/AssessmentOptions.cs deleted file mode 100644 index d119df1f..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/AssessmentOptions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Serval.Assessment.Configuration; - -public class AssessmentOptions -{ - public const string Key = "Assessment"; - - public List Engines { get; set; } = new List(); -} - -public class EngineInfo -{ - public string Type { get; set; } = ""; - public string Address { get; set; } = ""; -} diff --git a/src/Serval/src/Serval.Assessment/Configuration/IEndpointRouteBuilderExtensions.cs b/src/Serval/src/Serval.Assessment/Configuration/IEndpointRouteBuilderExtensions.cs deleted file mode 100644 index 64ef9cad..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/IEndpointRouteBuilderExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Microsoft.AspNetCore.Builder; - -public static class IEndpointRouteBuilderExtensions -{ - public static IEndpointRouteBuilder MapServalAssessmentServices(this IEndpointRouteBuilder builder) - { - builder.MapGrpcService(); - - return builder; - } -} diff --git a/src/Serval/src/Serval.Assessment/Configuration/IMediatorRegistrationConfiguratorExtensions.cs b/src/Serval/src/Serval.Assessment/Configuration/IMediatorRegistrationConfiguratorExtensions.cs deleted file mode 100644 index 8b9bd293..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/IMediatorRegistrationConfiguratorExtensions.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Microsoft.Extensions.DependencyInjection; - -public static class IMediatorRegistrationConfiguratorExtensions -{ - public static IMediatorRegistrationConfigurator AddAssessmentConsumers( - this IMediatorRegistrationConfigurator configurator - ) - { - configurator.AddConsumer(); - return configurator; - } -} diff --git a/src/Serval/src/Serval.Assessment/Configuration/IMemoryDataAccessConfiguratorExtensions.cs b/src/Serval/src/Serval.Assessment/Configuration/IMemoryDataAccessConfiguratorExtensions.cs deleted file mode 100644 index 047d4b48..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/IMemoryDataAccessConfiguratorExtensions.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Microsoft.Extensions.DependencyInjection; - -public static class IMemoryDataAccessConfiguratorExtensions -{ - public static IMemoryDataAccessConfigurator AddAssessmentRepositories( - this IMemoryDataAccessConfigurator configurator - ) - { - configurator.AddRepository(); - configurator.AddRepository(); - configurator.AddRepository(); - return configurator; - } -} diff --git a/src/Serval/src/Serval.Assessment/Configuration/IMongoDataAccessConfiguratorExtensions.cs b/src/Serval/src/Serval.Assessment/Configuration/IMongoDataAccessConfiguratorExtensions.cs deleted file mode 100644 index 8ef721b1..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/IMongoDataAccessConfiguratorExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using MongoDB.Driver; - -namespace Microsoft.Extensions.DependencyInjection; - -public static class IMongoDataAccessConfiguratorExtensions -{ - public static IMongoDataAccessConfigurator AddAssessmentRepositories(this IMongoDataAccessConfigurator configurator) - { - configurator.AddRepository( - "assessment.engines", - init: async c => - { - await c.Indexes.CreateOrUpdateAsync( - new CreateIndexModel(Builders.IndexKeys.Ascending(e => e.Owner)) - ); - } - ); - configurator.AddRepository( - "assessment.jobs", - init: c => - c.Indexes.CreateOrUpdateAsync( - new CreateIndexModel(Builders.IndexKeys.Ascending(b => b.EngineRef)) - ) - ); - configurator.AddRepository( - "assessment.results", - init: async c => - { - await c.Indexes.CreateOrUpdateAsync( - new CreateIndexModel(Builders.IndexKeys.Ascending(pt => pt.EngineRef)) - ); - await c.Indexes.CreateOrUpdateAsync( - new CreateIndexModel(Builders.IndexKeys.Ascending(pt => pt.JobRef)) - ); - await c.Indexes.CreateOrUpdateAsync( - new CreateIndexModel(Builders.IndexKeys.Ascending(pt => pt.TextId)) - ); - } - ); - return configurator; - } -} diff --git a/src/Serval/src/Serval.Assessment/Configuration/IServalBuilderExtensions.cs b/src/Serval/src/Serval.Assessment/Configuration/IServalBuilderExtensions.cs deleted file mode 100644 index ee82803b..00000000 --- a/src/Serval/src/Serval.Assessment/Configuration/IServalBuilderExtensions.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Serval.Assessment.V1; -using Serval.Health.V1; - -namespace Microsoft.Extensions.DependencyInjection; - -public static class IServalBuilderExtensions -{ - public static IServalBuilder AddAssessment(this IServalBuilder builder) - { - builder.AddApiOptions(builder.Configuration.GetSection(ApiOptions.Key)); - builder.AddDataFileOptions(builder.Configuration.GetSection(DataFileOptions.Key)); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - var assessmentOptions = new AssessmentOptions(); - builder.Configuration.GetSection(AssessmentOptions.Key).Bind(assessmentOptions); - - foreach (EngineInfo engine in assessmentOptions.Engines) - { - builder.Services.AddGrpcClient( - engine.Type, - o => o.Address = new Uri(engine.Address) - ); - builder.Services.AddGrpcClient( - $"{engine.Type}-Health", - o => o.Address = new Uri(engine.Address) - ); - builder.Services.AddHealthChecks().AddCheck(engine.Type); - } - - return builder; - } -} diff --git a/src/Serval/src/Serval.Assessment/Consumers/DataFileDeletedConsumer.cs b/src/Serval/src/Serval.Assessment/Consumers/DataFileDeletedConsumer.cs deleted file mode 100644 index 11dde5b4..00000000 --- a/src/Serval/src/Serval.Assessment/Consumers/DataFileDeletedConsumer.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Serval.Assessment.Consumers; - -public class DataFileDeletedConsumer(IEngineService engineService) : IConsumer -{ - private readonly IEngineService _engineService = engineService; - - public Task Consume(ConsumeContext context) - { - return _engineService.DeleteAllCorpusFilesAsync(context.Message.DataFileId, context.CancellationToken); - } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusConfigDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusConfigDto.cs deleted file mode 100644 index 562d3568..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusConfigDto.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentCorpusConfigDto -{ - /// - /// The corpus name. - /// - public string? Name { get; init; } - - /// - /// The language tag. - /// - public required string Language { get; init; } - - /// - /// The corpus files. - /// - public required IReadOnlyList Files { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusDto.cs deleted file mode 100644 index 7be13e2b..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentCorpusDto -{ - public required string Url { get; init; } - public string? Name { get; init; } - public required string Language { get; init; } - public required IReadOnlyList Files { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileConfigDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileConfigDto.cs deleted file mode 100644 index d539d562..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileConfigDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentCorpusFileConfigDto -{ - public required string FileId { get; init; } - - public string? TextId { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileDto.cs deleted file mode 100644 index a9b57925..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentCorpusFileDto.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentCorpusFileDto -{ - public required ResourceLinkDto File { get; init; } - public string? TextId { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineConfigDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineConfigDto.cs deleted file mode 100644 index 81851b79..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineConfigDto.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentEngineConfigDto -{ - /// - /// The assessment engine name. - /// - public string? Name { get; init; } - - /// - /// The assessment engine type. - /// - public required string Type { get; init; } - - /// - /// The corpus. - /// - public required AssessmentCorpusConfigDto Corpus { get; init; } - - /// - /// The reference corpus. - /// - public AssessmentCorpusConfigDto? ReferenceCorpus { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineDto.cs deleted file mode 100644 index aa3951f9..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentEngineDto.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentEngineDto -{ - public required string Id { get; init; } - public required string Url { get; init; } - public string? Name { get; init; } - public required string Type { get; init; } - public required AssessmentCorpusDto Corpus { get; init; } - public AssessmentCorpusDto? ReferenceCorpus { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobConfigDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobConfigDto.cs deleted file mode 100644 index c5e6c276..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobConfigDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentJobConfigDto -{ - public string? Name { get; init; } - public IReadOnlyList? TextIds { get; init; } - public string? ScriptureRange { get; init; } - - /// - /// { - /// "property" : "value" - /// } - /// - public object? Options { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobDto.cs deleted file mode 100644 index 296c6b32..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentJobDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentJobDto -{ - public required string Id { get; init; } - public required string Url { get; init; } - public required int Revision { get; init; } - public string? Name { get; init; } - public required ResourceLinkDto Engine { get; init; } - public IReadOnlyList? TextIds { get; init; } - public string? ScriptureRange { get; init; } - public double? PercentCompleted { get; init; } - public string? Message { get; init; } - - /// - /// The current job state. - /// - public required JobState State { get; init; } - public DateTime? DateFinished { get; init; } - - /// - /// { - /// "property" : "value" - /// } - /// - public object? Options { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Contracts/AssessmentResultDto.cs b/src/Serval/src/Serval.Assessment/Contracts/AssessmentResultDto.cs deleted file mode 100644 index c1289da1..00000000 --- a/src/Serval/src/Serval.Assessment/Contracts/AssessmentResultDto.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Serval.Assessment.Contracts; - -public record AssessmentResultDto -{ - public required string TextId { get; init; } - public required string Ref { get; init; } - public double? Score { get; init; } - public string? Description { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Controllers/AssessmentEnginesController.cs b/src/Serval/src/Serval.Assessment/Controllers/AssessmentEnginesController.cs deleted file mode 100644 index 459d3b34..00000000 --- a/src/Serval/src/Serval.Assessment/Controllers/AssessmentEnginesController.cs +++ /dev/null @@ -1,673 +0,0 @@ -namespace Serval.Assessment.Controllers; - -[ApiVersion(1.0)] -[Route("api/v{version:apiVersion}/assessment/engines")] -[OpenApiTag("Assessment")] -[FeatureGate("Assessment")] -public class AssessmentEnginesController( - IAuthorizationService authService, - IEngineService engineService, - IJobService jobService, - IResultService resultService, - IOptionsMonitor apiOptions, - IUrlService urlService -) : ServalControllerBase(authService) -{ - private static readonly JsonSerializerOptions ObjectJsonSerializerOptions = - new() { Converters = { new ObjectToInferredTypesConverter() } }; - - private readonly IEngineService _engineService = engineService; - private readonly IJobService _jobService = jobService; - private readonly IResultService _resultService = resultService; - private readonly IOptionsMonitor _apiOptions = apiOptions; - private readonly IUrlService _urlService = urlService; - - /// - /// Get all assessment engines. - /// - /// - /// The engines - /// The client is not authenticated. - /// The authenticated client cannot perform the operation. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> GetAllAsync(CancellationToken cancellationToken) - { - return (await _engineService.GetAllAsync(Owner, cancellationToken)).Select(Map); - } - - /// - /// Get an assessment engine. - /// - /// The engine id - /// - /// The engine - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}", Name = Endpoints.GetAssessmentEngine)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> GetAsync( - [NotNull] string id, - CancellationToken cancellationToken - ) - { - Engine engine = await _engineService.GetAsync(id, cancellationToken); - await AuthorizeAsync(engine); - return Ok(Map(engine)); - } - - /// - /// Create a new assessment engine. - /// - /// The engine configuration (see above) - /// - /// The new engine - /// Bad request. Is the engine type correct? - /// The client is not authenticated. - /// The authenticated client cannot perform the operation. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.CreateAssessmentEngines)] - [HttpPost] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(typeof(void), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> CreateAsync( - [FromBody] AssessmentEngineConfigDto engineConfig, - [FromServices] IRequestClient getDataFileClient, - CancellationToken cancellationToken - ) - { - Engine engine = await MapAsync(getDataFileClient, engineConfig, cancellationToken); - Engine updatedEngine = await _engineService.CreateAsync(engine, cancellationToken); - AssessmentEngineDto dto = Map(updatedEngine); - return Created(dto.Url, dto); - } - - /// - /// Delete an assessment engine. - /// - /// The engine id - /// - /// The engine was successfully deleted. - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine does not exist and therefore cannot be deleted. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.DeleteAssessmentEngines)] - [HttpDelete("{id}")] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task DeleteAsync([NotNull] string id, CancellationToken cancellationToken) - { - await AuthorizeAsync(id, cancellationToken); - await _engineService.DeleteAsync(id, cancellationToken); - return Ok(); - } - - /// - /// Get the configuration of the corpus for an assessment engine. - /// - /// The assessment engine id - /// - /// The corpus configuration - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the assessment engine. - /// The engine or corpus does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}/corpus", Name = Endpoints.GetAssessmentCorpus)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> GetCorpusAsync( - [NotNull] string id, - CancellationToken cancellationToken - ) - { - Engine engine = await _engineService.GetAsync(id, cancellationToken); - await AuthorizeAsync(engine); - return Ok(Map(id, Endpoints.GetAssessmentCorpus, engine.Corpus)); - } - - /// - /// Replace the corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The new corpus configuration - /// The data file client - /// - /// The corpus configuration - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the assessment engine. - /// The engine or corpus does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.UpdateAssessmentEngines)] - [HttpPut("{id}/corpus")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> ReplaceCorpusAsync( - [NotNull] string id, - [FromBody] AssessmentCorpusConfigDto corpusConfig, - [FromServices] IRequestClient getDataFileClient, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - Corpus newCorpus = await MapAsync(getDataFileClient, corpusConfig, cancellationToken); - Corpus updatedCorpus = await _engineService.ReplaceCorpusAsync(id, newCorpus, cancellationToken); - return Ok(Map(id, Endpoints.GetAssessmentCorpus, updatedCorpus)); - } - - /// - /// Get the configuration of the reference corpus for an assessment engine. - /// - /// The assessment engine id - /// - /// The corpus configuration - /// The engine does not have a reference corpus. - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the assessment engine. - /// The engine or corpus does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadTranslationEngines)] - [HttpGet("{id}/reference-corpus", Name = Endpoints.GetAssessmentReferenceCorpus)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> GetReferenceCorpusAsync( - [NotNull] string id, - CancellationToken cancellationToken - ) - { - Engine engine = await _engineService.GetAsync(id, cancellationToken); - await AuthorizeAsync(engine); - if (engine.ReferenceCorpus is null) - return NoContent(); - return Ok(Map(id, Endpoints.GetAssessmentReferenceCorpus, engine.ReferenceCorpus)); - } - - /// - /// Replace the reference corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// The data file client - /// - /// The new corpus configuration - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the assessment engine. - /// The engine or corpus does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.UpdateAssessmentEngines)] - [HttpPut("{id}/reference-corpus")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> ReplaceReferenceCorpusAsync( - [NotNull] string id, - [FromBody] AssessmentCorpusConfigDto corpusConfig, - [FromServices] IRequestClient getDataFileClient, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - Corpus newCorpus = await MapAsync(getDataFileClient, corpusConfig, cancellationToken); - Corpus updatedCorpus = await _engineService.ReplaceReferenceCorpusAsync(id, newCorpus, cancellationToken); - return Ok(Map(id, Endpoints.GetAssessmentReferenceCorpus, updatedCorpus)); - } - - /// - /// Get all assessment jobs. - /// - /// The engine id - /// - /// The jobs - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}/jobs")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task>> GetAllJobsAsync( - [NotNull] string id, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - return Ok((await _jobService.GetAllAsync(id, cancellationToken)).Select(Map)); - } - - /// - /// Get an assessment job. - /// - /// - /// If the `minRevision` is not defined, the current job, at whatever state it is, - /// will be immediately returned. If `minRevision` is defined, Serval will wait for - /// up to 40 seconds for the engine to job to the `minRevision` specified, else - /// will timeout. - /// A use case is to actively query the state of the current job, where the subsequent - /// request sets the `minRevision` to the returned `revision` + 1 and timeouts are handled gracefully. - /// This method should use request throttling. - /// Note: Within the returned job, percentCompleted is a value between 0 and 1. - /// - /// The engine id - /// The job id - /// The minimum revision - /// - /// The job - /// The client is not authenticated. - /// The authenticated client does not own the engine. - /// The engine or job does not exist. - /// The long polling request timed out. This is expected behavior if you're using long-polling with the minRevision strategy specified in the docs. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}/jobs/{jobId}", Name = Endpoints.GetAssessmentJob)] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status408RequestTimeout)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> GetJobAsync( - [NotNull] string id, - [NotNull] string jobId, - [FromQuery] long? minRevision, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - if (minRevision != null) - { - (_, EntityChange change) = await TaskEx.Timeout( - ct => _jobService.GetNewerRevisionAsync(jobId, minRevision.Value, ct), - _apiOptions.CurrentValue.LongPollTimeout, - cancellationToken: cancellationToken - ); - return change.Type switch - { - EntityChangeType.None => StatusCode(StatusCodes.Status408RequestTimeout), - EntityChangeType.Delete => NotFound(), - _ => Ok(Map(change.Entity!)), - }; - } - else - { - Job job = await _jobService.GetAsync(jobId, cancellationToken); - return Ok(Map(job)); - } - } - - /// - /// Start an assessment job. - /// - /// The engine id - /// The job config (see remarks) - /// - /// The new job - /// The job configuration was invalid. - /// The client is not authenticated. - /// The authenticated client does not own the engine. - /// The engine does not exist. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.UpdateAssessmentEngines)] - [HttpPost("{id}/jobs")] - [ProducesResponseType(StatusCodes.Status201Created)] - [ProducesResponseType(typeof(void), StatusCodes.Status400BadRequest)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task> StartJobAsync( - [NotNull] string id, - [FromBody] AssessmentJobConfigDto jobConfig, - CancellationToken cancellationToken - ) - { - Engine engine = await _engineService.GetAsync(id, cancellationToken); - await AuthorizeAsync(engine); - Job job = Map(engine, jobConfig); - await _engineService.StartJobAsync(job, cancellationToken); - - AssessmentJobDto dto = Map(job); - return Created(dto.Url, dto); - } - - /// - /// Delete an assessment job. - /// - /// The engine id - /// - /// The job was successfully deleted. - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine does not exist and therefore cannot be deleted. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.DeleteAssessmentEngines)] - [HttpDelete("{id}/jobs/{jobId}")] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task DeleteJobAsync( - [NotNull] string id, - [NotNull] string jobId, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - await _jobService.DeleteAsync(jobId, cancellationToken); - return Ok(); - } - - /// - /// Cancel an assessment job. - /// - /// - /// - /// The engine id - /// The job id - /// - /// The job was cancelled successfully. - /// The job is not active. - /// The client is not authenticated. - /// The authenticated client does not own the engine. - /// The engine does not exist. - /// The engine does not support canceling jobs. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.UpdateAssessmentEngines)] - [HttpPost("{id}/jobs/{jobId}/cancel")] - [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status204NoContent)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status405MethodNotAllowed)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task CancelJobAsync( - [NotNull] string id, - [NotNull] string jobId, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - if (!await _engineService.CancelJobAsync(id, jobId, cancellationToken)) - return NoContent(); - return Ok(); - } - - /// - /// Get all results of an assessment job. - /// - /// The engine id - /// The job id - /// The text id (optional) - /// - /// The results - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine or corpus does not exist. - /// The engine needs to be built first. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}/jobs/{jobId}/results")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status409Conflict)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task>> GetAllResultsAsync( - [NotNull] string id, - [NotNull] string jobId, - [FromQuery] string? textId, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - - IEnumerable results = await _resultService.GetAllAsync(id, jobId, textId, cancellationToken); - return Ok(results.Select(Map)); - } - - /// - /// Get all results for the specified text of an assessment job. - /// - /// The engine id - /// The job id - /// The text id - /// - /// The results - /// The client is not authenticated. - /// The authenticated client cannot perform the operation or does not own the engine. - /// The engine or corpus does not exist. - /// The engine needs to be built first. - /// A necessary service is currently unavailable. Check `/health` for more details. - [Authorize(Scopes.ReadAssessmentEngines)] - [HttpGet("{id}/jobs/{jobId}/results/{textId}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] - [ProducesResponseType(typeof(void), StatusCodes.Status403Forbidden)] - [ProducesResponseType(typeof(void), StatusCodes.Status404NotFound)] - [ProducesResponseType(typeof(void), StatusCodes.Status409Conflict)] - [ProducesResponseType(typeof(void), StatusCodes.Status503ServiceUnavailable)] - public async Task>> GetResultsByTextIdAsync( - [NotNull] string id, - [NotNull] string jobId, - [NotNull] string textId, - CancellationToken cancellationToken - ) - { - await AuthorizeAsync(id, cancellationToken); - - IEnumerable results = await _resultService.GetAllAsync(id, jobId, textId, cancellationToken); - return Ok(results.Select(Map)); - } - - private async Task AuthorizeAsync(string id, CancellationToken cancellationToken) - { - Engine engine = await _engineService.GetAsync(id, cancellationToken); - await AuthorizeAsync(engine); - } - - private AssessmentEngineDto Map(Engine source) - { - return new AssessmentEngineDto - { - Id = source.Id, - Url = _urlService.GetUrl(Endpoints.GetAssessmentEngine, new { id = source.Id }), - Name = source.Name, - Type = source.Type.ToKebabCase(), - Corpus = Map(source.Id, Endpoints.GetAssessmentCorpus, source.Corpus), - ReferenceCorpus = source.ReferenceCorpus is null - ? null - : Map(source.Id, Endpoints.GetAssessmentReferenceCorpus, source.ReferenceCorpus) - }; - } - - private async Task MapAsync( - IRequestClient getDataFileClient, - AssessmentEngineConfigDto source, - CancellationToken cancellationToken - ) - { - return new Engine - { - Name = source.Name, - Type = source.Type.ToPascalCase(), - Owner = Owner, - Corpus = await MapAsync(getDataFileClient, source.Corpus, cancellationToken), - ReferenceCorpus = source.ReferenceCorpus is null - ? null - : await MapAsync(getDataFileClient, source.ReferenceCorpus, cancellationToken) - }; - } - - private static AssessmentResultDto Map(Result source) - { - return new AssessmentResultDto - { - TextId = source.TextId, - Ref = source.Ref, - Score = source.Score, - Description = source.Description - }; - } - - private AssessmentJobDto Map(Job source) - { - return new AssessmentJobDto - { - Id = source.Id, - Url = _urlService.GetUrl(Endpoints.GetAssessmentJob, new { id = source.EngineRef, jobId = source.Id }), - Revision = source.Revision, - Name = source.Name, - Engine = new ResourceLinkDto - { - Id = source.EngineRef, - Url = _urlService.GetUrl(Endpoints.GetAssessmentEngine, new { id = source.EngineRef }) - }, - TextIds = source.TextIds, - ScriptureRange = source.ScriptureRange, - PercentCompleted = source.PercentCompleted, - Message = source.Message, - State = source.State, - DateFinished = source.DateFinished, - Options = source.Options - }; - } - - private static Job Map(Engine engine, AssessmentJobConfigDto source) - { - if (source.TextIds is not null && source.ScriptureRange is not null) - throw new InvalidOperationException("Set at most one of TextIds and ScriptureRange."); - - return new Job - { - EngineRef = engine.Id, - Name = source.Name, - TextIds = source.TextIds?.ToList(), - ScriptureRange = source.ScriptureRange, - Options = Map(source.Options) - }; - } - - private static Dictionary? Map(object? source) - { - try - { - return JsonSerializer.Deserialize>( - source?.ToString() ?? "{}", - ObjectJsonSerializerOptions - ); - } - catch (Exception e) - { - throw new InvalidOperationException($"Unable to parse field 'options' : {e.Message}", e); - } - } - - private AssessmentCorpusDto Map(string engineId, string getCorpusEndpointName, Corpus source) - { - return new AssessmentCorpusDto - { - Url = _urlService.GetUrl(getCorpusEndpointName, new { id = engineId }), - Name = source.Name, - Language = source.Language, - Files = source.Files.Select(Map).ToList() - }; - } - - private AssessmentCorpusFileDto Map(CorpusFile source) - { - return new AssessmentCorpusFileDto - { - File = new ResourceLinkDto - { - Id = source.Id, - Url = _urlService.GetUrl(Endpoints.GetDataFile, new { id = source.Id }) - }, - TextId = source.TextId - }; - } - - private async Task MapAsync( - IRequestClient getDataFileClient, - AssessmentCorpusConfigDto source, - CancellationToken cancellationToken - ) - { - return new Corpus - { - Name = source.Name, - Language = source.Language, - Files = await MapAsync(getDataFileClient, source.Files, cancellationToken) - }; - } - - private async Task> MapAsync( - IRequestClient getDataFileClient, - IEnumerable fileConfigs, - CancellationToken cancellationToken - ) - { - var files = new List(); - foreach (AssessmentCorpusFileConfigDto fileConfig in fileConfigs) - { - Response response = await getDataFileClient.GetResponse< - DataFileResult, - DataFileNotFound - >(new GetDataFile { DataFileId = fileConfig.FileId, Owner = Owner }, cancellationToken); - if (response.Is(out Response? result)) - { - files.Add( - new CorpusFile - { - Id = fileConfig.FileId, - Filename = result.Message.Filename, - TextId = fileConfig.TextId ?? result.Message.Name, - Format = result.Message.Format - } - ); - } - else if (response.Is(out Response? _)) - { - throw new InvalidOperationException($"The data file {fileConfig.FileId} cannot be found."); - } - } - return files; - } -} diff --git a/src/Serval/src/Serval.Assessment/Models/Corpus.cs b/src/Serval/src/Serval.Assessment/Models/Corpus.cs deleted file mode 100644 index 33ef0981..00000000 --- a/src/Serval/src/Serval.Assessment/Models/Corpus.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Serval.Assessment.Models; - -public record Corpus -{ - public string? Name { get; init; } - public required string Language { get; init; } - public required IReadOnlyList Files { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Models/CorpusFile.cs b/src/Serval/src/Serval.Assessment/Models/CorpusFile.cs deleted file mode 100644 index fa491558..00000000 --- a/src/Serval/src/Serval.Assessment/Models/CorpusFile.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Serval.Assessment.Models; - -public record CorpusFile -{ - public required string Id { get; init; } - public required string Filename { get; init; } - public required FileFormat Format { get; init; } - public required string TextId { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Models/Engine.cs b/src/Serval/src/Serval.Assessment/Models/Engine.cs deleted file mode 100644 index 337b8875..00000000 --- a/src/Serval/src/Serval.Assessment/Models/Engine.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Serval.Assessment.Models; - -public record Engine : IOwnedEntity -{ - public string Id { get; set; } = ""; - public int Revision { get; set; } = 1; - public required string Owner { get; init; } - public string? Name { get; init; } - public required string Type { get; init; } - public required Corpus Corpus { get; init; } - public Corpus? ReferenceCorpus { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Models/Job.cs b/src/Serval/src/Serval.Assessment/Models/Job.cs deleted file mode 100644 index c1863e46..00000000 --- a/src/Serval/src/Serval.Assessment/Models/Job.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Serval.Assessment.Models; - -public record Job : IEntity -{ - public string Id { get; set; } = ""; - public int Revision { get; set; } = 1; - public string? Name { get; init; } - public required string EngineRef { get; init; } - public IReadOnlyList? TextIds { get; set; } - public string? ScriptureRange { get; set; } - public double? PercentCompleted { get; init; } - public string? Message { get; init; } - public JobState State { get; init; } = JobState.Pending; - public DateTime? DateFinished { get; init; } - public IReadOnlyDictionary? Options { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Models/Result.cs b/src/Serval/src/Serval.Assessment/Models/Result.cs deleted file mode 100644 index b346f222..00000000 --- a/src/Serval/src/Serval.Assessment/Models/Result.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Serval.Assessment.Models; - -public record Result : IEntity -{ - public string Id { get; set; } = ""; - public int Revision { get; set; } = 1; - public required string EngineRef { get; init; } - public required string JobRef { get; init; } - public required string TextId { get; init; } - public required string Ref { get; init; } - public double? Score { get; init; } - public string? Description { get; init; } -} diff --git a/src/Serval/src/Serval.Assessment/Serval.Assessment.csproj b/src/Serval/src/Serval.Assessment/Serval.Assessment.csproj deleted file mode 100644 index 81b1b5a4..00000000 --- a/src/Serval/src/Serval.Assessment/Serval.Assessment.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - net8.0 - enable - enable - true - true - true - $(NoWarn);CS1591;CS1573 - - - - - - - - - - - - - - - - - diff --git a/src/Serval/src/Serval.Assessment/Services/AssessmentPlatformServiceV1.cs b/src/Serval/src/Serval.Assessment/Services/AssessmentPlatformServiceV1.cs deleted file mode 100644 index 61bd88ce..00000000 --- a/src/Serval/src/Serval.Assessment/Services/AssessmentPlatformServiceV1.cs +++ /dev/null @@ -1,257 +0,0 @@ -using Google.Protobuf.WellKnownTypes; -using Serval.Assessment.V1; - -namespace Serval.Assessment.Services; - -public class AssessmentPlatformServiceV1( - IRepository jobs, - IRepository engines, - IRepository results, - IDataAccessContext dataAccessContext, - IPublishEndpoint publishEndpoint -) : AssessmentPlatformApi.AssessmentPlatformApiBase -{ - private const int ResultInsertBatchSize = 128; - private static readonly Empty Empty = new(); - - private readonly IRepository _jobs = jobs; - private readonly IRepository _engines = engines; - private readonly IRepository _results = results; - private readonly IDataAccessContext _dataAccessContext = dataAccessContext; - private readonly IPublishEndpoint _publishEndpoint = publishEndpoint; - - public override async Task JobStarted(JobStartedRequest request, ServerCallContext context) - { - await _dataAccessContext.WithTransactionAsync( - async (ct) => - { - Job? job = await _jobs.UpdateAsync( - request.JobId, - u => u.Set(b => b.State, JobState.Active), - cancellationToken: ct - ); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - - Engine? engine = await _engines.GetAsync(job.EngineRef, cancellationToken: ct); - if (engine is null) - throw new RpcException(new Status(StatusCode.NotFound, "The engine does not exist.")); - - await _publishEndpoint.Publish( - new AssessmentJobStarted - { - JobId = job.Id, - EngineId = engine.Id, - Owner = engine.Owner - }, - ct - ); - }, - cancellationToken: context.CancellationToken - ); - return Empty; - } - - public override async Task JobCompleted(JobCompletedRequest request, ServerCallContext context) - { - await _dataAccessContext.WithTransactionAsync( - async (ct) => - { - Job? job = await _jobs.UpdateAsync( - request.JobId, - u => - u.Set(b => b.State, JobState.Completed) - .Set(b => b.Message, "Completed") - .Set(b => b.DateFinished, DateTime.UtcNow), - cancellationToken: ct - ); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - - Engine? engine = await _engines.GetAsync(job.EngineRef, cancellationToken: ct); - if (engine is null) - throw new RpcException(new Status(StatusCode.NotFound, "The engine does not exist.")); - - await _publishEndpoint.Publish( - new AssessmentJobFinished - { - JobId = job.Id, - EngineId = engine.Id, - Owner = engine.Owner, - JobState = job.State, - Message = job.Message!, - DateFinished = job.DateFinished!.Value - }, - ct - ); - }, - cancellationToken: context.CancellationToken - ); - - return Empty; - } - - public override async Task JobCanceled(JobCanceledRequest request, ServerCallContext context) - { - await _dataAccessContext.WithTransactionAsync( - async (ct) => - { - Job? job = await _jobs.UpdateAsync( - request.JobId, - u => - { - u.Set(j => j.Message, "Canceled"); - u.Set(j => j.DateFinished, DateTime.UtcNow); - u.Set(j => j.State, JobState.Canceled); - }, - cancellationToken: ct - ); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - - Engine? engine = await _engines.GetAsync(job.EngineRef, cancellationToken: ct); - if (engine is null) - throw new RpcException(new Status(StatusCode.NotFound, "The engine does not exist.")); - - await _publishEndpoint.Publish( - new AssessmentJobFinished - { - JobId = job.Id, - EngineId = engine.Id, - Owner = engine.Owner, - JobState = job.State, - Message = job.Message!, - DateFinished = job.DateFinished!.Value - }, - ct - ); - }, - cancellationToken: context.CancellationToken - ); - - return Empty; - } - - public override async Task JobFaulted(JobFaultedRequest request, ServerCallContext context) - { - await _dataAccessContext.WithTransactionAsync( - async (ct) => - { - Job? job = await _jobs.UpdateAsync( - request.JobId, - u => - { - u.Set(b => b.State, JobState.Faulted); - u.Set(b => b.Message, request.Message); - u.Set(b => b.DateFinished, DateTime.UtcNow); - }, - cancellationToken: ct - ); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - - Engine? engine = await _engines.GetAsync(job.EngineRef, cancellationToken: ct); - if (engine is null) - throw new RpcException(new Status(StatusCode.NotFound, "The engine does not exist.")); - - await _publishEndpoint.Publish( - new AssessmentJobFinished - { - JobId = job.Id, - EngineId = engine.Id, - Owner = engine.Owner, - JobState = job.State, - Message = job.Message!, - DateFinished = job.DateFinished!.Value - }, - ct - ); - }, - cancellationToken: context.CancellationToken - ); - - return Empty; - } - - public override async Task JobRestarting(JobRestartingRequest request, ServerCallContext context) - { - Job? job = await _jobs.UpdateAsync( - request.JobId, - u => - { - u.Set(j => j.Message, "Restarting"); - u.Unset(j => j.PercentCompleted); - u.Set(j => j.State, JobState.Pending); - }, - cancellationToken: context.CancellationToken - ); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - - return Empty; - } - - public override async Task UpdateJobStatus(UpdateJobStatusRequest request, ServerCallContext context) - { - await _jobs.UpdateAsync( - j => j.Id == request.JobId && (j.State == JobState.Active || j.State == JobState.Pending), - u => - { - if (request.HasPercentCompleted) - { - u.Set( - j => j.PercentCompleted, - Math.Round(request.PercentCompleted, 4, MidpointRounding.AwayFromZero) - ); - } - if (request.HasMessage) - u.Set(j => j.Message, request.Message); - }, - cancellationToken: context.CancellationToken - ); - - return Empty; - } - - public override async Task InsertResults( - IAsyncStreamReader requestStream, - ServerCallContext context - ) - { - string jobId = ""; - string engineId = ""; - List batch = []; - await foreach (InsertResultsRequest request in requestStream.ReadAllAsync(context.CancellationToken)) - { - if (jobId != request.JobId) - { - Job? job = await _jobs.GetAsync(request.JobId, context.CancellationToken); - if (job is null) - throw new RpcException(new Status(StatusCode.NotFound, "The job does not exist.")); - engineId = job.EngineRef; - jobId = request.JobId; - } - - batch.Add( - new Result - { - EngineRef = engineId, - JobRef = request.JobId, - TextId = request.TextId, - Ref = request.Ref, - Score = request.HasScore ? request.Score : null, - Description = request.HasDescription ? request.Description : null - } - ); - if (batch.Count == ResultInsertBatchSize) - { - await _results.InsertAllAsync(batch, context.CancellationToken); - batch.Clear(); - } - } - if (batch.Count > 0) - await _results.InsertAllAsync(batch, CancellationToken.None); - - return Empty; - } -} diff --git a/src/Serval/src/Serval.Assessment/Services/EngineService.cs b/src/Serval/src/Serval.Assessment/Services/EngineService.cs deleted file mode 100644 index 01ced93a..00000000 --- a/src/Serval/src/Serval.Assessment/Services/EngineService.cs +++ /dev/null @@ -1,239 +0,0 @@ -using Serval.Assessment.V1; - -namespace Serval.Assessment.Services; - -public class EngineService( - IRepository engines, - IRepository jobs, - IRepository results, - GrpcClientFactory grpcClientFactory, - IOptionsMonitor dataFileOptions, - IDataAccessContext dataAccessContext, - ILoggerFactory loggerFactory, - IScriptureDataFileService scriptureDataFileService -) : OwnedEntityServiceBase(engines), IEngineService -{ - private readonly IRepository _jobs = jobs; - private readonly IRepository _results = results; - private readonly GrpcClientFactory _grpcClientFactory = grpcClientFactory; - private readonly IOptionsMonitor _dataFileOptions = dataFileOptions; - private readonly IDataAccessContext _dataAccessContext = dataAccessContext; - private readonly ILogger _logger = loggerFactory.CreateLogger(); - private readonly IScriptureDataFileService _scriptureDataFileService = scriptureDataFileService; - - public override async Task CreateAsync(Engine engine, CancellationToken cancellationToken = default) - { - try - { - await Entities.InsertAsync(engine, cancellationToken); - var client = _grpcClientFactory.CreateClient(engine.Type); - if (client is null) - throw new InvalidOperationException($"'{engine.Type}' is an invalid engine type."); - var request = new CreateRequest { EngineType = engine.Type, EngineId = engine.Id, }; - if (engine.Name is not null) - request.EngineName = engine.Name; - await client.CreateAsync(request, cancellationToken: cancellationToken); - } - catch - { - await Entities.DeleteAsync(engine, CancellationToken.None); - throw; - } - return engine; - } - - public override async Task DeleteAsync(string id, CancellationToken cancellationToken = default) - { - Engine? engine = await Entities.GetAsync(id, cancellationToken); - if (engine is null) - throw new EntityNotFoundException($"Could not find the Engine '{id}'."); - - var client = _grpcClientFactory.CreateClient(engine.Type); - await client.DeleteAsync( - new DeleteRequest { EngineType = engine.Type, EngineId = engine.Id }, - cancellationToken: cancellationToken - ); - - await _dataAccessContext.WithTransactionAsync( - async (ct) => - { - await Entities.DeleteAsync(id, ct); - await _jobs.DeleteAllAsync(b => b.EngineRef == id, ct); - await _results.DeleteAllAsync(r => r.EngineRef == id, ct); - }, - CancellationToken.None - ); - } - - public async Task ReplaceCorpusAsync( - string id, - Models.Corpus corpus, - CancellationToken cancellationToken = default - ) - { - Engine? engine = await Entities.UpdateAsync( - id, - u => u.Set(e => e.Corpus, corpus), - cancellationToken: cancellationToken - ); - if (engine is null) - throw new EntityNotFoundException($"Could not find the Engine '{id}'."); - return engine.Corpus; - } - - public async Task ReplaceReferenceCorpusAsync( - string id, - Models.Corpus referenceCorpus, - CancellationToken cancellationToken = default - ) - { - Engine? engine = await Entities.UpdateAsync( - id, - u => u.Set(e => e.ReferenceCorpus, referenceCorpus), - cancellationToken: cancellationToken - ); - if (engine is null) - throw new EntityNotFoundException($"Could not find the Engine '{id}'."); - return engine.ReferenceCorpus!; - } - - public async Task StartJobAsync(Job job, CancellationToken cancellationToken = default) - { - Engine engine = await GetAsync(job.EngineRef, cancellationToken); - await _jobs.InsertAsync(job, cancellationToken); - - try - { - AssessmentEngineApi.AssessmentEngineApiClient client = - _grpcClientFactory.CreateClient(engine.Type); - var request = new StartJobRequest - { - EngineType = engine.Type, - EngineId = engine.Id, - JobId = job.Id, - Options = JsonSerializer.Serialize(job.Options), - Corpus = Map(engine.Corpus), - IncludeAll = job.TextIds is null || job.TextIds.Count == 0 - }; - if (engine.ReferenceCorpus is not null) - request.ReferenceCorpus = Map(engine.ReferenceCorpus); - if (job.TextIds is not null) - request.IncludeTextIds.Add(job.TextIds); - if (job.ScriptureRange is not null) - { - if ( - engine.Corpus.Files.Count > 1 - || engine.Corpus.Files[0].Format != Shared.Contracts.FileFormat.Paratext - ) - { - throw new InvalidOperationException($"The engine is not compatible with using a scripture range."); - } - - try - { - ScrVers versification = _scriptureDataFileService - .GetParatextProjectSettings(request.Corpus.Files[0].Location) - .Versification; - Dictionary chapters = ScriptureRangeParser - .GetChapters(job.ScriptureRange, versification) - .ToDictionary(kvp => kvp.Key, kvp => new ScriptureChapters { Chapters = { kvp.Value } }); - request.IncludeChapters.Add(chapters); - } - catch (ArgumentException ae) - { - throw new InvalidOperationException( - $"The scripture range {job.ScriptureRange} is not valid: {ae.Message}" - ); - } - } - - // Log the job request summary - try - { - var jobRequestSummary = (JsonObject)JsonNode.Parse(JsonSerializer.Serialize(request))!; - // correct job options parsing - jobRequestSummary.Remove("Options"); - try - { - jobRequestSummary.Add("Options", JsonNode.Parse(request.Options)); - } - catch (JsonException) - { - jobRequestSummary.Add("Options", "Job \"Options\" failed parsing: " + (request.Options ?? "null")); - } - jobRequestSummary.Add("Event", "JobRequest"); - jobRequestSummary.Add("ClientId", engine.Owner); - _logger.LogInformation("{request}", jobRequestSummary.ToJsonString()); - } - catch (JsonException) - { - _logger.LogInformation("Error parsing job request summary."); - _logger.LogInformation("{request}", JsonSerializer.Serialize(request)); - } - - await client.StartJobAsync(request, cancellationToken: cancellationToken); - } - catch - { - await _jobs.DeleteAsync(job, CancellationToken.None); - throw; - } - } - - public async Task CancelJobAsync(string id, string jobId, CancellationToken cancellationToken = default) - { - Engine? engine = await GetAsync(id, cancellationToken); - if (engine is null) - throw new EntityNotFoundException($"Could not find the Engine '{id}'."); - - AssessmentEngineApi.AssessmentEngineApiClient client = - _grpcClientFactory.CreateClient(engine.Type); - try - { - await client.CancelJobAsync( - new CancelJobRequest - { - EngineType = engine.Type, - EngineId = engine.Id, - JobId = jobId - }, - cancellationToken: cancellationToken - ); - } - catch (RpcException re) - { - if (re.StatusCode is StatusCode.Aborted) - return false; - throw; - } - return true; - } - - public Task DeleteAllCorpusFilesAsync(string dataFileId, CancellationToken cancellationToken = default) - { - return Entities.UpdateAllAsync( - e => e.Corpus.Files.Any(f => f.Id == dataFileId) || e.ReferenceCorpus!.Files.Any(f => f.Id == dataFileId), - u => - { - u.RemoveAll(e => e.Corpus.Files, f => f.Id == dataFileId); - u.RemoveAll(e => e.ReferenceCorpus!.Files, f => f.Id == dataFileId); - }, - cancellationToken - ); - } - - private V1.Corpus Map(Models.Corpus source) - { - return new V1.Corpus { Language = source.Language, Files = { source.Files.Select(Map) } }; - } - - private V1.CorpusFile Map(Models.CorpusFile source) - { - return new V1.CorpusFile - { - TextId = source.TextId, - Format = (V1.FileFormat)source.Format, - Location = Path.Combine(_dataFileOptions.CurrentValue.FilesDirectory, source.Filename) - }; - } -} diff --git a/src/Serval/src/Serval.Assessment/Services/IEngineService.cs b/src/Serval/src/Serval.Assessment/Services/IEngineService.cs deleted file mode 100644 index 4025d6f3..00000000 --- a/src/Serval/src/Serval.Assessment/Services/IEngineService.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Serval.Assessment.Services; - -public interface IEngineService -{ - Task> GetAllAsync(string owner, CancellationToken cancellationToken = default); - Task GetAsync(string id, CancellationToken cancellationToken = default); - - Task CreateAsync(Engine engine, CancellationToken cancellationToken = default); - Task DeleteAsync(string id, CancellationToken cancellationToken = default); - - Task ReplaceCorpusAsync(string id, Corpus corpus, CancellationToken cancellationToken = default); - Task ReplaceReferenceCorpusAsync( - string id, - Corpus referenceCorpus, - CancellationToken cancellationToken = default - ); - - Task StartJobAsync(Job job, CancellationToken cancellationToken = default); - Task CancelJobAsync(string id, string jobId, CancellationToken cancellationToken = default); - - Task DeleteAllCorpusFilesAsync(string dataFileId, CancellationToken cancellationToken = default); -} diff --git a/src/Serval/src/Serval.Assessment/Services/IJobService.cs b/src/Serval/src/Serval.Assessment/Services/IJobService.cs deleted file mode 100644 index 5ceb6f83..00000000 --- a/src/Serval/src/Serval.Assessment/Services/IJobService.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Serval.Assessment.Services; - -public interface IJobService -{ - Task> GetAllAsync(string engineId, CancellationToken cancellationToken = default); - Task DeleteAsync(string id, CancellationToken cancellationToken = default); - Task GetAsync(string id, CancellationToken cancellationToken = default); - Task> GetNewerRevisionAsync( - string id, - long minRevision, - CancellationToken cancellationToken = default - ); -} diff --git a/src/Serval/src/Serval.Assessment/Services/IResultService.cs b/src/Serval/src/Serval.Assessment/Services/IResultService.cs deleted file mode 100644 index 6c5c4a26..00000000 --- a/src/Serval/src/Serval.Assessment/Services/IResultService.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Serval.Assessment.Services; - -public interface IResultService -{ - Task> GetAllAsync( - string engineId, - string jobId, - string? textId = null, - CancellationToken cancellationToken = default - ); -} diff --git a/src/Serval/src/Serval.Assessment/Services/JobService.cs b/src/Serval/src/Serval.Assessment/Services/JobService.cs deleted file mode 100644 index 9bb0bb8f..00000000 --- a/src/Serval/src/Serval.Assessment/Services/JobService.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace Serval.Assessment.Services; - -public class JobService(IDataAccessContext dataAccessContext, IRepository jobs, IRepository results) - : EntityServiceBase(jobs), - IJobService -{ - private readonly IDataAccessContext _dataAccessContext = dataAccessContext; - private readonly IRepository _results = results; - - public async Task> GetAllAsync(string engineId, CancellationToken cancellationToken = default) - { - return await Entities.GetAllAsync(e => e.EngineRef == engineId, cancellationToken); - } - - public override Task DeleteAsync(string id, CancellationToken cancellationToken = default) - { - return _dataAccessContext.WithTransactionAsync( - async ct => - { - Job? job = await Entities.DeleteAsync(id, ct); - if (job is null) - throw new EntityNotFoundException($"Could not find the Job '{id}'."); - - await _results.DeleteAllAsync(r => r.JobRef == id, ct); - }, - cancellationToken - ); - } - - public Task> GetNewerRevisionAsync( - string id, - long minRevision, - CancellationToken cancellationToken = default - ) - { - return GetNewerRevisionAsync(e => e.Id == id, minRevision, cancellationToken); - } - - private async Task> GetNewerRevisionAsync( - Expression> filter, - long minRevision, - CancellationToken cancellationToken = default - ) - { - using ISubscription subscription = await Entities.SubscribeAsync(filter, cancellationToken); - EntityChange curChange = subscription.Change; - if (curChange.Type == EntityChangeType.Delete && minRevision > 1) - return curChange; - while (true) - { - if (curChange.Entity is not null) - { - if (curChange.Type != EntityChangeType.Delete && minRevision <= curChange.Entity.Revision) - return curChange; - } - await subscription.WaitForChangeAsync(cancellationToken: cancellationToken); - curChange = subscription.Change; - if (curChange.Type == EntityChangeType.Delete) - return curChange; - } - } -} diff --git a/src/Serval/src/Serval.Assessment/Services/ResultService.cs b/src/Serval/src/Serval.Assessment/Services/ResultService.cs deleted file mode 100644 index d25c33b2..00000000 --- a/src/Serval/src/Serval.Assessment/Services/ResultService.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Serval.Assessment.Services; - -public class ResultService(IRepository results) : EntityServiceBase(results), IResultService -{ - public async Task> GetAllAsync( - string engineId, - string jobId, - string? textId = null, - CancellationToken cancellationToken = default - ) - { - return await Entities.GetAllAsync( - r => r.EngineRef == engineId && r.JobRef == jobId && (textId == null || r.TextId == textId), - cancellationToken - ); - } -} diff --git a/src/Serval/src/Serval.Assessment/Usings.cs b/src/Serval/src/Serval.Assessment/Usings.cs deleted file mode 100644 index 29d2b2f7..00000000 --- a/src/Serval/src/Serval.Assessment/Usings.cs +++ /dev/null @@ -1,32 +0,0 @@ -global using System.Diagnostics.CodeAnalysis; -global using System.Linq.Expressions; -global using System.Text.Json; -global using System.Text.Json.Nodes; -global using Asp.Versioning; -global using CaseExtensions; -global using Grpc.Core; -global using Grpc.Net.ClientFactory; -global using MassTransit; -global using Microsoft.AspNetCore.Authorization; -global using Microsoft.AspNetCore.Http; -global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Routing; -global using Microsoft.Extensions.Configuration; -global using Microsoft.Extensions.Logging; -global using Microsoft.Extensions.Options; -global using Microsoft.FeatureManagement.Mvc; -global using NSwag.Annotations; -global using Serval.Assessment.Configuration; -global using Serval.Assessment.Consumers; -global using Serval.Assessment.Contracts; -global using Serval.Assessment.Models; -global using Serval.Assessment.Services; -global using Serval.Shared.Configuration; -global using Serval.Shared.Contracts; -global using Serval.Shared.Controllers; -global using Serval.Shared.Models; -global using Serval.Shared.Services; -global using Serval.Shared.Utils; -global using SIL.DataAccess; -global using SIL.Scripture; -global using SIL.ServiceToolkit.Utils; diff --git a/src/Serval/src/Serval.Client/Client.g.cs b/src/Serval/src/Serval.Client/Client.g.cs index ee4ce398..f7645763 100644 --- a/src/Serval/src/Serval.Client/Client.g.cs +++ b/src/Serval/src/Serval.Client/Client.g.cs @@ -478,1978 +478,6 @@ private string ConvertToString(object? value, System.Globalization.CultureInfo c } } - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial interface IAssessmentEnginesClient - { - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all assessment engines. - /// - /// The engines - /// A server side error occurred. - System.Threading.Tasks.Task> GetAllAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Create a new assessment engine. - /// - /// The engine configuration (see above) - /// The new engine - /// A server side error occurred. - System.Threading.Tasks.Task CreateAsync(AssessmentEngineConfig engineConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get an assessment engine. - /// - /// The engine id - /// The engine - /// A server side error occurred. - System.Threading.Tasks.Task GetAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Delete an assessment engine. - /// - /// The engine id - /// The engine was successfully deleted. - /// A server side error occurred. - System.Threading.Tasks.Task DeleteAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get the configuration of the corpus for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// A server side error occurred. - System.Threading.Tasks.Task GetCorpusAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Replace the corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The new corpus configuration - /// The corpus configuration - /// A server side error occurred. - System.Threading.Tasks.Task ReplaceCorpusAsync(string id, AssessmentCorpusConfig corpusConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get the configuration of the reference corpus for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// A server side error occurred. - System.Threading.Tasks.Task GetReferenceCorpusAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Replace the reference corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// The new corpus configuration - /// A server side error occurred. - System.Threading.Tasks.Task ReplaceReferenceCorpusAsync(string id, AssessmentCorpusConfig corpusConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all assessment jobs. - /// - /// The engine id - /// The jobs - /// A server side error occurred. - System.Threading.Tasks.Task> GetAllJobsAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Start an assessment job. - /// - /// The engine id - /// The job config (see remarks) - /// The new job - /// A server side error occurred. - System.Threading.Tasks.Task StartJobAsync(string id, AssessmentJobConfig jobConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get an assessment job. - /// - /// - /// If the `minRevision` is not defined, the current job, at whatever state it is, - ///
will be immediately returned. If `minRevision` is defined, Serval will wait for - ///
up to 40 seconds for the engine to job to the `minRevision` specified, else - ///
will timeout. - ///
A use case is to actively query the state of the current job, where the subsequent - ///
request sets the `minRevision` to the returned `revision` + 1 and timeouts are handled gracefully. - ///
This method should use request throttling. - ///
Note: Within the returned job, percentCompleted is a value between 0 and 1. - ///
- /// The engine id - /// The job id - /// The minimum revision - /// The job - /// A server side error occurred. - System.Threading.Tasks.Task GetJobAsync(string id, string jobId, long? minRevision = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Delete an assessment job. - /// - /// The engine id - /// The job was successfully deleted. - /// A server side error occurred. - System.Threading.Tasks.Task DeleteJobAsync(string id, string jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Cancel an assessment job. - /// - /// The engine id - /// The job id - /// The job was cancelled successfully. - /// A server side error occurred. - System.Threading.Tasks.Task CancelJobAsync(string id, string jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all results of an assessment job. - /// - /// The engine id - /// The job id - /// The text id (optional) - /// The results - /// A server side error occurred. - System.Threading.Tasks.Task> GetAllResultsAsync(string id, string jobId, string? textId = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all results for the specified text of an assessment job. - /// - /// The engine id - /// The job id - /// The text id - /// The results - /// A server side error occurred. - System.Threading.Tasks.Task> GetResultsByTextIdAsync(string id, string jobId, string textId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)); - - } - - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentEnginesClient : IAssessmentEnginesClient - { - #pragma warning disable 8618 - private string _baseUrl; - #pragma warning restore 8618 - - private System.Net.Http.HttpClient _httpClient; - private static System.Lazy _settings = new System.Lazy(CreateSerializerSettings, true); - private Newtonsoft.Json.JsonSerializerSettings _instanceSettings; - - #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public AssessmentEnginesClient(System.Net.Http.HttpClient httpClient) - #pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - { - BaseUrl = "/api/v1"; - _httpClient = httpClient; - Initialize(); - } - - private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings() - { - var settings = new Newtonsoft.Json.JsonSerializerSettings(); - UpdateJsonSerializerSettings(settings); - return settings; - } - - public string BaseUrl - { - get { return _baseUrl; } - set - { - _baseUrl = value; - if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/")) - _baseUrl += '/'; - } - } - - protected Newtonsoft.Json.JsonSerializerSettings JsonSerializerSettings { get { return _instanceSettings ?? _settings.Value; } } - - static partial void UpdateJsonSerializerSettings(Newtonsoft.Json.JsonSerializerSettings settings); - - partial void Initialize(); - - partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, string url); - partial void PrepareRequest(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, System.Text.StringBuilder urlBuilder); - partial void ProcessResponse(System.Net.Http.HttpClient client, System.Net.Http.HttpResponseMessage response); - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all assessment engines. - /// - /// The engines - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> GetAllAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines" - urlBuilder_.Append("assessment/engines"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Create a new assessment engine. - /// - /// The engine configuration (see above) - /// The new engine - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task CreateAsync(AssessmentEngineConfig engineConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (engineConfig == null) - throw new System.ArgumentNullException("engineConfig"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(engineConfig, JsonSerializerSettings); - var content_ = new System.Net.Http.StringContent(json_); - content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); - request_.Content = content_; - request_.Method = new System.Net.Http.HttpMethod("POST"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines" - urlBuilder_.Append("assessment/engines"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 201) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 400) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("Bad request. Is the engine type correct?", status_, responseText_, headers_, null); - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get an assessment engine. - /// - /// The engine id - /// The engine - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task GetAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Delete an assessment engine. - /// - /// The engine id - /// The engine was successfully deleted. - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task DeleteAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("DELETE"); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - return; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist and therefore cannot be deleted.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get the configuration of the corpus for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task GetCorpusAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/corpus" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/corpus"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the assessment engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Replace the corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The new corpus configuration - /// The corpus configuration - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task ReplaceCorpusAsync(string id, AssessmentCorpusConfig corpusConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (corpusConfig == null) - throw new System.ArgumentNullException("corpusConfig"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(corpusConfig, JsonSerializerSettings); - var content_ = new System.Net.Http.StringContent(json_); - content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); - request_.Content = content_; - request_.Method = new System.Net.Http.HttpMethod("PUT"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/corpus" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/corpus"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the assessment engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get the configuration of the reference corpus for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task GetReferenceCorpusAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/reference-corpus" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/reference-corpus"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 204) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not have a reference corpus.", status_, responseText_, headers_, null); - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the assessment engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Replace the reference corpus configuration for an assessment engine. - /// - /// The assessment engine id - /// The corpus configuration - /// The new corpus configuration - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task ReplaceReferenceCorpusAsync(string id, AssessmentCorpusConfig corpusConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (corpusConfig == null) - throw new System.ArgumentNullException("corpusConfig"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(corpusConfig, JsonSerializerSettings); - var content_ = new System.Net.Http.StringContent(json_); - content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); - request_.Content = content_; - request_.Method = new System.Net.Http.HttpMethod("PUT"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/reference-corpus" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/reference-corpus"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the assessment engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all assessment jobs. - /// - /// The engine id - /// The jobs - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> GetAllJobsAsync(string id, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Start an assessment job. - /// - /// The engine id - /// The job config (see remarks) - /// The new job - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task StartJobAsync(string id, AssessmentJobConfig jobConfig, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobConfig == null) - throw new System.ArgumentNullException("jobConfig"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - var json_ = Newtonsoft.Json.JsonConvert.SerializeObject(jobConfig, JsonSerializerSettings); - var content_ = new System.Net.Http.StringContent(json_); - content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json"); - request_.Content = content_; - request_.Method = new System.Net.Http.HttpMethod("POST"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 201) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 400) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The job configuration was invalid.", status_, responseText_, headers_, null); - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get an assessment job. - /// - /// - /// If the `minRevision` is not defined, the current job, at whatever state it is, - ///
will be immediately returned. If `minRevision` is defined, Serval will wait for - ///
up to 40 seconds for the engine to job to the `minRevision` specified, else - ///
will timeout. - ///
A use case is to actively query the state of the current job, where the subsequent - ///
request sets the `minRevision` to the returned `revision` + 1 and timeouts are handled gracefully. - ///
This method should use request throttling. - ///
Note: Within the returned job, percentCompleted is a value between 0 and 1. - ///
- /// The engine id - /// The job id - /// The minimum revision - /// The job - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task GetJobAsync(string id, string jobId, long? minRevision = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobId == null) - throw new System.ArgumentNullException("jobId"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs/{jobId}" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(jobId, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append('?'); - if (minRevision != null) - { - urlBuilder_.Append(System.Uri.EscapeDataString("minRevision")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(minRevision, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); - } - urlBuilder_.Length--; - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or job does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 408) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The long polling request timed out. This is expected behavior if you\'re using long-polling with the minRevision strategy specified in the docs.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Delete an assessment job. - /// - /// The engine id - /// The job was successfully deleted. - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task DeleteJobAsync(string id, string jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobId == null) - throw new System.ArgumentNullException("jobId"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("DELETE"); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs/{jobId}" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(jobId, System.Globalization.CultureInfo.InvariantCulture))); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - return; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist and therefore cannot be deleted.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Cancel an assessment job. - /// - /// The engine id - /// The job id - /// The job was cancelled successfully. - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task CancelJobAsync(string id, string jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobId == null) - throw new System.ArgumentNullException("jobId"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Content = new System.Net.Http.StringContent(string.Empty, System.Text.Encoding.UTF8, "application/json"); - request_.Method = new System.Net.Http.HttpMethod("POST"); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs/{jobId}/cancel" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(jobId, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/cancel"); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - return; - } - else - if (status_ == 204) - { - return; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 405) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine does not support canceling jobs.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all results of an assessment job. - /// - /// The engine id - /// The job id - /// The text id (optional) - /// The results - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> GetAllResultsAsync(string id, string jobId, string? textId = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobId == null) - throw new System.ArgumentNullException("jobId"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs/{jobId}/results" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(jobId, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/results"); - urlBuilder_.Append('?'); - if (textId != null) - { - urlBuilder_.Append(System.Uri.EscapeDataString("textId")).Append('=').Append(System.Uri.EscapeDataString(ConvertToString(textId, System.Globalization.CultureInfo.InvariantCulture))).Append('&'); - } - urlBuilder_.Length--; - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 409) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine needs to be built first.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. - /// - /// Get all results for the specified text of an assessment job. - /// - /// The engine id - /// The job id - /// The text id - /// The results - /// A server side error occurred. - public virtual async System.Threading.Tasks.Task> GetResultsByTextIdAsync(string id, string jobId, string textId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) - { - if (id == null) - throw new System.ArgumentNullException("id"); - - if (jobId == null) - throw new System.ArgumentNullException("jobId"); - - if (textId == null) - throw new System.ArgumentNullException("textId"); - - var client_ = _httpClient; - var disposeClient_ = false; - try - { - using (var request_ = new System.Net.Http.HttpRequestMessage()) - { - request_.Method = new System.Net.Http.HttpMethod("GET"); - request_.Headers.Accept.Add(System.Net.Http.Headers.MediaTypeWithQualityHeaderValue.Parse("application/json")); - - var urlBuilder_ = new System.Text.StringBuilder(); - if (!string.IsNullOrEmpty(_baseUrl)) urlBuilder_.Append(_baseUrl); - // Operation Path: "assessment/engines/{id}/jobs/{jobId}/results/{textId}" - urlBuilder_.Append("assessment/engines/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(id, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/jobs/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(jobId, System.Globalization.CultureInfo.InvariantCulture))); - urlBuilder_.Append("/results/"); - urlBuilder_.Append(System.Uri.EscapeDataString(ConvertToString(textId, System.Globalization.CultureInfo.InvariantCulture))); - - PrepareRequest(client_, request_, urlBuilder_); - - var url_ = urlBuilder_.ToString(); - request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute); - - PrepareRequest(client_, request_, url_); - - var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false); - var disposeResponse_ = true; - try - { - var headers_ = new System.Collections.Generic.Dictionary>(); - foreach (var item_ in response_.Headers) - headers_[item_.Key] = item_.Value; - if (response_.Content != null && response_.Content.Headers != null) - { - foreach (var item_ in response_.Content.Headers) - headers_[item_.Key] = item_.Value; - } - - ProcessResponse(client_, response_); - - var status_ = (int)response_.StatusCode; - if (status_ == 200) - { - var objectResponse_ = await ReadObjectResponseAsync>(response_, headers_, cancellationToken).ConfigureAwait(false); - if (objectResponse_.Object == null) - { - throw new ServalApiException("Response was null which was not expected.", status_, objectResponse_.Text, headers_, null); - } - return objectResponse_.Object; - } - else - if (status_ == 401) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The client is not authenticated.", status_, responseText_, headers_, null); - } - else - if (status_ == 403) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The authenticated client cannot perform the operation or does not own the engine.", status_, responseText_, headers_, null); - } - else - if (status_ == 404) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine or corpus does not exist.", status_, responseText_, headers_, null); - } - else - if (status_ == 409) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The engine needs to be built first.", status_, responseText_, headers_, null); - } - else - if (status_ == 503) - { - string responseText_ = ( response_.Content == null ) ? string.Empty : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("A necessary service is currently unavailable. Check `/health` for more details.", status_, responseText_, headers_, null); - } - else - { - var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false); - throw new ServalApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null); - } - } - finally - { - if (disposeResponse_) - response_.Dispose(); - } - } - } - finally - { - if (disposeClient_) - client_.Dispose(); - } - } - - protected struct ObjectResponseResult - { - public ObjectResponseResult(T responseObject, string responseText) - { - this.Object = responseObject; - this.Text = responseText; - } - - public T Object { get; } - - public string Text { get; } - } - - public bool ReadResponseAsString { get; set; } - - protected virtual async System.Threading.Tasks.Task> ReadObjectResponseAsync(System.Net.Http.HttpResponseMessage response, System.Collections.Generic.IReadOnlyDictionary> headers, System.Threading.CancellationToken cancellationToken) - { - if (response == null || response.Content == null) - { - return new ObjectResponseResult(default(T)!, string.Empty); - } - - if (ReadResponseAsString) - { - var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - try - { - var typedBody = Newtonsoft.Json.JsonConvert.DeserializeObject(responseText, JsonSerializerSettings); - return new ObjectResponseResult(typedBody!, responseText); - } - catch (Newtonsoft.Json.JsonException exception) - { - var message = "Could not deserialize the response body string as " + typeof(T).FullName + "."; - throw new ServalApiException(message, (int)response.StatusCode, responseText, headers, exception); - } - } - else - { - try - { - using (var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) - using (var streamReader = new System.IO.StreamReader(responseStream)) - using (var jsonTextReader = new Newtonsoft.Json.JsonTextReader(streamReader)) - { - var serializer = Newtonsoft.Json.JsonSerializer.Create(JsonSerializerSettings); - var typedBody = serializer.Deserialize(jsonTextReader); - return new ObjectResponseResult(typedBody!, string.Empty); - } - } - catch (Newtonsoft.Json.JsonException exception) - { - var message = "Could not deserialize the response body stream as " + typeof(T).FullName + "."; - throw new ServalApiException(message, (int)response.StatusCode, string.Empty, headers, exception); - } - } - } - - private string ConvertToString(object? value, System.Globalization.CultureInfo cultureInfo) - { - if (value == null) - { - return ""; - } - - if (value is System.Enum) - { - var name = System.Enum.GetName(value.GetType(), value); - if (name != null) - { - var field = System.Reflection.IntrospectionExtensions.GetTypeInfo(value.GetType()).GetDeclaredField(name); - if (field != null) - { - var attribute = System.Reflection.CustomAttributeExtensions.GetCustomAttribute(field, typeof(System.Runtime.Serialization.EnumMemberAttribute)) - as System.Runtime.Serialization.EnumMemberAttribute; - if (attribute != null) - { - return attribute.Value != null ? attribute.Value : name; - } - } - - var converted = System.Convert.ToString(System.Convert.ChangeType(value, System.Enum.GetUnderlyingType(value.GetType()), cultureInfo)); - return converted == null ? string.Empty : converted; - } - } - else if (value is bool) - { - return System.Convert.ToString((bool)value, cultureInfo).ToLowerInvariant(); - } - else if (value is byte[]) - { - return System.Convert.ToBase64String((byte[]) value); - } - else if (value is string[]) - { - return string.Join(",", (string[])value); - } - else if (value.GetType().IsArray) - { - var valueArray = (System.Array)value; - var valueTextArray = new string[valueArray.Length]; - for (var i = 0; i < valueArray.Length; i++) - { - valueTextArray[i] = ConvertToString(valueArray.GetValue(i), cultureInfo); - } - return string.Join(",", valueTextArray); - } - - var result = System.Convert.ToString(value, cultureInfo); - return result == null ? "" : result; - } - } - [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] public partial interface ICorporaClient { @@ -9015,252 +7043,6 @@ public partial class DeploymentInfo } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentEngine - { - [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Id { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Url { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Type { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("corpus", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public AssessmentCorpus Corpus { get; set; } = new AssessmentCorpus(); - - [Newtonsoft.Json.JsonProperty("referenceCorpus", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public AssessmentCorpus? ReferenceCorpus { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentCorpus - { - [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Url { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("language", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Language { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("files", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public System.Collections.Generic.IList Files { get; set; } = new System.Collections.ObjectModel.Collection(); - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentCorpusFile - { - [Newtonsoft.Json.JsonProperty("file", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public ResourceLink File { get; set; } = new ResourceLink(); - - [Newtonsoft.Json.JsonProperty("textId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? TextId { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class ResourceLink - { - [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Id { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Url { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentEngineConfig - { - /// - /// The assessment engine name. - /// - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - /// - /// The assessment engine type. - /// - [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Type { get; set; } = default!; - - /// - /// The corpus. - /// - [Newtonsoft.Json.JsonProperty("corpus", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public AssessmentCorpusConfig Corpus { get; set; } = new AssessmentCorpusConfig(); - - /// - /// The reference corpus. - /// - [Newtonsoft.Json.JsonProperty("referenceCorpus", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public AssessmentCorpusConfig? ReferenceCorpus { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentCorpusConfig - { - /// - /// The corpus name. - /// - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - /// - /// The language tag. - /// - [Newtonsoft.Json.JsonProperty("language", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Language { get; set; } = default!; - - /// - /// The corpus files. - /// - [Newtonsoft.Json.JsonProperty("files", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public System.Collections.Generic.IList Files { get; set; } = new System.Collections.ObjectModel.Collection(); - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentCorpusFileConfig - { - [Newtonsoft.Json.JsonProperty("fileId", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string FileId { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("textId", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? TextId { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentJob - { - [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Id { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Url { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("revision", Required = Newtonsoft.Json.Required.Always)] - public int Revision { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("engine", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required] - public ResourceLink Engine { get; set; } = new ResourceLink(); - - [Newtonsoft.Json.JsonProperty("textIds", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public System.Collections.Generic.IList? TextIds { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("scriptureRange", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? ScriptureRange { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("percentCompleted", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public double? PercentCompleted { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Message { get; set; } = default!; - - /// - /// The current job state. - /// - [Newtonsoft.Json.JsonProperty("state", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] - public JobState State { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("dateFinished", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public System.DateTimeOffset? DateFinished { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("options", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public object? Options { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public enum JobState - { - - [System.Runtime.Serialization.EnumMember(Value = @"Pending")] - Pending = 0, - - [System.Runtime.Serialization.EnumMember(Value = @"Active")] - Active = 1, - - [System.Runtime.Serialization.EnumMember(Value = @"Completed")] - Completed = 2, - - [System.Runtime.Serialization.EnumMember(Value = @"Faulted")] - Faulted = 3, - - [System.Runtime.Serialization.EnumMember(Value = @"Canceled")] - Canceled = 4, - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentJobConfig - { - [Newtonsoft.Json.JsonProperty("name", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Name { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("textIds", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public System.Collections.Generic.IList? TextIds { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("scriptureRange", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? ScriptureRange { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("options", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public object? Options { get; set; } = default!; - - } - - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] - public partial class AssessmentResult - { - [Newtonsoft.Json.JsonProperty("textId", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string TextId { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("ref", Required = Newtonsoft.Json.Required.Always)] - [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] - public string Ref { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("score", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public double? Score { get; set; } = default!; - - [Newtonsoft.Json.JsonProperty("description", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] - public string? Description { get; set; } = default!; - - } - [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] public partial class Corpus { @@ -9626,6 +7408,19 @@ public partial class TranslationCorpus } + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public partial class ResourceLink + { + [Newtonsoft.Json.JsonProperty("id", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Id { get; set; } = default!; + + [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.Always)] + [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] + public string Url { get; set; } = default!; + + } + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] public partial class TranslationCorpusFile { @@ -9915,6 +7710,27 @@ public partial class PretranslateCorpus } + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] + public enum JobState + { + + [System.Runtime.Serialization.EnumMember(Value = @"Pending")] + Pending = 0, + + [System.Runtime.Serialization.EnumMember(Value = @"Active")] + Active = 1, + + [System.Runtime.Serialization.EnumMember(Value = @"Completed")] + Completed = 2, + + [System.Runtime.Serialization.EnumMember(Value = @"Faulted")] + Faulted = 3, + + [System.Runtime.Serialization.EnumMember(Value = @"Canceled")] + Canceled = 4, + + } + [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] public partial class TranslationBuildConfig { @@ -10070,12 +7886,6 @@ public enum WebhookEvent [System.Runtime.Serialization.EnumMember(Value = @"TranslationBuildFinished")] TranslationBuildFinished = 1, - [System.Runtime.Serialization.EnumMember(Value = @"AssessmentJobStarted")] - AssessmentJobStarted = 2, - - [System.Runtime.Serialization.EnumMember(Value = @"AssessmentJobFinished")] - AssessmentJobFinished = 3, - } [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.1.0.0 (NJsonSchema v11.0.2.0 (Newtonsoft.Json v13.0.0.0))")] diff --git a/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/engine.proto b/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/engine.proto deleted file mode 100644 index 2fb422d6..00000000 --- a/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/engine.proto +++ /dev/null @@ -1,62 +0,0 @@ -syntax = "proto3"; - -package serval.assessment.v1; - -import "google/protobuf/empty.proto"; - -service AssessmentEngineApi { - rpc Create(CreateRequest) returns (google.protobuf.Empty); - rpc Delete(DeleteRequest) returns (google.protobuf.Empty); - rpc StartJob(StartJobRequest) returns (google.protobuf.Empty); - rpc CancelJob(CancelJobRequest) returns (google.protobuf.Empty); -} - -message CreateRequest { - string engine_type = 1; - string engine_id = 2; - optional string engine_name = 3; -} - -message DeleteRequest { - string engine_type = 1; - string engine_id = 2; -} - -message StartJobRequest { - string engine_type = 1; - string engine_id = 2; - string job_id = 3; - Corpus corpus = 4; - optional Corpus reference_corpus = 5; - bool include_all = 6; - map include_chapters = 7; - repeated string include_text_ids = 8; - optional string options = 9; -} - -message CancelJobRequest { - string engine_type = 1; - string engine_id = 2; - string job_id = 3; -} - -message ScriptureChapters { - repeated int32 chapters = 1; -} - -message Corpus { - string id = 1; - string language = 2; - repeated CorpusFile files = 3; -} - -message CorpusFile { - string location = 1; - FileFormat format = 2; - string text_id = 3; -} - -enum FileFormat { - FILE_FORMAT_TEXT = 0; - FILE_FORMAT_PARATEXT = 1; -} diff --git a/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/platform.proto b/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/platform.proto deleted file mode 100644 index f49bddd9..00000000 --- a/src/Serval/src/Serval.Grpc/Protos/serval/assessment/v1/platform.proto +++ /dev/null @@ -1,51 +0,0 @@ -syntax = "proto3"; - -package serval.assessment.v1; - -import "google/protobuf/empty.proto"; - -service AssessmentPlatformApi { - rpc UpdateJobStatus(UpdateJobStatusRequest) returns (google.protobuf.Empty); - rpc JobStarted(JobStartedRequest) returns (google.protobuf.Empty); - rpc JobCompleted(JobCompletedRequest) returns (google.protobuf.Empty); - rpc JobCanceled(JobCanceledRequest) returns (google.protobuf.Empty); - rpc JobFaulted(JobFaultedRequest) returns (google.protobuf.Empty); - rpc JobRestarting(JobRestartingRequest) returns (google.protobuf.Empty); - - rpc InsertResults(stream InsertResultsRequest) returns (google.protobuf.Empty); -} - -message UpdateJobStatusRequest { - string job_id = 1; - optional double percent_completed = 2; - optional string message = 3; -} - -message JobStartedRequest { - string job_id = 1; -} - -message JobCompletedRequest { - string job_id = 1; -} - -message JobCanceledRequest { - string job_id = 1; -} - -message JobFaultedRequest { - string job_id = 1; - string message = 2; -} - -message JobRestartingRequest { - string job_id = 1; -} - -message InsertResultsRequest { - string job_id = 1; - string text_id = 2; - string ref = 3; - optional double score = 4; - optional string description = 5; -} diff --git a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinished.cs b/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinished.cs deleted file mode 100644 index 0751a3d1..00000000 --- a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinished.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Serval.Shared.Contracts; - -public record AssessmentJobFinished -{ - public required string JobId { get; init; } - public required string EngineId { get; init; } - public required string Owner { get; init; } - public required JobState JobState { get; init; } - public required string Message { get; init; } - public required DateTime DateFinished { get; init; } -} diff --git a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinishedDto.cs b/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinishedDto.cs deleted file mode 100644 index 9382e35f..00000000 --- a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobFinishedDto.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Serval.Shared.Contracts; - -public record AssessmentJobFinishedDto -{ - public required ResourceLinkDto Job { get; init; } - public required ResourceLinkDto Engine { get; init; } - public required JobState JobState { get; init; } - public required string Message { get; init; } - public required DateTime DateFinished { get; init; } -} diff --git a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStarted.cs b/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStarted.cs deleted file mode 100644 index 4a03d86c..00000000 --- a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStarted.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Serval.Shared.Contracts; - -public record AssessmentJobStarted -{ - public required string JobId { get; init; } - public required string EngineId { get; init; } - public required string Owner { get; init; } -} diff --git a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStartedDto.cs b/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStartedDto.cs deleted file mode 100644 index 16333e02..00000000 --- a/src/Serval/src/Serval.Shared/Contracts/AssessmentJobStartedDto.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Serval.Shared.Contracts; - -public record AssessmentJobStartedDto -{ - public required ResourceLinkDto Job { get; init; } - public required ResourceLinkDto Engine { get; init; } -} diff --git a/src/Serval/src/Serval.Shared/Controllers/Endpoints.cs b/src/Serval/src/Serval.Shared/Controllers/Endpoints.cs index e8e147a0..c12582cc 100644 --- a/src/Serval/src/Serval.Shared/Controllers/Endpoints.cs +++ b/src/Serval/src/Serval.Shared/Controllers/Endpoints.cs @@ -9,11 +9,6 @@ public static class Endpoints public const string GetParallelTranslationCorpus = "GetParallelTranslationCorpus"; public const string GetTranslationBuild = "GetTranslationBuild"; - public const string GetAssessmentEngine = "GetAssessmentEngine"; - public const string GetAssessmentCorpus = "GetAssessmentCorpus"; - public const string GetAssessmentReferenceCorpus = "GetAssessmentReferenceCorpus"; - public const string GetAssessmentJob = "GetAssessmentJob"; - public const string GetWebhook = "GetWebhook"; public const string GetCorpus = "GetCorpus"; diff --git a/src/Serval/src/Serval.Shared/Controllers/Scopes.cs b/src/Serval/src/Serval.Shared/Controllers/Scopes.cs index b94ccf87..c88f06b3 100644 --- a/src/Serval/src/Serval.Shared/Controllers/Scopes.cs +++ b/src/Serval/src/Serval.Shared/Controllers/Scopes.cs @@ -7,11 +7,6 @@ public static class Scopes public const string UpdateTranslationEngines = "update:translation_engines"; public const string DeleteTranslationEngines = "delete:translation_engines"; - public const string CreateAssessmentEngines = "create:assessment_engines"; - public const string ReadAssessmentEngines = "read:assessment_engines"; - public const string UpdateAssessmentEngines = "update:assessment_engines"; - public const string DeleteAssessmentEngines = "delete:assessment_engines"; - public const string CreateHooks = "create:hooks"; public const string ReadHooks = "read:hooks"; public const string DeleteHooks = "delete:hooks"; @@ -29,10 +24,6 @@ public static class Scopes ReadTranslationEngines, UpdateTranslationEngines, DeleteTranslationEngines, - CreateAssessmentEngines, - ReadAssessmentEngines, - UpdateAssessmentEngines, - DeleteAssessmentEngines, CreateHooks, ReadHooks, DeleteHooks, diff --git a/src/Serval/src/Serval.Webhooks/Configuration/IMediatorRegistrationConfiguratorExtensions.cs b/src/Serval/src/Serval.Webhooks/Configuration/IMediatorRegistrationConfiguratorExtensions.cs index 37e15a45..7239bf06 100644 --- a/src/Serval/src/Serval.Webhooks/Configuration/IMediatorRegistrationConfiguratorExtensions.cs +++ b/src/Serval/src/Serval.Webhooks/Configuration/IMediatorRegistrationConfiguratorExtensions.cs @@ -8,8 +8,6 @@ this IMediatorRegistrationConfigurator configurator { configurator.AddConsumer(); configurator.AddConsumer(); - configurator.AddConsumer(); - configurator.AddConsumer(); return configurator; } } diff --git a/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobFinishedConsumer.cs b/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobFinishedConsumer.cs deleted file mode 100644 index 117536f9..00000000 --- a/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobFinishedConsumer.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Serval.Webhooks.Consumers; - -public class AssessmentJobFinishedConsumer(IWebhookService webhookService, IUrlService urlService) - : IConsumer -{ - private readonly IWebhookService _webhookService = webhookService; - private readonly IUrlService _urlService = urlService; - - public async Task Consume(ConsumeContext context) - { - await _webhookService.SendEventAsync( - WebhookEvent.AssessmentJobFinished, - context.Message.Owner, - new AssessmentJobFinishedDto - { - Job = new ResourceLinkDto - { - Id = context.Message.JobId, - Url = _urlService.GetUrl( - Endpoints.GetAssessmentJob, - new { id = context.Message.EngineId, jobId = context.Message.JobId } - ) - }, - Engine = new ResourceLinkDto - { - Id = context.Message.EngineId, - Url = _urlService.GetUrl(Endpoints.GetAssessmentEngine, new { id = context.Message.EngineId })! - }, - JobState = context.Message.JobState, - Message = context.Message.Message, - DateFinished = context.Message.DateFinished - }, - context.CancellationToken - ); - } -} diff --git a/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobStartedConsumer.cs b/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobStartedConsumer.cs deleted file mode 100644 index 06e21d40..00000000 --- a/src/Serval/src/Serval.Webhooks/Consumers/AssessmentJobStartedConsumer.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Serval.Webhooks.Consumers; - -public class AssessmentJobStartedConsumer(IWebhookService webhookService, IUrlService urlService) - : IConsumer -{ - private readonly IWebhookService _webhookService = webhookService; - private readonly IUrlService _urlService = urlService; - - public async Task Consume(ConsumeContext context) - { - await _webhookService.SendEventAsync( - WebhookEvent.AssessmentJobStarted, - context.Message.Owner, - new AssessmentJobStartedDto - { - Job = new ResourceLinkDto - { - Id = context.Message.JobId, - Url = _urlService.GetUrl( - Endpoints.GetAssessmentJob, - new { id = context.Message.EngineId, jobId = context.Message.JobId } - ) - }, - Engine = new ResourceLinkDto - { - Id = context.Message.EngineId, - Url = _urlService.GetUrl(Endpoints.GetAssessmentEngine, new { id = context.Message.EngineId }) - } - }, - context.CancellationToken - ); - } -} diff --git a/src/Serval/src/Serval.Webhooks/Contracts/WebhookEvent.cs b/src/Serval/src/Serval.Webhooks/Contracts/WebhookEvent.cs index 1dc5d0a4..771d0ff8 100644 --- a/src/Serval/src/Serval.Webhooks/Contracts/WebhookEvent.cs +++ b/src/Serval/src/Serval.Webhooks/Contracts/WebhookEvent.cs @@ -4,7 +4,4 @@ public enum WebhookEvent { TranslationBuildStarted, TranslationBuildFinished, - - AssessmentJobStarted, - AssessmentJobFinished } diff --git a/src/Serval/test/Serval.ApiServer.IntegrationTests/AssessmentEngineTests.cs b/src/Serval/test/Serval.ApiServer.IntegrationTests/AssessmentEngineTests.cs deleted file mode 100644 index 328964e2..00000000 --- a/src/Serval/test/Serval.ApiServer.IntegrationTests/AssessmentEngineTests.cs +++ /dev/null @@ -1,223 +0,0 @@ -using Google.Protobuf.WellKnownTypes; -using Serval.Assessment.Models; -using Serval.Assessment.V1; -using static Serval.ApiServer.Utils; - -namespace Serval.ApiServer; - -[TestFixture] -public class AssessmentEngineTests -{ - private const string EngineType = "Test"; - private const string ClientId1 = "client1"; - - [Test] - public async Task CreateAsync() - { - using TestEnvironment env = new(); - DataFiles.Models.DataFile dataFile = await env.AddDataFileAsync(); - - AssessmentEnginesClient client = env.CreateClient(); - AssessmentEngine result = await client.CreateAsync( - new() - { - Name = "test", - Type = EngineType, - Corpus = new() { Language = "en", Files = { new() { FileId = dataFile.Id } } } - } - ); - Assert.That(result.Name, Is.EqualTo("test")); - AssessmentEngine? engine = await client.GetAsync(result.Id); - Assert.That(engine, Is.Not.Null); - Assert.That(engine.Name, Is.EqualTo("test")); - } - - [Test] - public async Task StartJobAsync() - { - using TestEnvironment env = new(); - Engine engine = await env.AddEngineAsync(); - - AssessmentEnginesClient client = env.CreateClient(); - AssessmentJob result = await client.StartJobAsync(engine.Id, new() { Name = "test" }); - Assert.That(result.Name, Is.EqualTo("test")); - AssessmentJob? job = await client.GetJobAsync(engine.Id, result.Id); - Assert.That(job, Is.Not.Null); - Assert.That(job.Name, Is.EqualTo("test")); - } - - [Test] - public async Task GetAllResultsAsync() - { - using TestEnvironment env = new(); - Job job = await env.AddJobAsync(); - await env.Results.InsertAllAsync( - [ - new() - { - EngineRef = job.EngineRef, - JobRef = job.Id, - TextId = "text1", - Ref = "1" - }, - new() - { - EngineRef = job.EngineRef, - JobRef = job.Id, - TextId = "text2", - Ref = "2" - } - ] - ); - - AssessmentEnginesClient client = env.CreateClient(); - - IList results = await client.GetAllResultsAsync(job.EngineRef, job.Id); - Assert.That(results, Has.Count.EqualTo(2)); - - results = await client.GetAllResultsAsync(job.EngineRef, job.Id, textId: "text1"); - Assert.That(results, Has.Count.EqualTo(1)); - Assert.That(results[0].Ref, Is.EqualTo("1")); - } - - private class TestEnvironment : DisposableBase - { - private readonly IServiceScope _scope; - private readonly MongoClient _mongoClient; - - public TestEnvironment() - { - MongoClientSettings clientSettings = new() { LinqProvider = LinqProvider.V2 }; - _mongoClient = new MongoClient(clientSettings); - ResetDatabases(); - - Factory = new ServalWebApplicationFactory(); - _scope = Factory.Services.CreateScope(); - Engines = _scope.ServiceProvider.GetRequiredService>(); - DataFiles = _scope.ServiceProvider.GetRequiredService>(); - Results = _scope.ServiceProvider.GetRequiredService>(); - Jobs = _scope.ServiceProvider.GetRequiredService>(); - - Client = Substitute.For(); - Client - .CreateAsync(Arg.Any(), null, null, Arg.Any()) - .Returns(CreateAsyncUnaryCall(new Empty())); - Client - .DeleteAsync(Arg.Any(), null, null, Arg.Any()) - .Returns(CreateAsyncUnaryCall(new Empty())); - Client - .StartJobAsync(Arg.Any(), null, null, Arg.Any()) - .Returns(CreateAsyncUnaryCall(new Empty())); - Client - .CancelJobAsync(Arg.Any(), null, null, Arg.Any()) - .Returns(CreateAsyncUnaryCall(new Empty())); - Client - .DeleteAsync(Arg.Any(), null, null, Arg.Any()) - .Returns(CreateAsyncUnaryCall(new Empty())); - } - - public ServalWebApplicationFactory Factory { get; } - public IRepository Engines { get; } - public IRepository DataFiles { get; } - public IRepository Results { get; } - public IRepository Jobs { get; } - public AssessmentEngineApi.AssessmentEngineApiClient Client { get; } - - public AssessmentEnginesClient CreateClient(IEnumerable? scope = null) - { - scope ??= - [ - Scopes.CreateAssessmentEngines, - Scopes.ReadAssessmentEngines, - Scopes.UpdateAssessmentEngines, - Scopes.DeleteAssessmentEngines - ]; - HttpClient httpClient = Factory - .WithWebHostBuilder(builder => - { - builder.ConfigureTestServices(services => - { - GrpcClientFactory grpcClientFactory = Substitute.For(); - grpcClientFactory - .CreateClient(EngineType) - .Returns(Client); - services.AddSingleton(grpcClientFactory); - }); - }) - .CreateClient(); - httpClient.DefaultRequestHeaders.Add("Scope", string.Join(" ", scope)); - return new AssessmentEnginesClient(httpClient); - } - - public async Task AddDataFileAsync() - { - DataFiles.Models.DataFile dataFile = - new() - { - Owner = ClientId1, - Format = Shared.Contracts.FileFormat.Paratext, - Id = "f00000000000000000000001", - Name = "file1.zip", - Filename = "file1.zip" - }; - await DataFiles.InsertAsync(dataFile); - return dataFile; - } - - public async Task AddEngineAsync() - { - DataFiles.Models.DataFile dataFile = await AddDataFileAsync(); - Engine engine = - new() - { - Owner = ClientId1, - Type = EngineType, - Corpus = new() - { - Language = "en", - Files = - [ - new() - { - Id = dataFile.Id, - Format = Shared.Contracts.FileFormat.Paratext, - Filename = dataFile.Filename, - TextId = "all" - } - ] - }, - }; - await Engines.InsertAsync(engine); - return engine; - } - - public async Task AddJobAsync() - { - Engine engine = await AddEngineAsync(); - Job job = - new() - { - Name = "test", - EngineRef = engine.Id, - State = Shared.Contracts.JobState.Completed, - Message = "Completed", - DateFinished = DateTime.UtcNow - }; - await Jobs.InsertAsync(job); - return job; - } - - public void ResetDatabases() - { - _mongoClient.DropDatabase("serval_test"); - _mongoClient.DropDatabase("serval_test_jobs"); - } - - protected override void DisposeManagedResources() - { - _scope.Dispose(); - Factory.Dispose(); - ResetDatabases(); - } - } -}