Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ob 8353 externalize translations config #107

Merged
merged 8 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
package de.caritas.cob.mailservice.api.service;

import de.caritas.cob.mailservice.api.model.Dialect;
import de.caritas.cob.mailservice.config.apiclient.TranlationMangementServiceApiClient;
import de.caritas.cob.mailservice.config.apiclient.TranslationManagementServiceApiClient;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class DefaultTranslationsService {

@Value("${template.custom.default.translations.path}")
private String customTranslationsPath;

@Value("${template.use.custom.resources.path}")
private boolean useCustomResourcesPath;
Leandro13Silva13 marked this conversation as resolved.
Show resolved Hide resolved

public String fetchDefaultTranslations(String translationComponentName, String languageCode,
Dialect dialect) {
InputStream inputStream = tryFetchDefaultTranslationWithFallbackToEmptyDialect(translationComponentName, languageCode, dialect);
InputStream inputStream = useCustomResourcesPath ? tryFetchExternalTranslationWithFallbackToEmptyDialect(translationComponentName, languageCode, dialect) :
tryFetchDefaultTranslationWithFallbackToEmptyDialect(translationComponentName, languageCode, dialect);
if (inputStream == null) {
return "{}";
}
Expand All @@ -31,6 +42,23 @@ public String fetchDefaultTranslations(String translationComponentName, String l
}
}

private InputStream tryFetchExternalTranslationWithFallbackToEmptyDialect(String translationComponentName, String languageCode,
Dialect dialect) {
InputStream inputStream = buildStreamForExternalPath(translationComponentName, languageCode, dialect);
return inputStream != null ? inputStream : buildStreamForExternalPath(translationComponentName, languageCode, null);
}

private FileInputStream buildStreamForExternalPath(String translationComponentName, String languageCode, Dialect dialect) {
try {
String filename = String.format("%s/%s.%s%s.json", customTranslationsPath, translationComponentName.toLowerCase(), languageCode, TranslationManagementServiceApiClient.getDialectSuffix(dialect));
return new FileInputStream(filename);
} catch (FileNotFoundException e) {
log.warn("Default translations for component {}, language {} not found in external path {}", translationComponentName,
languageCode, customTranslationsPath);
return null;
}
}

private InputStream tryFetchDefaultTranslationWithFallbackToEmptyDialect(String translationComponentName, String languageCode,
Dialect dialect) {
InputStream inputStream = getInputStream(translationComponentName, languageCode,
Expand All @@ -57,7 +85,7 @@ private InputStream getInputStream(String translationComponentName, String langu
Dialect dialect) {
String translationFilename = getTranslationFilename(
translationComponentName + "." + languageCode
+ TranlationMangementServiceApiClient.getDialectSuffix(dialect));
+ TranslationManagementServiceApiClient.getDialectSuffix(dialect));
return TranslationService.class.getResourceAsStream(translationFilename);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.caritas.cob.mailservice.api.model.Dialect;
import de.caritas.cob.mailservice.config.apiclient.TranlationMangementServiceApiClient;
import de.caritas.cob.mailservice.config.apiclient.TranslationManagementServiceApiClient;
import java.util.Map;
import java.util.Optional;
import lombok.NonNull;
Expand Down Expand Up @@ -32,13 +32,16 @@ public class TranslationService {
@Value("${weblate.component}")
private String component;

private final @NonNull TranlationMangementServiceApiClient tranlationMangementServiceApiClient;
@Value("${translation.management.system.enabled}")
private boolean translationManagementSystemEnabled;

private final @NonNull TranslationManagementServiceApiClient translationManagementServiceApiClient;

private final @NonNull DefaultTranslationsService defaultTranslationsService;

public TranslationService(
TranlationMangementServiceApiClient tranlationMangementServiceApiClient, DefaultTranslationsService defaultTranslationsService) {
this.tranlationMangementServiceApiClient = tranlationMangementServiceApiClient;
TranslationManagementServiceApiClient translationManagementServiceApiClient, DefaultTranslationsService defaultTranslationsService) {
this.translationManagementServiceApiClient = translationManagementServiceApiClient;
this.defaultTranslationsService = defaultTranslationsService;
}

Expand Down Expand Up @@ -85,9 +88,12 @@ private String fetchTranslationsAsString(String languageCode, Dialect dialect) {

private String fetchDefaultTranslationsFromTranslationsManagementSystem(String languageCode, Dialect dialect) {
try {
return tranlationMangementServiceApiClient.tryFetchTranslationsFromTranslationManagementService(
log.info("Fetching translations. Translation management system enabled value: {}",
translationManagementSystemEnabled);
return translationManagementSystemEnabled ? translationManagementServiceApiClient.tryFetchTranslationsFromTranslationManagementService(
project, component,
languageCode, dialect);
languageCode, dialect) : defaultTranslationsService.fetchDefaultTranslations(component, languageCode,
dialect);
} catch (HttpClientErrorException e) {
if (HttpStatus.NOT_FOUND.equals(e.getStatusCode())) {
log.warn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,21 @@
@Service
@RequiredArgsConstructor
@Slf4j
public class TranlationMangementServiceApiClient {
public class TranslationManagementServiceApiClient {

@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, Dialect dialect) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Token " + apiKey);
String url = apiUrl + "translations/" + project + "/" + component + "/" + languageCode + getDialectSuffix(dialect)
String url = apiUrl + "translations/" + project + "/" + component + "/" + languageCode + getWeblateDialectSuffix(dialect)
+ "/file.json";

log.info("Calling url to fetch translations: {}", url);
Expand All @@ -41,7 +39,7 @@ public String tryFetchTranslationsFromTranslationManagementService(String projec
return response.getBody();
}

public static String getDialectSuffix(Dialect dialect) {
public static String getWeblateDialectSuffix(Dialect dialect) {
if (dialect == null) {
return StringUtils.EMPTY;
}
Expand All @@ -50,4 +48,14 @@ public static String getDialectSuffix(Dialect dialect) {
}
return StringUtils.EMPTY;
}

public static String getDialectSuffix(Dialect dialect) {
if (dialect == null) {
return StringUtils.EMPTY;
}
if (dialect == Dialect.INFORMAL) {
return "_informal";
}
return StringUtils.EMPTY;
}
}
1 change: 1 addition & 0 deletions src/main/resources/application-testing.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mail.exchange.version=Exchange2010_SP2

template.use.custom.resources.path=false
template.custom.resources.path=false
translation.management.system.enabled=false

csrf.header.property=csrfHeader
csrf.cookie.property=csrfCookie
4 changes: 3 additions & 1 deletion src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ csrf.cookie.property=
# refactoring
template.use.custom.resources.path=
template.custom.resources.path=
template.custom.default.translations.path=
translation.management.system.enabled=

weblate.api.url=
weblate.api.key=
Expand All @@ -74,4 +76,4 @@ management.endpoints.web.exposure.include=health
management.health.probes.enabled=true
spring.cache.jcache.config=classpath:ehcache.xml

logging.level.net.sf.ehcache=info
logging.level.net.sf.ehcache=info
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
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 de.caritas.cob.mailservice.config.apiclient.TranslationManagementServiceApiClient;
import java.util.List;
import java.util.Map;
import javax.servlet.http.Cookie;
Expand Down Expand Up @@ -57,7 +57,7 @@ class MailControllerE2EIT {
private JavaMailSender javaMailSender;

@MockBean
private TranlationMangementServiceApiClient tranlationMangementServiceApiClient;
private TranslationManagementServiceApiClient translationManagementServiceApiClient;

@Captor
private ArgumentCaptor<MimeMessagePreparator> mimeMessagePrepCaptor;
Expand All @@ -67,8 +67,7 @@ class MailControllerE2EIT {

@BeforeEach
void setUp() {
Mockito.doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)).when(
tranlationMangementServiceApiClient).tryFetchTranslationsFromTranslationManagementService(
Mockito.doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)).when(translationManagementServiceApiClient).tryFetchTranslationsFromTranslationManagementService(
anyString(), anyString(), anyString(), any(Dialect.class));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@

@SpringBootTest
@ActiveProfiles("testing")
class DefaultTranslationsServiceTest {
class DefaultTranslationsServiceIT {

@Autowired
DefaultTranslationsService defaultTranslationsService;
private DefaultTranslationsService defaultTranslationsService;

@Test
void fetchDefaultTranslations_Should_FetchTranlsationsForInformalGerman() {
Expand Down Expand Up @@ -45,4 +45,4 @@ void fetchDefaultTranslations_Should_FetchTranlsationsForEnglish() {
assertThat(translations).contains("has assigned you {0} new advice seeker.");
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package de.caritas.cob.mailservice.api.service;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;

import de.caritas.cob.mailservice.api.model.Dialect;
import de.caritas.cob.mailservice.config.apiclient.TranslationManagementServiceApiClient;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class TranslationServiceTest {

private TranslationService translationService;

@Mock
private TranslationManagementServiceApiClient translationManagementServiceApiClient;

@Mock
private DefaultTranslationsService defaultTranslationsService;

public final String TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_NAME = "translationManagementSystemEnabled";

@BeforeEach
public void setUp() {
translationService = new TranslationService(translationManagementServiceApiClient, defaultTranslationsService);
}

@Test
void fetchTranslations_Should_call_tryFetchTranslationsFromTranslationManagementService_When_translationManagementSystemEnabled_is_true() {
Leandro13Silva13 marked this conversation as resolved.
Show resolved Hide resolved
Leandro13Silva13 marked this conversation as resolved.
Show resolved Hide resolved

//Arrange
Leandro13Silva13 marked this conversation as resolved.
Show resolved Hide resolved
final boolean TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_VALUE = true;
ReflectionTestUtils.setField(translationService, TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_NAME, TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_VALUE);
when(translationManagementServiceApiClient.tryFetchTranslationsFromTranslationManagementService(any(), any(), any(), any())).thenReturn("{\"mail.label.header\": \"Beratung\"}");

//Act
translationService.fetchTranslations("test", Dialect.INFORMAL);

//Assert
verify(translationManagementServiceApiClient).tryFetchTranslationsFromTranslationManagementService(any(), any(), any(), any());
verifyNoInteractions(defaultTranslationsService);

}

@Test
void fetchTranslations_Should_call_fetchDefaultTranslations_When_translationManagementSystemEnabled_is_false() {

//Arrange
Leandro13Silva13 marked this conversation as resolved.
Show resolved Hide resolved
final boolean TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_VALUE = false;
ReflectionTestUtils.setField(translationService, TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_NAME, TRANSLATION_MANAGEMENT_SYSTEM_ENABLED_FIELD_VALUE);
when(defaultTranslationsService.fetchDefaultTranslations(any(), any(), any())).thenReturn("{\"mail.label.header\": \"Beratung\"}");

//Act
translationService.fetchTranslations("test", Dialect.INFORMAL);

//Assert
verifyNoInteractions(translationManagementServiceApiClient);
verify(defaultTranslationsService).fetchDefaultTranslations(any(), any(), any());

}

}
Loading