From cf1191336f16acc9acf110aa8a39f8ccb1d5b1ea Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 14:39:08 +0100 Subject: [PATCH 01/17] feat: weblate integration --- .../mailservice/api/RestApiMessageSource.java | 39 +++++ .../api/controller/TranslationController.java | 31 ++++ .../api/helper/ThymeleafHelper.java | 6 +- .../mailservice/api/service/MailService.java | 1 - .../api/service/TemplateService.java | 25 +++- .../api/service/TranslationService.java | 135 ++++++++++++++++++ .../cob/mailservice/config/AppConfig.java | 7 + .../mailservice/config/SpringFoxConfig.java | 3 +- .../mailservice/config/ThymeleafConfig.java | 9 ++ src/main/resources/application.properties | 8 +- src/main/resources/i18n/mailservice.de.json | 10 ++ src/main/resources/i18n/mailservice.en.json | 10 ++ .../assign-enquiry-notification.html | 12 +- ...reassign-confirmation-notification.en.html | 12 +- .../reassign-confirmation-notification.html | 8 +- .../api/controller/MailControllerE2EIT.java | 10 +- .../api/service/TemplateServiceTest.java | 6 +- templates/assign-enquiry-notification.html | 17 +-- ...reassign-confirmation-notification.en.html | 11 +- .../reassign-confirmation-notification.html | 13 +- 20 files changed, 322 insertions(+), 51 deletions(-) create mode 100644 src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java create mode 100644 src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java create mode 100644 src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java create mode 100644 src/main/resources/i18n/mailservice.de.json create mode 100644 src/main/resources/i18n/mailservice.en.json diff --git a/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java b/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java new file mode 100644 index 0000000..567422e --- /dev/null +++ b/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java @@ -0,0 +1,39 @@ +package de.caritas.cob.mailservice.api; + +import de.caritas.cob.mailservice.api.service.TranslationService; +import java.util.Locale; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.NoSuchMessageException; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class RestApiMessageSource implements MessageSource { + + + public final @NonNull TranslationService translationService; + + @Override + public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) { + log.info("getMessage called with code: {}, args: {}, defaultMessage: {}, locale: {}", code, + args, defaultMessage, locale); + return translationService.fetchTranslations(locale.getLanguage()).get(code); + } + + @Override + public String getMessage(String code, Object[] args, Locale locale) + throws NoSuchMessageException { + return getMessage(code, args, null, locale); + } + + @Override + public String getMessage(MessageSourceResolvable resolvable, Locale locale) + throws NoSuchMessageException { + return getMessage(resolvable.getCodes()[0], null, locale); + } +} diff --git a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java new file mode 100644 index 0000000..03b0d16 --- /dev/null +++ b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java @@ -0,0 +1,31 @@ +package de.caritas.cob.mailservice.api.controller; + +import de.caritas.cob.mailservice.api.service.TranslationService; +import java.util.Map; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + + +@Controller +@RequiredArgsConstructor +public class TranslationController { + + private final @NonNull TranslationService translationService; + + @RequestMapping(value = "/translations") + public ResponseEntity> getTranslations() { + var result = translationService.fetchTranslations("de"); + return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); + } + + @RequestMapping(value = "/translations/evict") + public ResponseEntity evictTranslationCache() { + translationService.evictCache(); + return new ResponseEntity<>(HttpStatus.OK); + } + +} diff --git a/src/main/java/de/caritas/cob/mailservice/api/helper/ThymeleafHelper.java b/src/main/java/de/caritas/cob/mailservice/api/helper/ThymeleafHelper.java index 8e8f158..7f020b6 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/helper/ThymeleafHelper.java +++ b/src/main/java/de/caritas/cob/mailservice/api/helper/ThymeleafHelper.java @@ -1,5 +1,7 @@ package de.caritas.cob.mailservice.api.helper; +import de.caritas.cob.mailservice.api.model.LanguageCode; +import java.util.Locale; import java.util.Map; import java.util.Optional; import javax.annotation.PostConstruct; @@ -21,9 +23,11 @@ void init() { templateEngine = tempTemplateEngine; } - public static Optional getProcessedHtml(Map data, String templateName) { + public static Optional getProcessedHtml(Map data, LanguageCode languageCode, String templateName) { Context context = new Context(); + Locale locale = Locale.forLanguageTag(languageCode.getValue()); + context.setLocale(locale); if (data != null) { data.forEach(context::setVariable); diff --git a/src/main/java/de/caritas/cob/mailservice/api/service/MailService.java b/src/main/java/de/caritas/cob/mailservice/api/service/MailService.java index 34faca9..1d0120e 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/service/MailService.java +++ b/src/main/java/de/caritas/cob/mailservice/api/service/MailService.java @@ -77,7 +77,6 @@ private void loadRequiredMailDataAndSendMail(MailDTO mail, TemplateDescription d private void renderAndSend(MailDTO mail, TemplateDescription desc, Map data) { var subject = templateService.getRenderedSubject(desc, data, mail.getLanguage()); - try { templateService .render(desc, mail.getTemplate(), data, mail.getLanguage()) diff --git a/src/main/java/de/caritas/cob/mailservice/api/service/TemplateService.java b/src/main/java/de/caritas/cob/mailservice/api/service/TemplateService.java index cc63e37..12dc5d7 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/service/TemplateService.java +++ b/src/main/java/de/caritas/cob/mailservice/api/service/TemplateService.java @@ -1,7 +1,8 @@ package de.caritas.cob.mailservice.api.service; +import static de.caritas.cob.mailservice.api.helper.ThymeleafHelper.getProcessedHtml; + import de.caritas.cob.mailservice.api.exception.TemplateServiceException; -import de.caritas.cob.mailservice.api.helper.ThymeleafHelper; import de.caritas.cob.mailservice.api.mailtemplate.TemplateDescription; import de.caritas.cob.mailservice.api.model.LanguageCode; import java.util.ArrayList; @@ -9,6 +10,8 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.apache.commons.text.StringSubstitutor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -18,6 +21,7 @@ * Service for template processing **/ @Service +@RequiredArgsConstructor public class TemplateService { @Value("${app.imprint.url}") @@ -26,6 +30,9 @@ public class TemplateService { @Value("${app.dataprivacy.url}") private String dataPrivacyUrl; + @NonNull + private final TranslationService translationService; + /** * Get the processed html template with replaced placeholders * @@ -41,6 +48,7 @@ public Optional render(TemplateDescription desc, String name, data.put("urlimpressum", imprintUrl); data.put("urldatenschutz", dataPrivacyUrl); + data.putAll(getTranslationMapAndDefaultToGermanIfNotFound(language)); List missingFieldList = getMissingTemplateFields(desc, data); if (!CollectionUtils.isEmpty(missingFieldList)) { @@ -51,7 +59,20 @@ public Optional render(TemplateDescription desc, String name, var templateFilename = desc.getTemplateFilenameOrFallback(language); - return ThymeleafHelper.getProcessedHtml(data, templateFilename); + return translationsArePresentAndNotEmpty(language) ? getProcessedHtml(data, language, templateFilename) : + getProcessedHtml(data, LanguageCode.DE, templateFilename); + } + + private boolean translationsArePresentAndNotEmpty(LanguageCode language) { + var translations = translationService.tryFetchTranslations( + language.getValue()); + return translations.isPresent() && !translations.get().isEmpty(); + } + + private Map getTranslationMapAndDefaultToGermanIfNotFound(LanguageCode language) { + return translationService.tryFetchTranslations(language.getValue()).orElse( + translationService.tryFetchTranslations(LanguageCode.DE.getValue()) + .orElse(new HashMap<>())); } /** diff --git a/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java new file mode 100644 index 0000000..ccf680b --- /dev/null +++ b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java @@ -0,0 +1,135 @@ +package de.caritas.cob.mailservice.api.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; +import springfox.documentation.annotations.Cacheable; + +@Service +@Slf4j +public class TranslationService { + + @Value("${weblate.api.url}") + private String apiUrl; + + @Value("${weblate.api.key}") + private String apiKey; + + @Value("${weblate.project}") + private String project; + + @Value("${weblate.component}") + private String component; + + private final RestTemplate restTemplate; + + public TranslationService(RestTemplate restTemplate) { + this.restTemplate = restTemplate; + } + + @Cacheable(value = "translations") + public Map fetchTranslations(String languageCode) { + try { + return fetchTranslationAsMap(languageCode); + } catch (JsonProcessingException ex) { + throw new TranslationServiceException(String.format( + "Json file with translations could not be parsed, translation component name: %s", + component), ex); + } + } + + @CacheEvict(value = "translations", allEntries = true) + public void evictCache() { + log.info("Evicting translations cache"); + } + + private Map fetchTranslationAsMap(String languageCode) throws JsonProcessingException { + String translations = fetchTranslationsAsString(languageCode); + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(translations, Map.class); + } + + public Optional> tryFetchTranslations(String languageCode) { + + try { + var result = fetchTranslationAsMap(languageCode); + return Optional.of(result); + } catch (JsonProcessingException e) { + log.warn("Error while processing json file with translations. Returning empty translations", e); + return Optional.empty(); + } + + } + + private String fetchTranslationsAsString(String languageCode) { + try { + return tryFetchTranslationsFromTranslationManagementService(project, component, + languageCode); + } catch (HttpClientErrorException e) { + if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) { + log.warn("Translations for component {}, language {} not found in weblate, returning default translations", component, + languageCode); + return fetchDefaultTranslations(component, languageCode); + } else { + log.error("Error while fetching translations from translation management service", e); + throw e; + } + } + } + + private String tryFetchTranslationsFromTranslationManagementService(String project, + String component, String languageCode) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Token " + apiKey); + String url = apiUrl + "translations/" + project + "/" + component + "/test" + "/" + languageCode + + "/file.json"; + + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, + new HttpEntity<>(headers), String.class); + return response.getBody(); + } + + private String fetchDefaultTranslations(String translationComponentName, String languageCode) { + var inputStream = TranslationService.class.getResourceAsStream( + getTranslationFilename(translationComponentName + "." + languageCode)); + if (inputStream == null) { + return "{}"; + } + try { + final List fileLines = IOUtils + .readLines(inputStream, StandardCharsets.UTF_8.displayName()); + return String.join("", fileLines); + } catch (IOException ex) { + throw new RuntimeException(String.format( + "Json file with translations could not be loaded, translation component name: %s", + translationComponentName), ex); + } + } + + private String getTranslationFilename(String templateName) { + return "/i18n/" + templateName.toLowerCase() + ".json"; + } + + private class TranslationServiceException extends RuntimeException { + + public TranslationServiceException(String format, JsonProcessingException ex) { + super(format, ex); + } + } +} diff --git a/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java b/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java index eb5d47e..c51e24b 100644 --- a/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java +++ b/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java @@ -1,10 +1,12 @@ package de.caritas.cob.mailservice.config; +import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import org.springframework.web.client.RestTemplate; /** * Contains some general spring boot application configurations @@ -26,4 +28,9 @@ public LocalValidatorFactoryBean validator(MessageSource messageSource) { return validatorFactoryBean; } + @Bean + public RestTemplate restTemplate(RestTemplateBuilder builder) { + return builder.build(); + } + } diff --git a/src/main/java/de/caritas/cob/mailservice/config/SpringFoxConfig.java b/src/main/java/de/caritas/cob/mailservice/config/SpringFoxConfig.java index 518d550..a0b395f 100644 --- a/src/main/java/de/caritas/cob/mailservice/config/SpringFoxConfig.java +++ b/src/main/java/de/caritas/cob/mailservice/config/SpringFoxConfig.java @@ -46,7 +46,7 @@ public class SpringFoxConfig { // without authorization public static final String[] WHITE_LIST = new String[] {"/mails/docs", "/mails/docs/**", "/v2/api-docs", "/configuration/ui", - "/swagger-resources/**", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/actuator/health", "/actuator/health/**"}; + "/swagger-resources/**", "/configuration/security", "/swagger-ui.html", "/webjars/**", "/actuator/health", "/actuator/health/**", "/translations", "/translations/**"}; @Bean public Docket apiDocket() { @@ -64,7 +64,6 @@ public Docket apiDocket() { */ private Set protocols() { Set protocols = new HashSet<>(); - protocols.add("http"); // TODO remove for production mode protocols.add("https"); return protocols; } diff --git a/src/main/java/de/caritas/cob/mailservice/config/ThymeleafConfig.java b/src/main/java/de/caritas/cob/mailservice/config/ThymeleafConfig.java index c410890..b0509b3 100644 --- a/src/main/java/de/caritas/cob/mailservice/config/ThymeleafConfig.java +++ b/src/main/java/de/caritas/cob/mailservice/config/ThymeleafConfig.java @@ -1,7 +1,10 @@ package de.caritas.cob.mailservice.config; +import de.caritas.cob.mailservice.api.RestApiMessageSource; +import de.caritas.cob.mailservice.api.service.TranslationService; import java.nio.charset.StandardCharsets; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.thymeleaf.templatemode.TemplateMode; @@ -50,4 +53,10 @@ private ITemplateResolver htmlClassLoaderTemplateResolver() { emailClassLoaderTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name()); return emailClassLoaderTemplateResolver; } + + @Bean + public MessageSource messageSource(TranslationService translationService) { + return new RestApiMessageSource(translationService); + } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fa6bec4..866a6ea 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -63,7 +63,13 @@ csrf.cookie.property= template.use.custom.resources.path= template.custom.resources.path= +weblate.api.url= +weblate.api.key= +weblate.project=onlineberatung +weblate.component=mailservice + management.endpoint.health.enabled=true management.endpoint.health.show-details=never management.endpoints.web.exposure.include=health -management.health.probes.enabled=true \ No newline at end of file +management.health.probes.enabled=true + diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json new file mode 100644 index 0000000..0d1bdfe --- /dev/null +++ b/src/main/resources/i18n/mailservice.de.json @@ -0,0 +1,10 @@ +{ + "mail.label.header": "Beratung", + "mail.label.slogan": "Online. Anonym. Sicher.", + "mail.label.has.assigned.you.new.adviceseeker": "hat Ihnen einen neuen Ratsuchenden zugewiesen.", + "mail.label.has.given.you.new.adviceseeker": "hat Ihnen eine(n) Ratsuchende(n) übergeben.", + "mail.label.dear": "Liebe(r)", + "mail.label.view.message": "Nachricht ansehen", + "mail.label.best.regards": "Liebe Grüße", + "mail.label.your.team": "Ihr Team von der Onlineberatung" +} diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json new file mode 100644 index 0000000..7209fdd --- /dev/null +++ b/src/main/resources/i18n/mailservice.en.json @@ -0,0 +1,10 @@ +{ + "mail.label.header": "Counseling & Help", + "mail.label.slogan": "Online. Anonym. Sicher.", + "mail.label.has.assigned.you.new.adviceseeker": "has assigned you an advice seeker.", + "mail.label.has.given.you.new.adviceseeker": "has assigned you an advice seeker.", + "mail.label.dear": "Dear", + "mail.label.view.message": "View message", + "mail.label.best.regards": "Best regards", + "mail.label.your.team": "Your onlinecounseling Team" +} diff --git a/src/main/resources/templates/assign-enquiry-notification.html b/src/main/resources/templates/assign-enquiry-notification.html index 87ade38..75aab17 100644 --- a/src/main/resources/templates/assign-enquiry-notification.html +++ b/src/main/resources/templates/assign-enquiry-notification.html @@ -21,8 +21,8 @@ -

Beratung & Hilfe

-
Online. Anonym. Sicher.
+

+
@@ -42,9 +42,9 @@

- Liebe(r) , + ,

- hat dir als neuen Ratsuchenden zugewiesen. +
@@ -69,9 +69,9 @@

- Impressum +   |   - Datenschutz +
diff --git a/src/main/resources/templates/reassign-confirmation-notification.en.html b/src/main/resources/templates/reassign-confirmation-notification.en.html index 11bc87b..0680678 100644 --- a/src/main/resources/templates/reassign-confirmation-notification.en.html +++ b/src/main/resources/templates/reassign-confirmation-notification.en.html @@ -22,8 +22,8 @@ -

Consulting & Help

-
Online. Anonymous. Safe.
+

+
@@ -45,7 +45,7 @@

Dear ,

- has assigned you an advice seeker. + @@ -69,10 +69,10 @@

-
- Impressum +
4 +   |   - Datenschutz +
diff --git a/src/main/resources/templates/reassign-confirmation-notification.html b/src/main/resources/templates/reassign-confirmation-notification.html index 8d1f132..2c1d5c4 100644 --- a/src/main/resources/templates/reassign-confirmation-notification.html +++ b/src/main/resources/templates/reassign-confirmation-notification.html @@ -42,9 +42,9 @@

- Liebe(r) , + ,

- hat Ihnen eine_n Ratsuchende_n übergeben. +
@@ -69,9 +69,9 @@

- Impressum +   |   - Datenschutz +
diff --git a/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java b/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java index 97bb7d9..e778ea3 100644 --- a/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java +++ b/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java @@ -269,12 +269,12 @@ private void assertTextIsGerman(MimeMessagePreparator prep, MailDTO mailDTO) throws NoSuchFieldException, IllegalAccessException { var text = getArg(prep, 5); var data = mailDTO.getTemplateData(); - var salutation = "Liebe(r) " + valueOf("name_recipient", data) + ","; + var salutation = "Liebe(r) " + valueOf("name_recipient", data) + ","; assertTrue(text.contains(salutation)); var message = "" + valueOf("name_from_consultant", data) - + " hat Ihnen eine_n Ratsuchende_n übergeben."; + + " hat Ihnen eine(n) Ratsuchende(n) übergeben."; assertTrue(text.contains(message)); var anchorStart = ""; @@ -288,10 +288,8 @@ private void assertTextIsEnglish(MimeMessagePreparator prep, MailDTO mailDTO) var salutation = "Dear " + valueOf("name_recipient", data) + ","; assertTrue(text.contains(salutation)); - var message = "" - + valueOf("name_from_consultant", data) - + " has assigned you an advice seeker."; - assertTrue(text.contains(message)); + assertTrue(text.contains(valueOf("name_from_consultant", data))); + assertTrue(text.contains("has assigned you an advice seeker.")); var anchorStart = ""; assertTrue(text.contains(anchorStart)); diff --git a/src/test/java/de/caritas/cob/mailservice/api/service/TemplateServiceTest.java b/src/test/java/de/caritas/cob/mailservice/api/service/TemplateServiceTest.java index 64a8717..334ad70 100644 --- a/src/test/java/de/caritas/cob/mailservice/api/service/TemplateServiceTest.java +++ b/src/test/java/de/caritas/cob/mailservice/api/service/TemplateServiceTest.java @@ -14,6 +14,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) @@ -52,9 +53,12 @@ public class TemplateServiceTest { private TemplateService templateService; + @Mock + private TranslationService translationService; + @Before public void setup() { - this.templateService = new TemplateService(); + this.templateService = new TemplateService(translationService); } @Test diff --git a/templates/assign-enquiry-notification.html b/templates/assign-enquiry-notification.html index d2b7198..eb8dd88 100644 --- a/templates/assign-enquiry-notification.html +++ b/templates/assign-enquiry-notification.html @@ -23,8 +23,8 @@

- Beratung

-
Online. Anonym. Sicher.
+

+
@@ -41,9 +41,9 @@ - Liebe(r) , + ,

- hat Ihnen einen neuen Ratsuchenden zugewiesen. + @@ -55,8 +55,9 @@
Nachricht - ansehen + style="color: #fff; text-transform: uppercase; font-weight: bold; text-decoration: none;"> + +
@@ -71,11 +72,11 @@ Impressum + style="color: #5A2572; text-decoration: none; font-size: 14px; line-height: 20px;">   |   Datenschutz + style="color: #5A2572; text-decoration: none; font-size: 14px; line-height: 20px;"> diff --git a/templates/reassign-confirmation-notification.en.html b/templates/reassign-confirmation-notification.en.html index af60d0b..c15f9a9 100644 --- a/templates/reassign-confirmation-notification.en.html +++ b/templates/reassign-confirmation-notification.en.html @@ -24,8 +24,8 @@

- Counseling & Help

-
Online. Anonymous. Safe.
+

+
@@ -42,9 +42,9 @@ - Dear , + ,

- has assigned an advice seeker to you. + @@ -56,8 +56,7 @@
View - message + style="color: #fff; text-transform: uppercase; font-weight: bold; text-decoration: none;">
diff --git a/templates/reassign-confirmation-notification.html b/templates/reassign-confirmation-notification.html index e200d03..bdd9e24 100644 --- a/templates/reassign-confirmation-notification.html +++ b/templates/reassign-confirmation-notification.html @@ -24,8 +24,8 @@

- Beratung

-
Online. Anonym. Sicher.
+

+
@@ -42,7 +42,7 @@ - Liebe(r) , + ,

hat Ihnen eine(n) Ratsuchende(n) übergeben. @@ -56,8 +56,7 @@
Nachricht - ansehen + style="color: #fff; text-transform: uppercase; font-weight: bold; text-decoration: none;">
@@ -72,11 +71,11 @@ Impressum + style="color: #5A2572; text-decoration: none; font-size: 14px; line-height: 20px;">   |   Datenschutz + style="color: #5A2572; text-decoration: none; font-size: 14px; line-height: 20px;"> From 91290c411be0819853fe0b755dc68a61f24db86d Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 14:59:44 +0100 Subject: [PATCH 02/17] feat: weblate integration --- .../api/service/TranslationService.java | 27 ++++--------- .../TranlationMangementServiceApiClient.java | 38 +++++++++++++++++++ .../api/controller/MailControllerE2EIT.java | 17 +++++++++ 3 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java diff --git a/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java index ccf680b..ccb3547 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java +++ b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java @@ -2,23 +2,20 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import de.caritas.cob.mailservice.config.apiclient.TranlationMangementServiceApiClient; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; import java.util.Optional; +import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CacheEvict; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; import springfox.documentation.annotations.Cacheable; @Service @@ -37,10 +34,10 @@ public class TranslationService { @Value("${weblate.component}") private String component; - private final RestTemplate restTemplate; + private final @NonNull TranlationMangementServiceApiClient tranlationMangementServiceApiClient; - public TranslationService(RestTemplate restTemplate) { - this.restTemplate = restTemplate; + public TranslationService(TranlationMangementServiceApiClient tranlationMangementServiceApiClient) { + this.tranlationMangementServiceApiClient = tranlationMangementServiceApiClient; } @Cacheable(value = "translations") @@ -79,7 +76,7 @@ public Optional> tryFetchTranslations(String languageCode) { private String fetchTranslationsAsString(String languageCode) { try { - return tryFetchTranslationsFromTranslationManagementService(project, component, + return tranlationMangementServiceApiClient.tryFetchTranslationsFromTranslationManagementService(project, component, languageCode); } catch (HttpClientErrorException e) { if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) { @@ -93,17 +90,7 @@ private String fetchTranslationsAsString(String languageCode) { } } - private String tryFetchTranslationsFromTranslationManagementService(String project, - String component, String languageCode) { - HttpHeaders headers = new HttpHeaders(); - headers.set("Authorization", "Token " + apiKey); - String url = apiUrl + "translations/" + project + "/" + component + "/test" + "/" + languageCode - + "/file.json"; - ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, - new HttpEntity<>(headers), String.class); - return response.getBody(); - } private String fetchDefaultTranslations(String translationComponentName, String languageCode) { var inputStream = TranslationService.class.getResourceAsStream( @@ -116,7 +103,7 @@ private String fetchDefaultTranslations(String translationComponentName, String .readLines(inputStream, StandardCharsets.UTF_8.displayName()); return String.join("", fileLines); } catch (IOException ex) { - throw new RuntimeException(String.format( + throw new IllegalStateException(String.format( "Json file with translations could not be loaded, translation component name: %s", translationComponentName), ex); } diff --git a/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java b/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java new file mode 100644 index 0000000..f8843f6 --- /dev/null +++ b/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java @@ -0,0 +1,38 @@ +package de.caritas.cob.mailservice.config.apiclient; + +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +@RequiredArgsConstructor +public class TranlationMangementServiceApiClient { + + @Value("${weblate.api.url}") + private String apiUrl; + + @Value("${weblate.api.key}") + private String apiKey; + + + + private final @NonNull RestTemplate restTemplate; + + public String tryFetchTranslationsFromTranslationManagementService(String project, + String component, String languageCode) { + HttpHeaders headers = new HttpHeaders(); + headers.set("Authorization", "Token " + apiKey); + String url = apiUrl + "translations/" + project + "/" + component + "/test" + "/" + languageCode + + "/file.json"; + + ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, + new HttpEntity<>(headers), String.class); + return response.getBody(); + } +} diff --git a/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java b/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java index e778ea3..7870166 100644 --- a/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java +++ b/src/test/java/de/caritas/cob/mailservice/api/controller/MailControllerE2EIT.java @@ -2,7 +2,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -11,23 +13,28 @@ import de.caritas.cob.mailservice.api.model.MailDTO; import de.caritas.cob.mailservice.api.model.MailsDTO; import de.caritas.cob.mailservice.api.model.TemplateDataDTO; +import de.caritas.cob.mailservice.config.apiclient.TranlationMangementServiceApiClient; import java.util.List; import java.util.Map; import javax.servlet.http.Cookie; import org.apache.commons.lang3.RandomStringUtils; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Captor; +import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessagePreparator; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; +import org.springframework.web.client.HttpClientErrorException; @SpringBootTest @AutoConfigureMockMvc @@ -48,12 +55,22 @@ class MailControllerE2EIT { @Qualifier("emailsender") private JavaMailSender javaMailSender; + @MockBean + private TranlationMangementServiceApiClient tranlationMangementServiceApiClient; + @Captor private ArgumentCaptor mimeMessagePrepCaptor; private MailsDTO mailsDTO; private Map>> mailsDTOMap; + @BeforeEach + void setUp() { + Mockito.doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)).when( + tranlationMangementServiceApiClient).tryFetchTranslationsFromTranslationManagementService( + anyString(), anyString(), anyString()); + } + @Test void sendMailsShouldRespondWithOkWhenEmailListIsEmpty() throws Exception { givenAnEmptyEmailList(); From 6b481ca1ef9e4080e22595714a0ab7ba2c53aa68 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 15:26:42 +0100 Subject: [PATCH 03/17] feat: weblate integration --- .../api/controller/TranslationController.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java index 03b0d16..047e1a4 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java +++ b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java @@ -4,10 +4,11 @@ import java.util.Map; import lombok.NonNull; import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; @Controller @@ -22,10 +23,17 @@ public ResponseEntity> getTranslations() { return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); } + @RequestMapping(value = "/translations/{lang}") + public ResponseEntity> getTranslations(@PathVariable("lang") String languageCode) { + var result = translationService.fetchTranslations(languageCode); + return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); + } + @RequestMapping(value = "/translations/evict") - public ResponseEntity evictTranslationCache() { + @ResponseBody + public String evictTranslationCache() { translationService.evictCache(); - return new ResponseEntity<>(HttpStatus.OK); + return "Cache evicted"; } } From 078a42078075c816357797a6cb9c2b17208ea39b Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 15:36:46 +0100 Subject: [PATCH 04/17] enable remote debugging --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f5450b6..a3f7202 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,5 +2,5 @@ FROM adoptopenjdk/openjdk11 VOLUME ["/tmp","/log"] EXPOSE 8080 ARG JAR_FILE -COPY ./MailService.jar app.jar -ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] +COPY ./target/MailService.jar app.jar +ENTRYPOINT ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] From e549700624582d9a28d3f711be6e4fbdd060f468 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 15:38:18 +0100 Subject: [PATCH 05/17] fix: fix invalid path to fetch translations --- .../apiclient/TranlationMangementServiceApiClient.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java b/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java index f8843f6..83e7dfb 100644 --- a/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java +++ b/src/main/java/de/caritas/cob/mailservice/config/apiclient/TranlationMangementServiceApiClient.java @@ -2,6 +2,7 @@ import lombok.NonNull; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -12,6 +13,7 @@ @Service @RequiredArgsConstructor +@Slf4j public class TranlationMangementServiceApiClient { @Value("${weblate.api.url}") @@ -28,9 +30,10 @@ public String tryFetchTranslationsFromTranslationManagementService(String projec String component, String languageCode) { HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", "Token " + apiKey); - String url = apiUrl + "translations/" + project + "/" + component + "/test" + "/" + languageCode + String url = apiUrl + "translations/" + project + "/" + component + "/" + languageCode + "/file.json"; + log.info("Calling url to fetch translations: {}", url); ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), String.class); return response.getBody(); From fdc5bdaf4cb38cc0cbd795713d2f5032836852a0 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Wed, 22 Nov 2023 17:10:12 +0100 Subject: [PATCH 06/17] fix: dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a3f7202..ddad38e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,5 +2,5 @@ FROM adoptopenjdk/openjdk11 VOLUME ["/tmp","/log"] EXPOSE 8080 ARG JAR_FILE -COPY ./target/MailService.jar app.jar +COPY ./MailService.jar app.jar ENTRYPOINT ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] From 0d120b6bfdc7be1c1952c014dd7a28949891800b Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 23 Nov 2023 12:44:40 +0100 Subject: [PATCH 07/17] feat: add more keys --- src/main/resources/i18n/mailservice.de.json | 5 ++++- src/main/resources/i18n/mailservice.en.json | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json index 0d1bdfe..0a6ed9d 100644 --- a/src/main/resources/i18n/mailservice.de.json +++ b/src/main/resources/i18n/mailservice.de.json @@ -6,5 +6,8 @@ "mail.label.dear": "Liebe(r)", "mail.label.view.message": "Nachricht ansehen", "mail.label.best.regards": "Liebe Grüße", - "mail.label.your.team": "Ihr Team von der Onlineberatung" + "mail.label.your.team": "Ihr Team von der Onlineberatung", + "mail.label.in.the.agency": "in der Beratungsstelle", + "mail.label.is.a.new.enquiry.received": "ist eine neue Erstanfrage eingegangen.", + "mail.label.view.enquiry": "Anfrage ansehen" } diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json index 7209fdd..f780ade 100644 --- a/src/main/resources/i18n/mailservice.en.json +++ b/src/main/resources/i18n/mailservice.en.json @@ -6,5 +6,8 @@ "mail.label.dear": "Dear", "mail.label.view.message": "View message", "mail.label.best.regards": "Best regards", - "mail.label.your.team": "Your onlinecounseling Team" + "mail.label.your.team": "Your onlinecounseling Team", + "mail.label.in.the.agency": "in the agency", + "mail.label.is.a.new.enquiry.received": "is a new enquiry received.", + "mail.label.view.enquiry": "View enquiry" } From 4eedb55d38eef53be64fd95c25a27d94426f02dc Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 23 Nov 2023 12:46:30 +0100 Subject: [PATCH 08/17] feat: add more keys --- src/main/resources/i18n/mailservice.de.json | 3 ++- src/main/resources/i18n/mailservice.en.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json index 0a6ed9d..03d5208 100644 --- a/src/main/resources/i18n/mailservice.de.json +++ b/src/main/resources/i18n/mailservice.de.json @@ -9,5 +9,6 @@ "mail.label.your.team": "Ihr Team von der Onlineberatung", "mail.label.in.the.agency": "in der Beratungsstelle", "mail.label.is.a.new.enquiry.received": "ist eine neue Erstanfrage eingegangen.", - "mail.label.view.enquiry": "Anfrage ansehen" + "mail.label.view.enquiry": "Anfrage ansehen", + "mail.label.your.team.with.tenant": "Ihr Team von " } diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json index f780ade..09cc847 100644 --- a/src/main/resources/i18n/mailservice.en.json +++ b/src/main/resources/i18n/mailservice.en.json @@ -9,5 +9,6 @@ "mail.label.your.team": "Your onlinecounseling Team", "mail.label.in.the.agency": "in the agency", "mail.label.is.a.new.enquiry.received": "is a new enquiry received.", - "mail.label.view.enquiry": "View enquiry" + "mail.label.view.enquiry": "View enquiry", + "mail.label.your.team.with.tenant": "Your team of " } From 57f425cef289e4ece4f691909471a5f9a86dcdda Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 24 Nov 2023 13:14:28 +0100 Subject: [PATCH 09/17] feat: add more keys and default values --- src/main/resources/i18n/mailservice.de.json | 15 ++++++++++++++- src/main/resources/i18n/mailservice.en.json | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json index 03d5208..066b027 100644 --- a/src/main/resources/i18n/mailservice.de.json +++ b/src/main/resources/i18n/mailservice.de.json @@ -10,5 +10,18 @@ "mail.label.in.the.agency": "in der Beratungsstelle", "mail.label.is.a.new.enquiry.received": "ist eine neue Erstanfrage eingegangen.", "mail.label.view.enquiry": "Anfrage ansehen", - "mail.label.your.team.with.tenant": "Ihr Team von " + "mail.label.your.team.with.tenant": "Ihr Team von ", + "mail.label.there.are.present": "Es liegen", + "mail.label.new.enquiries.in.agency": "Erstanfragen in der\n Beratungsstelle", + "mail.label.there.are.present.closure": "vor", + "mail.label.there.is.one.enquiry.in.agency.present": "es liegt eine Erstanfrage in der Beratungsstelle", + "mail.label.an.adviceseeker.has.registered.and.left.you.a.message": "ein(e) Ratsuchende(r) hat sich direkt bei Ihnen registriert und eine Nachricht hinterlassen.", + "mail.label.has.left.feedback.regarding.counselling.the.user": "hat eine Feedback-Nachricht für die Beratung von", + "mail.label.has.left.closure": "hinterlassen", + "mail.label.you.have.received.an.answear.from": "Sie haben eine Antwort von", + "mail.label.you.have.received.an.answear.from.closure": "erhalten", + "mail.label.please.login.to.read.it": "Bitte melden Sie sich an, um Ihre Antwort zu lesen!", + "mail.label.read.the.response": "Antwort lesen", + "mail.label.you.have.a.new.message.in.your.counselings" : "Sie haben eine neue Nachricht in Ihren Beratungen", + "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Ihr(e) Berater(in) möchte Sie an eine(n) neue(n)\n Berater(in) übergeben. Dafür brauchen wir Ihre Zustimmung." } diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json index 09cc847..ae64af8 100644 --- a/src/main/resources/i18n/mailservice.en.json +++ b/src/main/resources/i18n/mailservice.en.json @@ -10,5 +10,18 @@ "mail.label.in.the.agency": "in the agency", "mail.label.is.a.new.enquiry.received": "is a new enquiry received.", "mail.label.view.enquiry": "View enquiry", - "mail.label.your.team.with.tenant": "Your team of " + "mail.label.your.team.with.tenant": "Your team of ", + "mail.label.there.are.present": "There are", + "mail.label.new.enquiries.in.agency": "enquiries in the agency", + "mail.label.there.are.present.closure": "", + "mail.label.there.is.one.enquiry.in.agency.present": "there is one new enquiry in the agency", + "mail.label.an.adviceseeker.has.registered.and.left.you.a.message": "an adviceseeker has registered and left you a message", + "mail.label.has.left.feedback.regarding.counselling.the.user": "has left feedback regarding the counseling", + "mail.label.has.left.closure": "", + "mail.label.you.have.received.an.answear.from": "you have received a response from", + "mail.label.you.have.received.an.answear.from.closure": "", + "mail.label.please.login.to.read.it": "Please login to read your message", + "mail.label.read.the.response": "Read the response", + "mail.label.you.have.a.new.message.in.your.counselings" : "You have a new message in your counselings", + "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Your advisor would like to hand you over to a new advisor. We need your consent for this." } From 7003f0fccd5771ee62f1c93c93cfa8ab1a86d4c7 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 24 Nov 2023 15:17:14 +0100 Subject: [PATCH 10/17] feat: add more keys and default values --- src/main/resources/i18n/mailservice.de.json | 4 +++- src/main/resources/i18n/mailservice.en.json | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json index 066b027..7a11a9c 100644 --- a/src/main/resources/i18n/mailservice.de.json +++ b/src/main/resources/i18n/mailservice.de.json @@ -23,5 +23,7 @@ "mail.label.please.login.to.read.it": "Bitte melden Sie sich an, um Ihre Antwort zu lesen!", "mail.label.read.the.response": "Antwort lesen", "mail.label.you.have.a.new.message.in.your.counselings" : "Sie haben eine neue Nachricht in Ihren Beratungen", - "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Ihr(e) Berater(in) möchte Sie an eine(n) neue(n)\n Berater(in) übergeben. Dafür brauchen wir Ihre Zustimmung." + "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Ihr(e) Berater(in) möchte Sie an eine(n) neue(n)\n Berater(in) übergeben. Dafür brauchen wir Ihre Zustimmung.", + "mail.label.imprint": "Impressum", + "mail.label.privacy": "Datenschutz" } diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json index ae64af8..9092a3a 100644 --- a/src/main/resources/i18n/mailservice.en.json +++ b/src/main/resources/i18n/mailservice.en.json @@ -23,5 +23,7 @@ "mail.label.please.login.to.read.it": "Please login to read your message", "mail.label.read.the.response": "Read the response", "mail.label.you.have.a.new.message.in.your.counselings" : "You have a new message in your counselings", - "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Your advisor would like to hand you over to a new advisor. We need your consent for this." + "mail.label.your.consultant.wants.to.assign.you.to.new.consultant": "Your advisor would like to hand you over to a new advisor. We need your consent for this.", + "mail.label.imprint": "Imprint", + "mail.label.privacy": "Privacy" } From 7eaa78d0f7ac35a6c0f3ecf22958c47201435f83 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Fri, 24 Nov 2023 17:13:18 +0100 Subject: [PATCH 11/17] feat: add caching --- pom.xml | 13 +++++++ .../api/cache/CacheEventLogger.java | 15 ++++++++ .../api/service/TranslationService.java | 3 +- .../cob/mailservice/config/AppConfig.java | 2 + src/main/resources/application.properties | 2 + src/main/resources/ehcache.xml | 38 +++++++++++++++++++ 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/main/java/de/caritas/cob/mailservice/api/cache/CacheEventLogger.java create mode 100644 src/main/resources/ehcache.xml diff --git a/pom.xml b/pom.xml index a70a1a0..85552a9 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,19 @@ org.springframework.boot spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-cache + + + org.ehcache + ehcache + + + javax.cache + cache-api + 1.1.1 + org.hibernate.validator hibernate-validator diff --git a/src/main/java/de/caritas/cob/mailservice/api/cache/CacheEventLogger.java b/src/main/java/de/caritas/cob/mailservice/api/cache/CacheEventLogger.java new file mode 100644 index 0000000..1434ac7 --- /dev/null +++ b/src/main/java/de/caritas/cob/mailservice/api/cache/CacheEventLogger.java @@ -0,0 +1,15 @@ +package de.caritas.cob.mailservice.api.cache; + +import lombok.extern.slf4j.Slf4j; +import org.ehcache.event.CacheEvent; +import org.ehcache.event.CacheEventListener; + +@Slf4j +public class CacheEventLogger implements CacheEventListener { + + @Override + public void onEvent(CacheEvent cacheEvent) { + log.info( + "caching event: ", cacheEvent.getKey(), cacheEvent.getOldValue(), cacheEvent.getNewValue()); + } +} diff --git a/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java index ccb3547..d2d841d 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java +++ b/src/main/java/de/caritas/cob/mailservice/api/service/TranslationService.java @@ -13,10 +13,10 @@ import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.client.HttpClientErrorException; -import springfox.documentation.annotations.Cacheable; @Service @Slf4j @@ -43,6 +43,7 @@ public TranslationService(TranlationMangementServiceApiClient tranlationMangemen @Cacheable(value = "translations") public Map fetchTranslations(String languageCode) { try { + return fetchTranslationAsMap(languageCode); } catch (JsonProcessingException ex) { throw new TranslationServiceException(String.format( diff --git a/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java b/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java index c51e24b..804227a 100644 --- a/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java +++ b/src/main/java/de/caritas/cob/mailservice/config/AppConfig.java @@ -1,6 +1,7 @@ package de.caritas.cob.mailservice.config; import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -13,6 +14,7 @@ */ @Configuration @ComponentScan(basePackages = {"de.caritas.cob.mailservice"}) +@EnableCaching public class AppConfig { /** diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 866a6ea..63ea274 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -72,4 +72,6 @@ management.endpoint.health.enabled=true management.endpoint.health.show-details=never management.endpoints.web.exposure.include=health management.health.probes.enabled=true +spring.cache.jcache.config=classpath:ehcache.xml +logging.level.net.sf.ehcache=info \ No newline at end of file diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml new file mode 100644 index 0000000..7992876 --- /dev/null +++ b/src/main/resources/ehcache.xml @@ -0,0 +1,38 @@ + + + + + 60 + + + + 10 + + + + + + 60 + + + + de.caritas.cob.mailservice.api.cache.CacheEventLogger + ASYNCHRONOUS + UNORDERED + CREATED + EXPIRED + EVICTED + + + + 1000 + 10 + 20 + + + \ No newline at end of file From c36c27ee258b0a3dfbfe37a7761facaf31876b82 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 30 Nov 2023 11:40:02 +0100 Subject: [PATCH 12/17] feat: add caching --- ehcache.xml | 38 +++++++++++++++++++ .../api/controller/TranslationController.java | 8 ++-- 2 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 ehcache.xml diff --git a/ehcache.xml b/ehcache.xml new file mode 100644 index 0000000..7992876 --- /dev/null +++ b/ehcache.xml @@ -0,0 +1,38 @@ + + + + + 60 + + + + 10 + + + + + + 60 + + + + de.caritas.cob.mailservice.api.cache.CacheEventLogger + ASYNCHRONOUS + UNORDERED + CREATED + EXPIRED + EVICTED + + + + 1000 + 10 + 20 + + + \ No newline at end of file diff --git a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java index 047e1a4..b6a3bb1 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java +++ b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java @@ -6,8 +6,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -17,19 +17,19 @@ public class TranslationController { private final @NonNull TranslationService translationService; - @RequestMapping(value = "/translations") + @GetMapping(value = "/translations") public ResponseEntity> getTranslations() { var result = translationService.fetchTranslations("de"); return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); } - @RequestMapping(value = "/translations/{lang}") + @GetMapping(value = "/translations/{lang}") public ResponseEntity> getTranslations(@PathVariable("lang") String languageCode) { var result = translationService.fetchTranslations(languageCode); return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); } - @RequestMapping(value = "/translations/evict") + @GetMapping(value = "/translations/evict") @ResponseBody public String evictTranslationCache() { translationService.evictCache(); From 91f114b2c57da51370e84e8b8c71720daf23afa4 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 30 Nov 2023 11:47:34 +0100 Subject: [PATCH 13/17] fix: remove not needed endpoint --- .../mailservice/api/controller/TranslationController.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java index b6a3bb1..3516b86 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java +++ b/src/main/java/de/caritas/cob/mailservice/api/controller/TranslationController.java @@ -7,7 +7,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.ResponseBody; @@ -23,12 +22,6 @@ public ResponseEntity> getTranslations() { return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); } - @GetMapping(value = "/translations/{lang}") - public ResponseEntity> getTranslations(@PathVariable("lang") String languageCode) { - var result = translationService.fetchTranslations(languageCode); - return new ResponseEntity<>(result, org.springframework.http.HttpStatus.OK); - } - @GetMapping(value = "/translations/evict") @ResponseBody public String evictTranslationCache() { From 161800d49c0871981aaee75a0d6ddbe8e6fc3998 Mon Sep 17 00:00:00 2001 From: tkuzynow Date: Thu, 30 Nov 2023 11:49:09 +0100 Subject: [PATCH 14/17] fix: potential NPE --- .../de/caritas/cob/mailservice/api/RestApiMessageSource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java b/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java index 567422e..d632b51 100644 --- a/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java +++ b/src/main/java/de/caritas/cob/mailservice/api/RestApiMessageSource.java @@ -34,6 +34,10 @@ public String getMessage(String code, Object[] args, Locale locale) @Override public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException { + if (resolvable == null) { + log.warn("getMessage called with null resolvable"); + return null; + } return getMessage(resolvable.getCodes()[0], null, locale); } } From 6b9874abf4433a53b8312a2fb2e05ba0dd75647a Mon Sep 17 00:00:00 2001 From: Tomasz Kuzynowski Date: Fri, 1 Dec 2023 15:03:19 +0100 Subject: [PATCH 15/17] Update src/main/resources/i18n/mailservice.en.json Co-authored-by: Marc Itzenthaler --- src/main/resources/i18n/mailservice.en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/i18n/mailservice.en.json b/src/main/resources/i18n/mailservice.en.json index 9092a3a..9c56079 100644 --- a/src/main/resources/i18n/mailservice.en.json +++ b/src/main/resources/i18n/mailservice.en.json @@ -1,7 +1,7 @@ { "mail.label.header": "Counseling & Help", "mail.label.slogan": "Online. Anonym. Sicher.", - "mail.label.has.assigned.you.new.adviceseeker": "has assigned you an advice seeker.", + "mail.label.has.assigned.you.new.adviceseeker": "has assigned you {0} as new advice seeker.", "mail.label.has.given.you.new.adviceseeker": "has assigned you an advice seeker.", "mail.label.dear": "Dear", "mail.label.view.message": "View message", From 6b528e0ec808950e4e08d3edf146a7e176d1f606 Mon Sep 17 00:00:00 2001 From: Tomasz Kuzynowski Date: Fri, 1 Dec 2023 15:03:26 +0100 Subject: [PATCH 16/17] Update src/main/resources/i18n/mailservice.de.json Co-authored-by: Marc Itzenthaler --- src/main/resources/i18n/mailservice.de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/i18n/mailservice.de.json b/src/main/resources/i18n/mailservice.de.json index 7a11a9c..7015b3f 100644 --- a/src/main/resources/i18n/mailservice.de.json +++ b/src/main/resources/i18n/mailservice.de.json @@ -1,7 +1,7 @@ { "mail.label.header": "Beratung", "mail.label.slogan": "Online. Anonym. Sicher.", - "mail.label.has.assigned.you.new.adviceseeker": "hat Ihnen einen neuen Ratsuchenden zugewiesen.", + "mail.label.has.assigned.you.new.adviceseeker": "hat Ihnen {0} als neuen Ratsuchenden zugewiesen.", "mail.label.has.given.you.new.adviceseeker": "hat Ihnen eine(n) Ratsuchende(n) übergeben.", "mail.label.dear": "Liebe(r)", "mail.label.view.message": "Nachricht ansehen", From 927c141696596152df08bd42c69b3f3ffe1f42fa Mon Sep 17 00:00:00 2001 From: Tomasz Kuzynowski Date: Fri, 1 Dec 2023 16:59:11 +0100 Subject: [PATCH 17/17] Update src/main/resources/templates/assign-enquiry-notification.html Co-authored-by: Marc Itzenthaler --- src/main/resources/templates/assign-enquiry-notification.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/assign-enquiry-notification.html b/src/main/resources/templates/assign-enquiry-notification.html index 75aab17..a4aac71 100644 --- a/src/main/resources/templates/assign-enquiry-notification.html +++ b/src/main/resources/templates/assign-enquiry-notification.html @@ -44,7 +44,7 @@

,

- +