From f2f794a000572e8e4367f70ee8607ce368bf0671 Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Fri, 10 May 2024 12:07:35 +0200 Subject: [PATCH 1/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES --- .../gov/pagopa/node/cfgsync/Application.java | 2 ++ .../controller/SyncCacheController.java | 3 +++ .../service/ApiConfigCacheEhConsumer.java | 5 +++-- .../service/ApiConfigCacheService.java | 19 ++++++++++++++----- .../node/cfgsync/CacheSyncNexiOracleTest.java | 3 ++- .../cfgsync/CacheSyncNexiPostgresTest.java | 4 +++- .../pagopa/node/cfgsync/CacheSyncTest.java | 3 ++- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/Application.java b/src/main/java/it/gov/pagopa/node/cfgsync/Application.java index b044901..4ee6881 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/Application.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/Application.java @@ -4,12 +4,14 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; import javax.annotation.PostConstruct; import java.util.TimeZone; @SpringBootApplication @Slf4j +@EnableAsync public class Application { @Value("${timezone}") diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java b/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java index a3f19bb..93ba2cc 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java @@ -136,6 +136,9 @@ public ResponseEntity> standin() { produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> cache() { log.debug("[NODE-CFG-SYNC] Force {} configuration to update", TargetRefreshEnum.cache.label); + + apiConfigCacheService.asyncRiversamento(); + Map syncStatusEnumMap = apiConfigCacheService.syncCache(); List syncStatusResponseList = syncStatusEnumMap.entrySet() diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java index dda2032..2a52339 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java @@ -7,7 +7,6 @@ import com.azure.messaging.eventhubs.models.EventContext; import com.azure.storage.blob.BlobContainerAsyncClient; import com.azure.storage.blob.BlobContainerClientBuilder; -import it.gov.pagopa.node.cfgsync.model.SyncStatusEnum; import it.gov.pagopa.node.cfgsync.model.TargetRefreshEnum; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -16,7 +15,6 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; -import java.util.Map; @Slf4j @Service @@ -54,6 +52,9 @@ public void processEvent(EventContext eventContext) { TargetRefreshEnum.cache.label, eventContext.getPartitionContext().getPartitionId(), eventContext.getEventData().getSequenceNumber(), eventContext.getEventData().getBodyAsString()); + + apiConfigCacheService.asyncRiversamento(); + try { apiConfigCacheService.syncCache(); } catch (Exception ex) { diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java index 14d2da3..a582116 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java @@ -23,6 +23,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.http.HttpStatus; +import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -143,11 +144,6 @@ public Map syncCache() { saveNexiPostgres(syncStatusMap, configCache); saveNexiOracle(syncStatusMap, configCache); - if(riversamentoEnabled) { - riversamentoElencoServizi(); - riversamentoCdiPreferences(); - } - return composeSyncStatusMapResult(TargetRefreshEnum.cache.label, syncStatusMap); } catch (FeignException fEx) { log.error("[{}] error: {}", TargetRefreshEnum.cache.label, fEx.getMessage(), fEx); @@ -160,6 +156,19 @@ public Map syncCache() { } } + @Async + public void asyncRiversamento() { + if(riversamentoEnabled) { + log.info("riversamento elenco servizi e cdi preferences abilitato"); + try { + riversamentoElencoServizi(); + riversamentoCdiPreferences(); + }catch (Exception e){ + log.error("Errore riversamento",e); + } + } + } + private void savePagoPA(Map syncStatusMap, ConfigCache configCache) { try { if(apiConfigCacheWritePagoPa) { diff --git a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiOracleTest.java b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiOracleTest.java index bb67090..6b3f34d 100644 --- a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiOracleTest.java +++ b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiOracleTest.java @@ -84,7 +84,7 @@ class CacheSyncNexiOracleTest { } @Test - void nexioracle() { + void nexioracle() throws InterruptedException { ReflectionTestUtils.setField(cacheManagerService, "riversamentoSource", "nexi-oracle"); ReflectionTestUtils.setField(cacheManagerService, "riversamentoTarget", "nexi-oracle"); @@ -124,6 +124,7 @@ void nexioracle() { assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(5000); List all = nexiCdiPreferencesOracleRepository.findAll(); assertThat(all.size()).isEqualTo(size); assertThat(all.get(0).getSeller()).isEqualTo(arrayList.get(0).getSeller()); diff --git a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java index ce645ea..654cd11 100644 --- a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java +++ b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java @@ -77,7 +77,7 @@ class CacheSyncNexiPostgresTest { } @Test - void nexipostgres() { + void nexipostgres() throws InterruptedException { ReflectionTestUtils.setField(cacheManagerService, "riversamentoSource", "nexi-postgres"); ReflectionTestUtils.setField(cacheManagerService, "riversamentoTarget", "nexi-postgres"); @@ -117,8 +117,10 @@ void nexipostgres() { assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(5000); List all = nexiCdiPreferencesPostgresRepository.findAll(); assertThat(all.size()).isEqualTo(size); + } } diff --git a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncTest.java b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncTest.java index ab3adbd..9f7f52f 100644 --- a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncTest.java +++ b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncTest.java @@ -168,7 +168,7 @@ void error500ConnectionRefused() { } @Test - void trimCacheVersionOnDb() { + void trimCacheVersionOnDb() throws InterruptedException { long size = Math.round(Math.random()*500); ArrayList arrayList = new ArrayList(); @@ -205,6 +205,7 @@ void trimCacheVersionOnDb() { assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(5000); List all = pagoPaCdiPreferencesPostgresRepository.findAll(); assertThat(all.size()).isEqualTo(size); } From 144618e1cbf6055d695781950a76f52e0468c8f7 Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Fri, 10 May 2024 13:34:15 +0200 Subject: [PATCH 2/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES --- .../gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java index a582116..94533a4 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java @@ -157,6 +157,7 @@ public Map syncCache() { } @Async + @Transactional public void asyncRiversamento() { if(riversamentoEnabled) { log.info("riversamento elenco servizi e cdi preferences abilitato"); From 456e235e1f86fc7760097c6fd2e4f8d1664e6ae2 Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Fri, 10 May 2024 14:45:49 +0200 Subject: [PATCH 3/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES --- .../gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java index 94533a4..829d596 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java @@ -166,6 +166,7 @@ public void asyncRiversamento() { riversamentoCdiPreferences(); }catch (Exception e){ log.error("Errore riversamento",e); + throw e; } } } From 98954e9408cddc0a10008d1d32bcd90f351f45fd Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Fri, 10 May 2024 14:54:32 +0200 Subject: [PATCH 4/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES --- openapi/openapi.json | 384 +++++++++--------- .../cfgsync/CacheSyncNexiPostgresTest.java | 48 +++ 2 files changed, 229 insertions(+), 203 deletions(-) diff --git a/openapi/openapi.json b/openapi/openapi.json index bc023a4..c0c03e4 100644 --- a/openapi/openapi.json +++ b/openapi/openapi.json @@ -1,286 +1,264 @@ { - "openapi": "3.0.1", - "info": { - "title": "cfg-sync", - "description": "Microservice to update configuration schema of Nodo dei Pagamenti", - "termsOfService": "https://www.pagopa.gov.it/", - "version": "0.0.6-3-NOD-866-dev-src" + "openapi" : "3.0.1", + "info" : { + "title" : "cfg-sync", + "description" : "Microservice to update configuration schema of Nodo dei Pagamenti", + "termsOfService" : "https://www.pagopa.gov.it/", + "version" : "0.0.6-3-NOD-866-dev-src" }, - "servers": [ - { - "url": "http://localhost", - "description": "Generated server url" - } - ], - "paths": { - "/ndp/cache": { - "put": { - "tags": [ - "Cache" - ], - "summary": "Force cache configuration to update", - "operationId": "cache", - "responses": { - "200": { - "description": "OK", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "servers" : [ { + "url" : "http://localhost", + "description" : "Generated server url" + } ], + "paths" : { + "/ndp/cache" : { + "put" : { + "tags" : [ "Cache" ], + "summary" : "Force cache configuration to update", + "operationId" : "cache", + "responses" : { + "200" : { + "description" : "OK", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SyncStatusResponse" + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/SyncStatusResponse" } } } } }, - "400": { - "description": "Bad Request", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "400" : { + "description" : "Bad Request", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "401" : { + "description" : "Unauthorized", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } } }, - "429": { - "description": "Too many requests", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "429" : { + "description" : "Too many requests", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } } }, - "500": { - "description": "Service unavailable", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "500" : { + "description" : "Service unavailable", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + } ] }, - "parameters": [ - { - "name": "X-Request-Id", - "in": "header", - "description": "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.", - "schema": { - "type": "string" - } + "parameters" : [ { + "name" : "X-Request-Id", + "in" : "header", + "description" : "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.", + "schema" : { + "type" : "string" } - ] + } ] }, - "/ndp/stand-in": { - "put": { - "tags": [ - "StandIn" - ], - "summary": "Force stand-in configuration to update", - "operationId": "standin", - "responses": { - "200": { - "description": "OK", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "/ndp/stand-in" : { + "put" : { + "tags" : [ "StandIn" ], + "summary" : "Force stand-in configuration to update", + "operationId" : "standin", + "responses" : { + "200" : { + "description" : "OK", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SyncStatusResponse" + "content" : { + "application/json" : { + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/components/schemas/SyncStatusResponse" } } } } }, - "400": { - "description": "Bad Request", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "400" : { + "description" : "Bad Request", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } }, - "401": { - "description": "Unauthorized", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "401" : { + "description" : "Unauthorized", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } } }, - "429": { - "description": "Too many requests", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "429" : { + "description" : "Too many requests", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } } }, - "500": { - "description": "Service unavailable", - "headers": { - "X-Request-Id": { - "description": "This header identifies the call", - "schema": { - "type": "string" + "500" : { + "description" : "Service unavailable", + "headers" : { + "X-Request-Id" : { + "description" : "This header identifies the call", + "schema" : { + "type" : "string" } } }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ProblemJson" + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/ProblemJson" } } } } }, - "security": [ - { - "ApiKey": [] - } - ] + "security" : [ { + "ApiKey" : [ ] + } ] }, - "parameters": [ - { - "name": "X-Request-Id", - "in": "header", - "description": "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.", - "schema": { - "type": "string" - } + "parameters" : [ { + "name" : "X-Request-Id", + "in" : "header", + "description" : "This header identifies the call, if not passed it is self-generated. This ID is returned in the response.", + "schema" : { + "type" : "string" } - ] + } ] } }, - "components": { - "schemas": { - "SyncStatusResponse": { - "required": [ - "serviceIdentifier", - "status" - ], - "type": "object", - "properties": { - "serviceIdentifier": { - "type": "string", - "description": "Database service identifier", - "example": "NDP001" + "components" : { + "schemas" : { + "ProblemJson" : { + "type" : "object", + "properties" : { + "title" : { + "type" : "string", + "description" : "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" + }, + "status" : { + "maximum" : 600, + "minimum" : 100, + "type" : "integer", + "description" : "The HTTP status code generated by the origin server for this occurrence of the problem.", + "format" : "int32", + "example" : 200 }, - "status": { - "type": "string", - "description": "Database sync status result", - "example": "done", - "enum": [ - "DONE", - "DISABLED", - "ROLLBACK", - "ERROR" - ] + "detail" : { + "type" : "string", + "description" : "A human readable explanation specific to this occurrence of the problem.", + "example" : "There was an error processing the request" } } }, - "ProblemJson": { - "type": "object", - "properties": { - "title": { - "type": "string", - "description": "A short, summary of the problem type. Written in english and readable for engineers (usually not suited for non technical stakeholders and not localized); example: Service Unavailable" - }, - "status": { - "maximum": 600, - "minimum": 100, - "type": "integer", - "description": "The HTTP status code generated by the origin server for this occurrence of the problem.", - "format": "int32", - "example": 200 + "SyncStatusResponse" : { + "required" : [ "serviceIdentifier", "status" ], + "type" : "object", + "properties" : { + "serviceIdentifier" : { + "type" : "string", + "description" : "Database service identifier", + "example" : "NDP001" }, - "detail": { - "type": "string", - "description": "A human readable explanation specific to this occurrence of the problem.", - "example": "There was an error processing the request" + "status" : { + "type" : "string", + "description" : "Database sync status result", + "example" : "done", + "enum" : [ "DONE", "DISABLED", "ROLLBACK", "ERROR" ] } } } }, - "securitySchemes": { - "ApiKey": { - "type": "apiKey", - "description": "The API key to access this function app.", - "name": "Ocp-Apim-Subscription-Key", - "in": "header" + "securitySchemes" : { + "ApiKey" : { + "type" : "apiKey", + "description" : "The API key to access this function app.", + "name" : "Ocp-Apim-Subscription-Key", + "in" : "header" } } } -} +} \ No newline at end of file diff --git a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java index 654cd11..329756f 100644 --- a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java +++ b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java @@ -123,4 +123,52 @@ void nexipostgres() throws InterruptedException { } + @Test + void nexipostgres2() throws InterruptedException { + + ReflectionTestUtils.setField(cacheManagerService, "riversamentoEnabled", false); + + long size = Math.round(Math.random()*500); + ArrayList arrayList = new ArrayList(); + for(long i = 0;i> headersCustom = + Map.of( + HEADER_CACHE_ID, List.of(String.valueOf(System.currentTimeMillis())), + HEADER_CACHE_TIMESTAMP, List.of(Instant.now().toString()), + HEADER_CACHE_VERSION, List.of(StringUtils.repeat("*", 50)) + ); + when(apiConfigCacheClient.getCache(anyString())).thenReturn(Response + .builder() + .status(200) + .reason("Mocked") + .headers(headersCustom) + .request(mock(Request.class)) + .body(new byte[0]) + .build()); + cacheManagerService.setApiConfigCacheClient(apiConfigCacheClient); + + ResponseEntity> response = restTemplate.exchange(CACHE_URL, HttpMethod.PUT, null, new ParameterizedTypeReference<>() {}); + + assertThat(response.getBody()).isNotNull(); + assertFalse(response.getHeaders().isEmpty()); + assertFalse(response.getBody().isEmpty()); + assertEquals(3, response.getBody().size()); + assertThat(response.getBody().get(0).getServiceIdentifier()).isEqualTo(PAGOPAPOSTGRES_SI); + assertThat(response.getBody().get(0).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(1).getServiceIdentifier()).isEqualTo(NEXIPOSTGRES_SI); + assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); + assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(5000); + Long afterCount = nexiCdiPreferencesPostgresRepository.count(); + assertThat(afterCount).isEqualTo(originalcount); + + } + } From 921d23c010ad5c6296f3fae8872d4f75be002ba7 Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Fri, 10 May 2024 15:02:51 +0200 Subject: [PATCH 5/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES --- .../cfgsync/CacheSyncNexiPostgresTest.java | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java index 329756f..df864b3 100644 --- a/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java +++ b/src/test/java/it/gov/pagopa/node/cfgsync/CacheSyncNexiPostgresTest.java @@ -171,4 +171,100 @@ void nexipostgres2() throws InterruptedException { } + @Test + void nexipostgres3() throws InterruptedException { + + ReflectionTestUtils.setField(cacheManagerService, "riversamentoSource", "exception"); + ReflectionTestUtils.setField(cacheManagerService, "riversamentoTarget", "nexi-postgres"); + + long size = Math.round(Math.random()*500); + ArrayList arrayList = new ArrayList(); + for(long i = 0;i> headersCustom = + Map.of( + HEADER_CACHE_ID, List.of(String.valueOf(System.currentTimeMillis())), + HEADER_CACHE_TIMESTAMP, List.of(Instant.now().toString()), + HEADER_CACHE_VERSION, List.of(StringUtils.repeat("*", 50)) + ); + when(apiConfigCacheClient.getCache(anyString())).thenReturn(Response + .builder() + .status(200) + .reason("Mocked") + .headers(headersCustom) + .request(mock(Request.class)) + .body(new byte[0]) + .build()); + cacheManagerService.setApiConfigCacheClient(apiConfigCacheClient); + + ResponseEntity> response = restTemplate.exchange(CACHE_URL, HttpMethod.PUT, null, new ParameterizedTypeReference<>() {}); + + assertThat(response.getBody()).isNotNull(); + assertFalse(response.getHeaders().isEmpty()); + assertFalse(response.getBody().isEmpty()); + assertEquals(3, response.getBody().size()); + assertThat(response.getBody().get(0).getServiceIdentifier()).isEqualTo(PAGOPAPOSTGRES_SI); + assertThat(response.getBody().get(0).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(1).getServiceIdentifier()).isEqualTo(NEXIPOSTGRES_SI); + assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); + assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(1000); + long all = nexiCdiPreferencesPostgresRepository.count(); + assertThat(all).isEqualTo(originalcount); + + } + + @Test + void nexipostgres4() throws InterruptedException { + + ReflectionTestUtils.setField(cacheManagerService, "riversamentoSource", "nexi-postgres"); + ReflectionTestUtils.setField(cacheManagerService, "riversamentoTarget", "exception"); + + long size = Math.round(Math.random()*500); + ArrayList arrayList = new ArrayList(); + for(long i = 0;i> headersCustom = + Map.of( + HEADER_CACHE_ID, List.of(String.valueOf(System.currentTimeMillis())), + HEADER_CACHE_TIMESTAMP, List.of(Instant.now().toString()), + HEADER_CACHE_VERSION, List.of(StringUtils.repeat("*", 50)) + ); + when(apiConfigCacheClient.getCache(anyString())).thenReturn(Response + .builder() + .status(200) + .reason("Mocked") + .headers(headersCustom) + .request(mock(Request.class)) + .body(new byte[0]) + .build()); + cacheManagerService.setApiConfigCacheClient(apiConfigCacheClient); + + ResponseEntity> response = restTemplate.exchange(CACHE_URL, HttpMethod.PUT, null, new ParameterizedTypeReference<>() {}); + + assertThat(response.getBody()).isNotNull(); + assertFalse(response.getHeaders().isEmpty()); + assertFalse(response.getBody().isEmpty()); + assertEquals(3, response.getBody().size()); + assertThat(response.getBody().get(0).getServiceIdentifier()).isEqualTo(PAGOPAPOSTGRES_SI); + assertThat(response.getBody().get(0).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(1).getServiceIdentifier()).isEqualTo(NEXIPOSTGRES_SI); + assertThat(response.getBody().get(1).getStatus()).isEqualTo(SyncStatusEnum.DONE); + assertThat(response.getBody().get(2).getServiceIdentifier()).isEqualTo(NEXIORACLE_SI); + assertThat(response.getBody().get(2).getStatus()).isEqualTo(SyncStatusEnum.DONE); + Thread.sleep(1000); + long all = nexiCdiPreferencesPostgresRepository.count(); + assertThat(all).isEqualTo(originalcount); + + } + } From 175d71aedf76b5de589dd946f0182202619f1f4a Mon Sep 17 00:00:00 2001 From: Lorenzo Catalano Date: Wed, 15 May 2024 08:48:48 +0200 Subject: [PATCH 6/6] NOD-883 [CFG-SYNC] Rendere async il riversamento delle tabelle ELENCO_SERVIZI e CDI_PREFERENCES a valle della cache --- .../it/gov/pagopa/node/cfgsync/Application.java | 2 -- .../cfgsync/controller/SyncCacheController.java | 3 +-- .../node/cfgsync/model/TargetRefreshEnum.java | 3 ++- .../cfgsync/service/ApiConfigCacheEhConsumer.java | 10 ++++++++-- .../node/cfgsync/service/ApiConfigCacheService.java | 13 +++---------- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/Application.java b/src/main/java/it/gov/pagopa/node/cfgsync/Application.java index 4ee6881..b044901 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/Application.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/Application.java @@ -4,14 +4,12 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.scheduling.annotation.EnableAsync; import javax.annotation.PostConstruct; import java.util.TimeZone; @SpringBootApplication @Slf4j -@EnableAsync public class Application { @Value("${timezone}") diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java b/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java index 93ba2cc..e087862 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/controller/SyncCacheController.java @@ -137,9 +137,8 @@ public ResponseEntity> standin() { public ResponseEntity> cache() { log.debug("[NODE-CFG-SYNC] Force {} configuration to update", TargetRefreshEnum.cache.label); - apiConfigCacheService.asyncRiversamento(); - Map syncStatusEnumMap = apiConfigCacheService.syncCache(); + apiConfigCacheService.syncRiversamento(); List syncStatusResponseList = syncStatusEnumMap.entrySet() .stream() diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/model/TargetRefreshEnum.java b/src/main/java/it/gov/pagopa/node/cfgsync/model/TargetRefreshEnum.java index 2d2c706..5bc94aa 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/model/TargetRefreshEnum.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/model/TargetRefreshEnum.java @@ -3,7 +3,8 @@ public enum TargetRefreshEnum { cache("api-config-cache"), - standin("stand-in-manager"); + standin("stand-in-manager"), + riversamento("riversamento"); public final String label; diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java index 2a52339..234ac7b 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheEhConsumer.java @@ -53,13 +53,19 @@ public void processEvent(EventContext eventContext) { eventContext.getPartitionContext().getPartitionId(), eventContext.getEventData().getSequenceNumber(), eventContext.getEventData().getBodyAsString()); - apiConfigCacheService.asyncRiversamento(); - try { apiConfigCacheService.syncCache(); } catch (Exception ex) { log.error("[{}][ALERT] Generic Error on consumer: {}", TargetRefreshEnum.cache.label, ex.getMessage(), ex); } + + try { + apiConfigCacheService.syncRiversamento(); + } catch (Exception ex) { + log.error("[{}][ALERT] Generic Error on consumer: {}", TargetRefreshEnum.riversamento.label, ex.getMessage(), ex); + } + + } public void processError(ErrorContext errorContext) { diff --git a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java index 829d596..b1c0018 100644 --- a/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java +++ b/src/main/java/it/gov/pagopa/node/cfgsync/service/ApiConfigCacheService.java @@ -23,7 +23,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.http.HttpStatus; -import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -156,18 +155,12 @@ public Map syncCache() { } } - @Async @Transactional - public void asyncRiversamento() { + public void syncRiversamento() { if(riversamentoEnabled) { log.info("riversamento elenco servizi e cdi preferences abilitato"); - try { - riversamentoElencoServizi(); - riversamentoCdiPreferences(); - }catch (Exception e){ - log.error("Errore riversamento",e); - throw e; - } + riversamentoElencoServizi(); + riversamentoCdiPreferences(); } }