diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/ReportTemplateResource.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/ReportTemplateResource.java index 02d3cd8..58f7ad2 100644 --- a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/ReportTemplateResource.java +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/resource/ReportTemplateResource.java @@ -14,11 +14,7 @@ public interface ReportTemplateResource { String REPORT_TEMPLATE_PATH = "/report-templates"; - String REPORT_TEMPLATE_UPLOAD_PATH = "/upload-template"; - - String TEMPLATE_ID = "templateId"; - - String TEMPLATE_ID_PATH_VARIABLE = "/template-id/{" + TEMPLATE_ID + "}"; + String EVICT_REPORT_TEMPLATE_CACHE_PATH = "/evict-report-template-cache"; String DOSSIER_TEMPLATE_ID = "dossierTemplateId"; @@ -29,7 +25,7 @@ public interface ReportTemplateResource { List getReportTemplatesByPlaceholder(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestBody JSONPrimitive placeholder); - @PostMapping(value = REPORT_TEMPLATE_UPLOAD_PATH + TEMPLATE_ID_PATH_VARIABLE) - void uploadTemplate(@PathVariable(TEMPLATE_ID) String templateId); + @PostMapping(value = EVICT_REPORT_TEMPLATE_CACHE_PATH) + void evictReportTemplateCache(); } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts b/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts index 01404a5..6c8e73d 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts +++ b/redaction-report-service-v1/redaction-report-service-server-v1/build.gradle.kts @@ -50,6 +50,9 @@ dependencies { implementation("org.springframework.cloud:spring-cloud-starter-openfeign:4.1.1") implementation("org.apache.commons:commons-lang3:3.12.0") + implementation("org.springframework.boot:spring-boot-starter-cache:${springBootStarterVersion}") + implementation("org.springframework.boot:spring-boot-starter-data-redis:${springBootStarterVersion}") + implementation("com.github.ben-manes.caffeine:caffeine:3.1.8") implementation("net.logstash.logback:logstash-logback-encoder:7.4") diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/RedisCachingConfiguration.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/RedisCachingConfiguration.java new file mode 100644 index 0000000..107c6de --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/RedisCachingConfiguration.java @@ -0,0 +1,31 @@ +package com.iqser.red.service.redaction.report.v1.server.cache; + +import java.time.Duration; + +import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; + +@Configuration +public class RedisCachingConfiguration { + + @Bean + public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() { + + return (builder) -> builder.withCacheConfiguration("reportTemplateCache", + RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(30)).disableCachingNullValues()); + } + + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + return template; + } + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/ReportTemplateCache.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/ReportTemplateCache.java new file mode 100644 index 0000000..2495eb5 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/cache/ReportTemplateCache.java @@ -0,0 +1,32 @@ +package com.iqser.red.service.redaction.report.v1.server.cache; + +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ReportTemplateCache { + + private final ReportStorageService reportStorageService; + + @Cacheable(value = "reportTemplateCache") + public byte[] getTemplate(String storageId) { + + log.info("Putting report template with storageId {} into cache", storageId); + return reportStorageService.getReportTemplate(storageId); + } + + + @CacheEvict(value = "reportTemplateCache", allEntries = true) + public void evictReportTemplateCache() { + log.info("Evicted cache for report templates"); + } + +} \ No newline at end of file diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/ReportTemplateController.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/ReportTemplateController.java index 4477906..3da26d8 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/ReportTemplateController.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/ReportTemplateController.java @@ -10,7 +10,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSON import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.ReportTemplate; import com.iqser.red.service.redaction.report.v1.api.resource.ReportTemplateResource; import com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService; -import com.iqser.red.service.redaction.report.v1.server.utils.TemplateCache; +import com.iqser.red.service.redaction.report.v1.server.cache.ReportTemplateCache; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j; public class ReportTemplateController implements ReportTemplateResource { private final PlaceholderService placeholderService; + private final ReportTemplateCache reportTemplateCache; @Override @@ -30,15 +31,10 @@ public class ReportTemplateController implements ReportTemplateResource { } - /** - * If a template with the same id is uploaded we evict it from the cache. - * - * @param templateId The id for the uploaded template - */ @Override - public void uploadTemplate(String templateId) { + public void evictReportTemplateCache(){ - TemplateCache.evictCache(templateId); + reportTemplateCache.evictReportTemplateCache(); } } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportTemplateService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportTemplateService.java index 39cc6e8..eb03bd6 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportTemplateService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ExcelReportTemplateService.java @@ -21,7 +21,7 @@ import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEnt import com.iqser.red.service.redaction.report.v1.server.model.ReportTemplatesModel; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageServiceAsyncWrapper; -import com.iqser.red.service.redaction.report.v1.server.utils.TemplateCache; +import com.iqser.red.service.redaction.report.v1.server.cache.ReportTemplateCache; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -37,6 +37,7 @@ public class ExcelReportTemplateService { ExcelReportGenerationService excelTemplateReportGenerationService; GeneratePlaceholderService generatePlaceholderService; ReportStorageServiceAsyncWrapper reportStorageServiceAsyncWrapper; + ReportTemplateCache reportTemplateCache; public CompletableFuture createExcelReportFromTemplateAsync(Dossier dossier, @@ -47,7 +48,7 @@ public class ExcelReportTemplateService { List reportEntries, ReportTemplate reportTemplate) { - byte[] excelTemplate = TemplateCache.getTemplate(reportTemplate.getStorageId(), reportStorageService); + byte[] excelTemplate = reportTemplateCache.getTemplate(reportTemplate.getStorageId()); try (ByteArrayInputStream is = new ByteArrayInputStream(excelTemplate)) { XSSFWorkbook readWorkbook = new XSSFWorkbook(is); SXSSFWorkbook writeWorkbook = new SXSSFWorkbook(); @@ -80,7 +81,7 @@ public class ExcelReportTemplateService { public void prepareExcelReportTemplates(String dossierTemplateId, String templateId, ReportTemplate reportTemplate, ReportTemplatesModel reportTemplatesModel) { - byte[] excelTemplate = TemplateCache.getTemplate(reportTemplate.getStorageId(), reportStorageService); + byte[] excelTemplate = reportTemplateCache.getTemplate(reportTemplate.getStorageId()); try (ByteArrayInputStream is = new ByteArrayInputStream(excelTemplate)) { XSSFWorkbook readWorkbook = new XSSFWorkbook(is); SXSSFWorkbook writeWorkbook = new SXSSFWorkbook(); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java index d182fe2..e90d8f9 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java @@ -7,9 +7,6 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.springframework.stereotype.Service; @@ -29,7 +26,6 @@ import com.iqser.red.service.redaction.report.v1.server.model.ReportTemplatesMod import com.iqser.red.service.redaction.report.v1.server.settings.ReportTemplateSettings; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageServiceAsyncWrapper; -import com.iqser.red.service.redaction.report.v1.server.utils.TemplateCache; import io.micrometer.core.annotation.Timed; import lombok.AccessLevel; diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportTemplateService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportTemplateService.java index c3c52c9..3ca8051 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportTemplateService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportTemplateService.java @@ -19,7 +19,7 @@ import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEnt import com.iqser.red.service.redaction.report.v1.server.model.ReportTemplatesModel; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageServiceAsyncWrapper; -import com.iqser.red.service.redaction.report.v1.server.utils.TemplateCache; +import com.iqser.red.service.redaction.report.v1.server.cache.ReportTemplateCache; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; @@ -34,6 +34,7 @@ public class WordReportTemplateService { ReportStorageService reportStorageService; ReportStorageServiceAsyncWrapper reportStorageServiceAsyncWrapper; WordReportGenerationService wordReportGenerationService; + ReportTemplateCache reportTemplateCache; public CompletableFuture createWordReportFromTemplateAsync(Dossier dossier, FileModel fileStatus, @@ -43,7 +44,7 @@ public class WordReportTemplateService { List reportEntries, ReportTemplate reportTemplate) { - byte[] wordTemplate = TemplateCache.getTemplate(reportTemplate.getStorageId(), reportStorageService); + byte[] wordTemplate = reportTemplateCache.getTemplate(reportTemplate.getStorageId()); try (ByteArrayInputStream is = new ByteArrayInputStream(wordTemplate)) { XWPFDocument doc = new XWPFDocument(is); wordReportGenerationService.generateWordReport(reportEntries, placeholderModel, templateName, doc, fileStatus, dossier, true); @@ -60,7 +61,7 @@ public class WordReportTemplateService { public void prepareWordReportTemplates(String templateId, ReportTemplate reportTemplate, ReportTemplatesModel reportTemplatesModel) { - byte[] wordTemplate = TemplateCache.getTemplate(reportTemplate.getStorageId(), reportStorageService); + byte[] wordTemplate = reportTemplateCache.getTemplate(reportTemplate.getStorageId()); try (ByteArrayInputStream is = new ByteArrayInputStream(wordTemplate)) { XWPFDocument doc = new XWPFDocument(is); MultiFileDocument multiFileDocument = new MultiFileDocument(wordTemplate, doc, templateId, reportTemplate.getFileName(), 0, 0); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/utils/TemplateCache.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/utils/TemplateCache.java deleted file mode 100644 index 3d79fbf..0000000 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/utils/TemplateCache.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.iqser.red.service.redaction.report.v1.server.utils; - -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; - -import lombok.extern.slf4j.Slf4j; - -/** - * This is a caching mechanism for templates to avoid getting a template from storage for each file when we request a download, - * since the templates are provided at startup. - */ -@Slf4j -public class TemplateCache { - - private static final Cache cache = Caffeine.newBuilder().maximumSize(500).build(); - - - public static byte[] getTemplate(String templateId, ReportStorageService reportStorageService) { - - return cache.get(templateId, reportStorageService::getReportTemplate); - } - - - public static void evictCache(String templateId) { - - log.info("Evicting cache for template {}", templateId); - cache.invalidate(templateId); - } - -} \ No newline at end of file diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/application.yml b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/application.yml index f3b3558..baa2a2f 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/application.yml +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/application.yml @@ -38,6 +38,8 @@ spring: max-attempts: 3 max-interval: 15000 prefetch: 1 + cache: + type: redis data: mongodb: auto-index-creation: true @@ -47,7 +49,12 @@ spring: port: ${MONGODB_PORT:27017} username: ${MONGODB_USER} password: ${MONGODB_PASSWORD} - + redis: + database: 0 + host: ${REDIS_HOST:localhost} + port: ${REDIS_PORT:6379} + password: ${REDIS_PASSWORD} + timeout: 60000 management: endpoint: diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/OsUtils.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/OsUtils.java index 52ea63f..f2518ea 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/OsUtils.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/utils/OsUtils.java @@ -19,7 +19,7 @@ public final class OsUtils { if (isWindows() && StringUtils.isNotBlank(tmpdir)) { return tmpdir; } - return "/tmp"; + return "/tmp/"; } } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml index c4213e1..1332200 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/application.yml @@ -9,6 +9,8 @@ management: spring: main: allow-circular-references: true + cache: + type: SIMPLE data: mongodb: auto-index-creation: true