From 8bd09ff93ab612f41c535713f9cc5e6cee81b5a7 Mon Sep 17 00:00:00 2001 From: devinleighsmith <devinleighsmith@gmail.com> Date: Wed, 22 Jan 2025 17:26:16 -0800 Subject: [PATCH 1/3] psp-9893 mayan document queue corrections. --- .../api/Services/DocumentQueueService.cs | 22 +++----- source/backend/scheduler/Startup.cs | 16 ++++-- .../api/Services/DocumentQueueServiceTest.cs | 53 ++++++++++++++++--- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/source/backend/api/Services/DocumentQueueService.cs b/source/backend/api/Services/DocumentQueueService.cs index b4389ed017..03d2d3263e 100644 --- a/source/backend/api/Services/DocumentQueueService.cs +++ b/source/backend/api/Services/DocumentQueueService.cs @@ -212,14 +212,6 @@ public async Task<PimsDocumentQueue> Upload(PimsDocumentQueue documentQueue) } databaseDocumentQueue.DocProcessStartDt = DateTime.UtcNow; - // if the document queued for upload is already in an error state, update the retries. - if (databaseDocumentQueue.DocumentQueueStatusTypeCode == DocumentQueueStatusTypes.PIMS_ERROR.ToString() || databaseDocumentQueue.DocumentQueueStatusTypeCode == DocumentQueueStatusTypes.MAYAN_ERROR.ToString()) - { - this.Logger.LogDebug("Document Queue {documentQueueId}, previously errored, retrying", documentQueue.DocumentQueueId); - databaseDocumentQueue.DocProcessRetries += 1; - databaseDocumentQueue.DocProcessEndDt = null; - } - bool isValid = ValidateQueuedDocument(databaseDocumentQueue, documentQueue); if (!isValid) { @@ -229,6 +221,14 @@ public async Task<PimsDocumentQueue> Upload(PimsDocumentQueue documentQueue) return databaseDocumentQueue; } + // if the document queued for upload is already in an error state, update the retries. + if (databaseDocumentQueue.DocumentQueueStatusTypeCode == DocumentQueueStatusTypes.PIMS_ERROR.ToString() || databaseDocumentQueue.DocumentQueueStatusTypeCode == DocumentQueueStatusTypes.MAYAN_ERROR.ToString()) + { + this.Logger.LogDebug("Document Queue {documentQueueId}, previously errored, retrying", documentQueue.DocumentQueueId); + databaseDocumentQueue.DocProcessRetries = ++databaseDocumentQueue.DocProcessRetries ?? 1; + databaseDocumentQueue.DocProcessEndDt = null; + } + PimsDocument relatedDocument = null; relatedDocument = _documentRepository.TryGetDocumentRelationships(databaseDocumentQueue.DocumentId.Value); if (relatedDocument?.DocumentTypeId == null) @@ -238,12 +238,6 @@ public async Task<PimsDocumentQueue> Upload(PimsDocumentQueue documentQueue) UpdateDocumentQueueStatus(databaseDocumentQueue, DocumentQueueStatusTypes.PIMS_ERROR); return databaseDocumentQueue; } - else if (relatedDocument?.MayanId != null && relatedDocument?.MayanId > 0) - { - this.Logger.LogInformation("Queued document {documentQueueId} already has a mayan id {mayanid}, no further processing required.", databaseDocumentQueue.DocumentQueueId, relatedDocument.MayanId); - UpdateDocumentQueueStatus(databaseDocumentQueue, DocumentQueueStatusTypes.SUCCESS); - return databaseDocumentQueue; // The document poll job should pick this up and fix the document queue status. - } try { diff --git a/source/backend/scheduler/Startup.cs b/source/backend/scheduler/Startup.cs index 74899aab00..698b516cf3 100644 --- a/source/backend/scheduler/Startup.cs +++ b/source/backend/scheduler/Startup.cs @@ -245,7 +245,12 @@ public void ConfigureServices(IServiceCollection services) { options.UseSimpleAssemblyNameTypeSerializer().UseRecommendedSerializerSettings().UseRedisStorage(redisConnection).UseSerilogLogProvider().UseConsole(); }); - services.AddHangfireServer(); + + BackgroundJobServerOptions hangfireOptions = Hangfire.Extensions.Configuration.ConfigurationExtensions.GetHangfireBackgroundJobServerOptions(this.Configuration); + services.AddHangfireServer(options => + { + options.Queues = hangfireOptions.Queues; + }); services.AddHangfireConsoleExtensions(); services.Configure<ForwardedHeadersOptions>(options => @@ -341,10 +346,13 @@ private static void ConfigureSecureHeaders(IApplicationBuilder app) private void ScheduleHangfireJobs(IServiceProvider services) { + BackgroundJobServerOptions hangfireOptions = Hangfire.Extensions.Configuration.ConfigurationExtensions.GetHangfireBackgroundJobServerOptions(this.Configuration); + // provide default definition of all jobs. - RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.UploadQueuedDocuments), x => x.UploadQueuedDocuments(), Cron.Minutely); - RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.RetryQueuedDocuments), x => x.RetryQueuedDocuments(), "0 0 * * *"); - RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.QueryProcessingDocuments), x => x.QueryProcessingDocuments(), Cron.Minutely); + + RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.UploadQueuedDocuments), hangfireOptions.Queues.FirstOrDefault() ?? "default", x => x.UploadQueuedDocuments(), Cron.Minutely); + RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.RetryQueuedDocuments), hangfireOptions.Queues.FirstOrDefault() ?? "default", x => x.RetryQueuedDocuments(), "0 0 * * *"); + RecurringJob.AddOrUpdate<IDocumentQueueService>(nameof(DocumentQueueService.QueryProcessingDocuments), hangfireOptions.Queues.FirstOrDefault() ?? "default", x => x.QueryProcessingDocuments(), Cron.Minutely); // override scheduled jobs with configuration. JobScheduleOptions jobOptions = this.Configuration.GetSection("JobOptions").Get<JobScheduleOptions>(); diff --git a/source/backend/tests/unit/api/Services/DocumentQueueServiceTest.cs b/source/backend/tests/unit/api/Services/DocumentQueueServiceTest.cs index 0c7d48579c..a6704c8c2a 100644 --- a/source/backend/tests/unit/api/Services/DocumentQueueServiceTest.cs +++ b/source/backend/tests/unit/api/Services/DocumentQueueServiceTest.cs @@ -544,24 +544,63 @@ public async Task Upload_ValidationFails_Retries() [Fact] public async Task Upload_RelatedDocument_MayanId() { - var service = CreateDocumentQueueServiceWithPermissions(Permissions.SystemAdmin); // Arrange - var documentQueue = new PimsDocumentQueue { DocumentQueueId = 1, DocumentId = 1, Document = new byte[] { 1, 2, 3 } }; + var service = CreateDocumentQueueServiceWithPermissions(Permissions.SystemAdmin); + var documentQueue = new PimsDocumentQueue + { + DocumentQueueId = 1, + DocumentId = 1, + DocumentQueueStatusTypeCode = DocumentQueueStatusTypes.PENDING.ToString(), + Document = new byte[] { 1, 2, 3 }, + DocProcessRetries = 0, + }; + + var relatedDocument = new PimsDocument + { + DocumentId = 1, + DocumentTypeId = 1, + FileName = "test.pdf", + DocumentStatusTypeCode = "STATUS", + MayanId = 1 + }; + + var documentType = new PimsDocumentTyp + { + DocumentTypeId = 1, + MayanId = 1 + }; + + var documentUploadResponse = new DocumentUploadResponse + { + DocumentExternalResponse = new ExternalResponse<DocumentDetailModel> + { + Status = ExternalResponseStatus.Success, + Payload = new DocumentDetailModel + { + } + }, + MetadataExternalResponse = new List<ExternalResponse<DocumentMetadataModel>>() + }; var documentRepositoryMock = this._helper.GetService<Mock<IDocumentRepository>>(); var documentQueueRepositoryMock = this._helper.GetService<Mock<IDocumentQueueRepository>>(); var documentServiceMock = this._helper.GetService<Mock<IDocumentService>>(); + var documentTypeRepositoryMock = this._helper.GetService<Mock<IDocumentTypeRepository>>(); documentQueueRepositoryMock.Setup(x => x.TryGetById(It.IsAny<long>())).Returns(documentQueue); - documentRepositoryMock.Setup(x => x.TryGetDocumentRelationships(It.IsAny<long>())).Returns(new PimsDocument() { DocumentTypeId = 1, MayanId = 1 }); + documentRepositoryMock.Setup(x => x.TryGetDocumentRelationships(It.IsAny<long>())).Returns(relatedDocument); + documentTypeRepositoryMock.Setup(x => x.GetById(It.IsAny<long>())).Returns(documentType); + documentServiceMock.Setup(x => x.UploadDocumentAsync(It.IsAny<DocumentUploadRequest>(), true)).ReturnsAsync(documentUploadResponse); // Act - var result = await service.Upload(documentQueue); + var result = await service.Upload(documentQueue); // Assert - result.DocumentQueueStatusTypeCode.Should().Be(DocumentQueueStatusTypes.SUCCESS.ToString()); - documentQueueRepositoryMock.Verify(x => x.TryGetById(It.IsAny<long>()), Times.Once); - documentRepositoryMock.Verify(x => x.TryGetDocumentRelationships(It.IsAny<long>()), Times.Once); + result.Should().NotBeNull(); + result.DocumentQueueStatusTypeCode.Should().Be(DocumentQueueStatusTypes.PROCESSING.ToString()); + documentQueueRepositoryMock.Verify(x => x.Update(It.IsAny<PimsDocumentQueue>(), It.IsAny<bool>()), Times.AtLeastOnce); + documentQueueRepositoryMock.Verify(x => x.CommitTransaction(), Times.AtLeastOnce); + documentServiceMock.Verify(x => x.UploadDocumentAsync(It.IsAny<DocumentUploadRequest>(), true), Times.Once); } [Fact] From f2df7fc73c010853cf58b88b1aabefb75f1be01d Mon Sep 17 00:00:00 2001 From: devinleighsmith <devinleighsmith@gmail.com> Date: Wed, 29 Jan 2025 12:43:17 -0800 Subject: [PATCH 2/3] hotfix version bump. --- source/backend/api/Pims.Api.csproj | 4 ++-- source/frontend/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/backend/api/Pims.Api.csproj b/source/backend/api/Pims.Api.csproj index f09d8d6653..a5788ba515 100644 --- a/source/backend/api/Pims.Api.csproj +++ b/source/backend/api/Pims.Api.csproj @@ -2,8 +2,8 @@ <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <UserSecretsId>0ef6255f-9ea0-49ec-8c65-c172304b4926</UserSecretsId> - <Version>5.7.2-96.22</Version> - <AssemblyVersion>5.7.2.96</AssemblyVersion> + <Version>5.7.3-96.22</Version> + <AssemblyVersion>5.7.3.96</AssemblyVersion> <GenerateDocumentationFile>true</GenerateDocumentationFile> <ProjectGuid>{16BC0468-78F6-4C91-87DA-7403C919E646}</ProjectGuid> <TargetFramework>net8.0</TargetFramework> diff --git a/source/frontend/package.json b/source/frontend/package.json index 4932d87988..ac7cb8502c 100644 --- a/source/frontend/package.json +++ b/source/frontend/package.json @@ -1,6 +1,6 @@ { "name": "frontend", - "version": "5.7.2-96.22", + "version": "5.7.3-96.22", "private": true, "dependencies": { "@bcgov/bc-sans": "1.0.1", From 88d046e97ca6af94e26dc07867b5b1b46ac4dbf5 Mon Sep 17 00:00:00 2001 From: devinleighsmith <devinleighsmith@gmail.com> Date: Wed, 29 Jan 2025 15:24:25 -0800 Subject: [PATCH 3/3] psp-9666 hotfix: correct loading of partial property ids. --- .../src/components/maps/leaflet/Layers/util.test.tsx | 5 +++++ source/frontend/src/hooks/layer-api/layerUtils.ts | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/frontend/src/components/maps/leaflet/Layers/util.test.tsx b/source/frontend/src/components/maps/leaflet/Layers/util.test.tsx index dc357301ca..012648e7ad 100644 --- a/source/frontend/src/components/maps/leaflet/Layers/util.test.tsx +++ b/source/frontend/src/components/maps/leaflet/Layers/util.test.tsx @@ -205,5 +205,10 @@ describe('mapUtils tests', () => { const cql = toCqlFilterValue({ PID: '12345678', PIN: '54321' }, { forceExactMatch: true }); expect(cql).toBe("PID = '12345678' AND PIN='54321'"); }); + + it('if property id is specified, exact search should always be used', () => { + const cql = toCqlFilterValue({ PROPERTY_ID: '1' }); + expect(cql).toBe("PROPERTY_ID = '1'"); + }); }); }); diff --git a/source/frontend/src/hooks/layer-api/layerUtils.ts b/source/frontend/src/hooks/layer-api/layerUtils.ts index c54a9fa604..c19baaa751 100644 --- a/source/frontend/src/hooks/layer-api/layerUtils.ts +++ b/source/frontend/src/hooks/layer-api/layerUtils.ts @@ -28,7 +28,8 @@ export const toCqlFilterValue = (object: Record<string, string>, flags?: IWfsCql } else if ( ((key === 'PID' || key === 'PID_PADDED' || key === 'PID_NUMBER') && object[key]?.length === 9) || - flags?.forceExactMatch + flags?.forceExactMatch || + key === 'PROPERTY_ID' ) { cql.push(`${key} = '${object[key]}'`); } else {