From 184eca14eeceb1c035f75d1ecc01bd7af50cb3b3 Mon Sep 17 00:00:00 2001 From: Vitolo-Andrea Date: Mon, 20 Jan 2025 14:08:52 +0100 Subject: [PATCH] redis first impl --- pom.xml | 8 +- .../citizen/configuration/RedissonConfig.java | 21 +++++ .../service/BloomFilterServiceImpl.java | 77 ++++++++++--------- .../citizen/service/CitizenServiceImpl.java | 39 ++++++---- src/main/resources/application.yml | 5 +- 5 files changed, 95 insertions(+), 55 deletions(-) create mode 100644 src/main/java/it/gov/pagopa/onboarding/citizen/configuration/RedissonConfig.java diff --git a/pom.xml b/pom.xml index 1913399..3e512b6 100644 --- a/pom.xml +++ b/pom.xml @@ -40,7 +40,11 @@ org.springframework.boot spring-boot-starter-validation - + + org.redisson + redisson-spring-boot-starter + 3.22.0 + com.azure.spring @@ -90,6 +94,8 @@ mockwebserver test + + diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/configuration/RedissonConfig.java b/src/main/java/it/gov/pagopa/onboarding/citizen/configuration/RedissonConfig.java new file mode 100644 index 0000000..55690cf --- /dev/null +++ b/src/main/java/it/gov/pagopa/onboarding/citizen/configuration/RedissonConfig.java @@ -0,0 +1,21 @@ +package it.gov.pagopa.onboarding.citizen.configuration; + +import org.redisson.Redisson; +import org.redisson.api.RedissonReactiveClient; +import org.redisson.config.Config; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RedissonConfig { + + @Value("${redis.url}") + private String redisUrl; + @Bean + public RedissonReactiveClient redissonClient() { + Config config = new Config(); + config.useSingleServer().setAddress(redisUrl); + return Redisson.create(config).reactive(); + } +} diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/service/BloomFilterServiceImpl.java b/src/main/java/it/gov/pagopa/onboarding/citizen/service/BloomFilterServiceImpl.java index efef5f1..2eaa510 100644 --- a/src/main/java/it/gov/pagopa/onboarding/citizen/service/BloomFilterServiceImpl.java +++ b/src/main/java/it/gov/pagopa/onboarding/citizen/service/BloomFilterServiceImpl.java @@ -1,52 +1,57 @@ package it.gov.pagopa.onboarding.citizen.service; -import com.azure.cosmos.implementation.guava25.hash.BloomFilter; -import com.azure.cosmos.implementation.guava25.hash.Funnels; -import it.gov.pagopa.onboarding.citizen.repository.CitizenRepository; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; +import org.redisson.api.RLock; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; -import java.nio.charset.StandardCharsets; +import org.redisson.api.RBloomFilter; +import org.redisson.api.RedissonClient; + +import java.util.concurrent.TimeUnit; @Service @Slf4j -public class BloomFilterServiceImpl implements BloomFilterService{ - - private final CitizenRepository citizenRepository; - - private BloomFilter bloomFilter; - - public BloomFilterServiceImpl(CitizenRepository citizenRepository) { - this.citizenRepository = citizenRepository; +public class BloomFilterServiceImpl implements BloomFilterService { + + private static final String REDDIS_BF_NAME = "emd-bloom-fiter"; + private static final String REDIS_LOCK_NAME = "startup-task-lock"; + + RBloomFilter bloomFilter ; + public BloomFilterServiceImpl(RedissonClient redissonClient) { + RLock lock = redissonClient.getLock(REDIS_LOCK_NAME); + + try { + if (lock.tryLock(0, TimeUnit.SECONDS)) { + try { + this.bloomFilter = initializeBloomFilter(redissonClient); + // carico dati dal db + log.info("[BLOOM-FILTER-SERVICE] Inizializzazione bloom filter eseguita"); + } finally { + lock.unlock(); + } + } else { + this.bloomFilter = redissonClient.getBloomFilter(REDDIS_BF_NAME); + log.info("BLOOM-FILTER-SERVICE] Un'altra replica sta giĆ  eseguendo l'inizializzazione bloom filter "); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException("Errore durante l'acquisizione del lock.", e); + } } - - - @PostConstruct - public void initializeBloomFilter() { - bloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), 1000000, 0.01); - - citizenRepository.findAll() - .doOnNext(citizenConsent -> - bloomFilter.put(citizenConsent.getFiscalCode())) - .doOnComplete(() -> log.info("Bloom filter initialized")) - .subscribe(); + private RBloomFilter initializeBloomFilter(RedissonClient redissonClient) { + RBloomFilter filter = redissonClient.getBloomFilter(REDDIS_BF_NAME); + filter.tryInit(1000000L, 0.01); + return filter; } - @Override - public boolean mightContain(String fiscalCode) { - return bloomFilter.mightContain(fiscalCode); + public void add(String value) { + bloomFilter.add(value); } - - @Scheduled(fixedRate = 3600000) - public void update() { - this.initializeBloomFilter(); + public boolean mightContain(String value) { + return bloomFilter.contains(value); } - public void add(String fiscalCode){ - bloomFilter.put(fiscalCode); - } -} + //Valutare re-inizializzaione temporizata per rimuovere eventuali elementi +} \ No newline at end of file diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java index aebd6ed..0143a34 100644 --- a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java +++ b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java @@ -46,7 +46,7 @@ public CitizenServiceImpl(CitizenRepository citizenRepository, @Override public Mono createCitizenConsent(String fiscalCode, String tppId){ - log.info("[EMD][CITIZEN][UPDATE-CHANNEL-STATE] Received hashedFiscalCode: {} and tppId: {}", + log.info("[EMD-CITIZEN][CREATE-CITIZEN-CONSENT] Received hashedFiscalCode: {} and tppId: {}", Utils.createSHA256(fiscalCode), inputSanify(tppId)); return tppConnector.get(tppId) @@ -84,17 +84,17 @@ public Mono createCitizenConsent(String fiscalCode, String tp .build(); return citizenRepository .save(citizenConsentToSave) - .map(mapperToDTO::map); + .map(mapperToDTO::map) + .doOnSuccess(citizenConsentSaved -> bloomFilterService.add(fiscalCode)); })) ) - .doOnSuccess(savedConsent -> { - log.info("[EMD][CREATE-CITIZEN-CONSENT] Created new citizen consent for fiscal code: {}", Utils.createSHA256(fiscalCode)); - bloomFilterService.add(fiscalCode); - }); + .doOnSuccess(savedConsent -> + log.info("[EMD-CITIZEN][CREATE-CITIZEN-CONSENT] Created new citizen consent for fiscal code: {}", Utils.createSHA256(fiscalCode)) + ); } @Override public Mono switchState(String fiscalCode, String tppId){ - log.info("[EMD][CITIZEN][UPDATE-CHANNEL-STATE] Received hashedFiscalCode: {} and tppId: {}", + log.info("[EMD-CITIZEN][UPDATE-CHANNEL-STATE] Received hashedFiscalCode: {} and tppId: {}", Utils.createSHA256(fiscalCode), inputSanify(tppId)); return citizenRepository.findByFiscalCode(fiscalCode) @@ -109,13 +109,14 @@ public Mono switchState(String fiscalCode, String tppId){ consentDetails.setTppState(!consentDetails.getTppState()); return citizenRepository.save(citizenConsent) .flatMap(savedConsent -> { + Map consents = new HashMap<>(); consents.put(tppId, citizenConsent.getConsents().get(tppId)); citizenConsent.setConsents(consents); return Mono.just(mapperToDTO.map(citizenConsent)); }); }) - .doOnSuccess(savedConsent -> log.info("[EMD][CITIZEN][UPDATE-CHANNEL-STATE] Updated state")); + .doOnSuccess(savedConsent -> log.info("[EMD-CITIZEN][UPDATE-CHANNEL-STATE] Updated state for fiscal code: {}", Utils.createSHA256(fiscalCode))); } @Override @@ -125,7 +126,7 @@ public Mono getCitizenConsentStatus(String fiscalCode, String .switchIfEmpty(Mono.error(exceptionMap.throwException (ExceptionName.CITIZEN_NOT_ONBOARDED, "Citizen consent not founded"))) .map(mapperToDTO::map) - .doOnSuccess(consent -> log.info("[EMD-CITIZEN][GET-CONSENT-STATUS] Consent consent found: {}", consent)); + .doOnSuccess(consent -> log.info("[EMD-CITIZEN][GET-CONSENT-STATUS] Consent consent found for fiscal code: {}", Utils.createSHA256(fiscalCode))); } @@ -141,9 +142,9 @@ public Mono> getTppEnabledList(String fiscalCode) { .toList()) .doOnSuccess(tppIdList -> { if (tppIdList != null){ - log.info("EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Consents found: {}", (tppIdList.size())); + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Founded {} Consents for fiscal code: {}", tppIdList.size(),Utils.createSHA256(fiscalCode)); } else { - log.info("EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] No consents found."); + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] No consents found."); } }); } @@ -155,7 +156,7 @@ public Mono getCitizenConsentsList(String fiscalCode) { .switchIfEmpty(Mono.error(exceptionMap.throwException (ExceptionName.CITIZEN_NOT_ONBOARDED, "Citizen consent not founded during get process "))) .map(mapperToDTO::map) - .doOnSuccess(consentList -> log.info("[EMD-CITIZEN][FIND-ALL-CITIZEN-CONSENTS] Consents found: {}", consentList)); + .doOnSuccess(consentList -> log.info("[EMD-CITIZEN][FIND-ALL-CITIZEN-CONSENTS] Consents for fiscal code: {}", Utils.createSHA256(fiscalCode))); } @Override @@ -175,9 +176,9 @@ public Mono getCitizenConsentsListEnabled(String fiscalCode) }) .doOnSuccess(citizenConsent -> { if (citizenConsent != null && !citizenConsent.getConsents().isEmpty()) { - log.info("EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Consents found: {}", citizenConsent.getConsents().size()); + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Funded {} consents for fiscal code: {} ", citizenConsent.getConsents().size(), Utils.createSHA256(fiscalCode)); } else { - log.info("EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] No consents found."); + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] No consents found."); } }); @@ -188,9 +189,15 @@ public Mono getCitizenConsentsListEnabled(String fiscalCode) public Mono> getCitizenEnabled(String tppId) { return citizenRepository.findByTppIdEnabled(tppId) .map(mapperToDTO::map) - .collectList(); + .collectList() + .doOnSuccess(citizenConsent -> { + if (citizenConsent != null && !citizenConsent.isEmpty()) { + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Funded {} citizen for tpp: {} ", citizenConsent.size(), tppId); + } else { + log.info("[EMD-CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] No consents found."); + } + }); } - @Override public Mono deleteCitizenConsent(String fiscalCode) { return citizenRepository.findByFiscalCode(fiscalCode) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 74fb1cc..69deca6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -22,7 +22,6 @@ spring: maxConnectionIdleTimeMS: ${MONGODB_CONNECTIONPOOL_MAX_CONNECTION_IDLE_MS:120000} maxConnecting: ${MONGODB_CONNECTIONPOOL_MAX_CONNECTING:2} - management: health: mongo.enabled: ${HEALTH_MONGO_ENABLED:false} @@ -40,4 +39,6 @@ management: exposure.include: info, health rest-client: tpp: - baseUrl: ${EMD_TPP:http://emd-tpp} \ No newline at end of file + baseUrl: ${EMD_TPP:http://emd-tpp} +redis: + url:${REDIS_CONNECTION_URL:redis://localhost:6379} \ No newline at end of file