Skip to content

Commit

Permalink
Merge pull request #52 from europeana/EA-3842-eTransl-error-callback
Browse files Browse the repository at this point in the history
eTransl error callback
  • Loading branch information
gsergiu authored May 15, 2024
2 parents 9fe597c + 8560834 commit 49030b3
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,30 +40,33 @@ public class ETranslationTranslationService extends AbstractTranslationService {
private final String domain;
//this is the base url of the translation api (without the request handler (or the controller) endpoint)
private final String callbackUrl;
private final String callbackErrorUrl;
private final String credentialUsername;
private final String credentialPwd;
private final int maxWaitMillisec;
private final RedisMessageListenerContainer redisMessageListenerContainer;
public static final String baseUrlTests="base-url-for-testing";
public static final String markupDelimiter="\ndeenPVsaOg\n";//base64 encoded string (as in generateRedisKey()) with new lines
public static final String markupDelimiterWithoutNewline="deenPVsaOg";
public static final String eTranslationErrorCallbackIndicator="eTranslationErrorCallback";

public ETranslationTranslationService(String baseUrl, String domain, String callbackUrl, int maxWaitMillisec,
public ETranslationTranslationService(String baseUrl, String domain, String callbackUrl, String callbackErrorUrl, int maxWaitMillisec,
String username, String password, RedisMessageListenerContainer redisMessageListenerContainer) throws TranslationException {
if(!baseUrlTests.equals(baseUrl)) {
validateETranslConfigParams(baseUrl, domain, callbackUrl, maxWaitMillisec, username, password);
validateETranslConfigParams(baseUrl, domain, callbackUrl, callbackErrorUrl, maxWaitMillisec, username, password);
}
this.baseUrl = baseUrl;
this.domain = domain;
this.callbackUrl=callbackUrl;
this.callbackErrorUrl=callbackErrorUrl;
this.maxWaitMillisec=maxWaitMillisec;
this.credentialUsername=username;
this.credentialPwd=password;
this.redisMessageListenerContainer=redisMessageListenerContainer;
}

private void validateETranslConfigParams(String baseUrl, String domain, String callbackUrl,
int maxWaitMillisec, String username, String password) throws TranslationException {
private void validateETranslConfigParams(String baseUrl, String domain, String callbackUrl,
String callbackErrorUrl, int maxWaitMillisec, String username, String password) throws TranslationException {
List<String> missingParams= new ArrayList<>(6);
if(StringUtils.isBlank(baseUrl)) {
missingParams.add("baseUrl");
Expand All @@ -74,6 +77,9 @@ private void validateETranslConfigParams(String baseUrl, String domain, String c
if(StringUtils.isBlank(callbackUrl)) {
missingParams.add("callbackUrl");
}
if(StringUtils.isBlank(callbackErrorUrl)) {
missingParams.add("callbackErrorUrl");
}
if(maxWaitMillisec<=0) {
missingParams.add("maxWaitMillisec (must be >0)");
}
Expand Down Expand Up @@ -160,7 +166,11 @@ private void createRedisMessageListenerAndWaitForResults(List<TranslationObj> tr
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("Received message from redis message listener is: {}", response);
}
if(response!=null) {
if(response.contains(ETranslationTranslationService.eTranslationErrorCallbackIndicator)) {
//eTtransl error callback received
throw new TranslationException(response);
}
else if(response!=null) {
//extractTranslationsFromETranslationHtmlResponse(translationObjs, redisMessageListenerAdapter, response);
extractTranslationsFromETranslationResponse(translationObjs, redisMessageListenerAdapter, response);
}
Expand Down Expand Up @@ -240,6 +250,7 @@ private String generateJointStringForTranslation(List<TranslationObj> translatio
private String createTranslationBodyWithPlainText(String text, String sourceLang, String targetLang, String externalReference) throws JSONException {
JSONObject jsonBody = new JSONObject().put("priority", 0)
.put("requesterCallback", callbackUrl)
.put("errorCallback", callbackErrorUrl)
.put("externalReference", externalReference)
.put("callerInformation", new JSONObject().put("application", credentialUsername).put("username", credentialUsername))
.put("sourceLanguage", sourceLang.toUpperCase(Locale.ENGLISH))
Expand Down Expand Up @@ -272,7 +283,7 @@ private String createTranslationBodyAsHtmlDocument(String text, String sourceLan
String base64EncodedText=Base64.encodeBase64String(text.getBytes(StandardCharsets.UTF_8));
JSONObject jsonBody = new JSONObject().put("priority", 0)
// .put("requesterCallback", callbackUrl)
// .put("errorCallback", callbackUrl)
// .put("errorCallback", callbackErrorUrl)
.put("externalReference", externalReference)
.put("callerInformation", new JSONObject().put("application", credentialUsername).put("username", credentialUsername))
.put("sourceLanguage", sourceLang.toUpperCase(Locale.ENGLISH))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,22 @@ public void onMessage(Message message, byte[] pattern) {
LOGGER.debug("New message received from RedisMessageListener: {}", message);
}
String messageBody=new String(message.getBody(), StandardCharsets.UTF_8);
if(messageBody.contains(ETranslationTranslationService.eTranslationErrorCallbackIndicator)) {
//if we enter here, means the eTranslation error callback is called
this.message=messageBody;
}
else {
/*
* the received message is treated as a json object and we need some adjustments for the escaped characters
* (this only applies if we get the translated text from the translated-text field in the eTransl callback,
* which happens if we send the text to be translated in the textToTranslate request param)
*/
//remove double quotes at the beginning and at the end of the response, from some reason they are duplicated
String messageRemDuplQuotes = messageBody.replaceAll("^\"|\"$", "");
//replace a double backslash with a single backslash
this.message = messageRemDuplQuotes.replace("\\n", "\n");
}

/*
* the received message is treated as a json object and we need some adjustments for the escaped characters
* (this only applies if we get the translated text from the translated-text field in the eTransl callback,
* which happens if we send the text to be translated in the textToTranslate request param)
*/
//remove double quotes at the beginning and at the end of the response, from some reason they are duplicated
String messageRemDuplQuotes = messageBody.replaceAll("^\"|\"$", "");
//replace a double backslash with a single backslash
this.message = messageRemDuplQuotes.replace("\\n", "\n");

//notify all threads waiting on this object
notifyAll();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ void translationETranslation() throws Exception {

mockMvc
.perform(
post("/eTranslation/callback").characterEncoding(StandardCharsets.UTF_8)
post("/etranslation/callback").characterEncoding(StandardCharsets.UTF_8)
.param("external-reference", eTranslRef)
.param("translated-text", translatedText.toString()))
.andExpect(status().isOk());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ public ETranslationTranslationService getETranslationService(
return new ETranslationTranslationService(
translationConfig.getEtranslationBaseUrl(),
translationConfig.getEtranslationDomain(),
translationConfig.getEtranslationCallback(),
translationConfig.getEtranslationCallback(),
translationConfig.getEtranslationErrorCallback(),
translationConfig.getEtranslationMaxWaitMillisec(),
translationConfig.getEtranslationUsername(),
translationConfig.getEtranslationPassword(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ public class TranslationConfig{
@Value("${translation.eTranslation.callback:#{null}}")
private String etranslationCallback;

@Value("${translation.eTranslation.error.callback:#{null}}")
private String etranslationErrorCallback;

@Value("${translation.eTranslation.maxWaitMillisec:30000}")
private int etranslationMaxWaitMillisec;

Expand Down Expand Up @@ -174,6 +177,10 @@ public String getEtranslationCallback() {
return etranslationCallback;
}

public String getEtranslationErrorCallback() {
return etranslationErrorCallback;
}

public int getEtranslationMaxWaitMillisec() {
return etranslationMaxWaitMillisec;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import eu.europeana.api.commons.definitions.utils.LoggingUtils;
import eu.europeana.api.translation.service.etranslation.ETranslationTranslationService;
import eu.europeana.api.translation.web.model.CachedTranslation;
import io.swagger.v3.oas.annotations.tags.Tag;
@RestController
Expand All @@ -25,20 +26,40 @@ public ETranslationCallbackController(RedisTemplate<String, CachedTranslation> r
}

@Tag(description = "ETranslation callback endpoint", name = "eTranslationCallback")
@PostMapping(value = "/eTranslation/callback")
@PostMapping(value = "/etranslation/callback")
public void eTranslationCallback(
@RequestParam(value = "target-language", required = false) String targetLanguage,
@RequestParam(value = "translated-text", required = false) String translatedTextSnippet,
@RequestParam(value = "request-id", required = false) String requestId,
@RequestParam(value = "external-reference", required = true) String externalReference,
@RequestBody(required = false) String body) {
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("eTranslation callback on translation api has been received with the request-id: {}, and the"
LOGGER.debug("eTranslation callback has been received with the request-id: {}, and the"
+ " external-reference: {}", LoggingUtils.sanitizeUserInput(requestId), LoggingUtils.sanitizeUserInput(externalReference));
}
if(externalReference!=null && translatedTextSnippet!=null) {
redisTemplate.convertAndSend(externalReference, translatedTextSnippet);
}
}


@Tag(description = "ETranslation error callback endpoint", name = "eTranslationErrorCallback")
@PostMapping(value = "/etranslation/error-callback")
public void eTranslationErrorCallback(
@RequestParam(value = "error-code", required = false) String errorCode,
@RequestParam(value = "error-message", required = false) String errorMessage,
@RequestParam(value = "target-languages", required = false) String targetLanguages,
@RequestParam(value = "request-id", required = false) String requestId,
@RequestParam(value = "external-reference", required = false) String externalReference,
@RequestBody(required = false) String body) {
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("eTranslation error callback has been received with the following parameters: error-code: {},"
+ "error-message: {}, request-id: {}, external-reference: {}", LoggingUtils.sanitizeUserInput(errorCode),
LoggingUtils.sanitizeUserInput(errorMessage), LoggingUtils.sanitizeUserInput(requestId), LoggingUtils.sanitizeUserInput(externalReference));
}
if(externalReference!=null) {
redisTemplate.convertAndSend(externalReference, String.format("%s: error-code=%s, error-message=%s",
ETranslationTranslationService.eTranslationErrorCallbackIndicator, errorCode, errorMessage));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ translation.eTranslation.password=
# eTranslation domain could be "SPD" (for neural and speed-optimized statistical engines on the cloud. This is the default.) else "Europeana"
translation.eTranslation.domain=
translation.eTranslation.callback=
translation.eTranslation.error.callback=
translation.eTranslation.maxWaitMillisec=

0 comments on commit 49030b3

Please sign in to comment.