ATS-531 : Reformat code

This commit is contained in:
Cezar.Leahu
2019-08-14 22:21:06 +03:00
committed by CezarLeahu
parent 70ab0241dd
commit 485347729b
58 changed files with 1310 additions and 1074 deletions

View File

@@ -26,6 +26,7 @@
*/
package org.alfresco.transformer;
import static java.util.stream.Collectors.joining;
import static org.alfresco.transformer.fs.FileManager.buildFile;
import static org.alfresco.transformer.fs.FileManager.createTargetFileName;
import static org.alfresco.transformer.fs.FileManager.deleteFile;
@@ -39,7 +40,6 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.stream.Collectors;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
@@ -76,32 +76,34 @@ import com.fasterxml.jackson.databind.ObjectMapper;
*
* <p>Status Codes:</p>
* <ul>
* <li>200 Success</li>
* <li>400 Bad Request: Request parameter <name> is missing (missing mandatory parameter)</li>
* <li>400 Bad Request: Request parameter <name> is of the wrong type</li>
* <li>400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)</li>
* <li>400 Bad Request: The source filename was not supplied</li>
* <li>500 Internal Server Error: (no message with low level IO problems)</li>
* <li>500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)</li>
* <li>500 Internal Server Error: Transformer version check exit code was not 0</li>
* <li>500 Internal Server Error: Transformer version check failed to create any output</li>
* <li>500 Internal Server Error: Could not read the target file</li>
* <li>500 Internal Server Error: The target filename was malformed (should not happen because of other checks)</li>
* <li>500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)</li>
* <li>500 Internal Server Error: Filename encoding error</li>
* <li>507 Insufficient Storage: Failed to store the source file</li>
* <li>200 Success</li>
* <li>400 Bad Request: Request parameter <name> is missing (missing mandatory parameter)</li>
* <li>400 Bad Request: Request parameter <name> is of the wrong type</li>
* <li>400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)</li>
* <li>400 Bad Request: The source filename was not supplied</li>
* <li>500 Internal Server Error: (no message with low level IO problems)</li>
* <li>500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)</li>
* <li>500 Internal Server Error: Transformer version check exit code was not 0</li>
* <li>500 Internal Server Error: Transformer version check failed to create any output</li>
* <li>500 Internal Server Error: Could not read the target file</li>
* <li>500 Internal Server Error: The target filename was malformed (should not happen because of other checks)</li>
* <li>500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)</li>
* <li>500 Internal Server Error: Filename encoding error</li>
* <li>507 Insufficient Storage: Failed to store the source file</li>
*
* <li>408 Request Timeout -- TODO implement general timeout mechanism rather than depend on transformer timeout
* (might be possible for external processes)</li>
* <li>415 Unsupported Media Type -- TODO possibly implement a check on supported source and target mimetypes (probably not)</li>
* <li>429 Too Many Requests: Returned by liveness probe</li>
* <li>408 Request Timeout -- TODO implement general timeout mechanism rather than depend on transformer timeout
* (might be possible for external processes)</li>
* <li>415 Unsupported Media Type -- TODO possibly implement a check on supported source and target mimetypes (probably not)</li>
* <li>429 Too Many Requests: Returned by liveness probe</li>
* </ul>
* <p>Provides methods to help super classes perform /transform requests. Also responses to /version, /ready and /live
* requests.</p>
*/
public abstract class AbstractTransformerController implements TransformController
{
private static final Logger logger = LoggerFactory.getLogger(AbstractTransformerController.class);
private static final Logger logger = LoggerFactory.getLogger(
AbstractTransformerController.class);
private static String ENGINE_CONFIG = "engine_config.json";
@Autowired
@@ -161,8 +163,11 @@ public abstract class AbstractTransformerController implements TransformControll
if (!errors.getAllErrors().isEmpty())
{
reply.setStatus(HttpStatus.BAD_REQUEST.value());
reply.setErrorDetails(errors.getAllErrors().stream().map(Object::toString)
.collect(Collectors.joining(", ")));
reply.setErrorDetails(errors
.getAllErrors()
.stream()
.map(Object::toString)
.collect(joining(", ")));
logger.error("Invalid request, sending {}", reply);
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
@@ -246,7 +251,7 @@ public abstract class AbstractTransformerController implements TransformControll
reply.setStatus(e.getStatusCode().value());
reply.setErrorDetails(messageWithCause("Failed at writing the transformed file. ", e));
logger.error("Failed to save target file (HttpClientErrorException), sending {}" +
logger.error("Failed to save target file (HttpClientErrorException), sending " +
reply, e);
return new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus()));
}
@@ -314,7 +319,7 @@ public abstract class AbstractTransformerController implements TransformControll
if (body == null)
{
String message = "Source file with reference: " + sourceReference + " is null or empty. "
+ "Transformation will fail and stop now as there is no content to be transformed.";
+ "Transformation will fail and stop now as there is no content to be transformed.";
logger.warn(message);
throw new TransformException(BAD_REQUEST.value(), message);
}
@@ -322,7 +327,7 @@ public abstract class AbstractTransformerController implements TransformControll
logger.debug("Read source content {} length={} contentType={}",
sourceReference, size, contentType);
save(body, file);
LogEntry.setSource(filename, size);
return file;

View File

@@ -26,6 +26,8 @@
*/
package org.alfresco.transformer;
import java.util.Optional;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
@@ -44,8 +46,6 @@ import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* Queue Transformer service.
* This service reads all the requests for the particular engine, forwards them to the worker
@@ -56,12 +56,11 @@ import java.util.Optional;
* created on 18/12/2018
*/
@Component
@ConditionalOnProperty(name="activemq.url")
@ConditionalOnProperty(name = "activemq.url")
public class QueueTransformService
{
private static final Logger logger = LoggerFactory.getLogger(QueueTransformService.class);
// TODO: I know this is not smart but all the the transformation logic is in the Controller.
// The controller also manages the probes. There's tons of refactoring needed there, hence this. Sorry.
@Autowired
@@ -98,7 +97,9 @@ public class QueueTransformService
}
catch (JMSException e)
{
logger.error("Cannot find 'replyTo' destination queue for message with correlationID {}. Stopping. ", correlationId);
logger.error(
"Cannot find 'replyTo' destination queue for message with correlationID {}. Stopping. ",
correlationId);
return;
}
@@ -126,7 +127,7 @@ public class QueueTransformService
}
TransformReply reply = transformController.transform(transformRequest.get(), null)
.getBody();
.getBody();
transformReplySender.send(replyToDestinationQueue, reply);
}
@@ -150,14 +151,14 @@ public class QueueTransformService
{
String message =
"MessageConversionException during T-Request deserialization of message with correlationID "
+ correlationId + ": ";
+ correlationId + ": ";
throw new TransformException(HttpStatus.BAD_REQUEST.value(), message + e.getMessage());
}
catch (JMSException e)
{
String message =
"JMSException during T-Request deserialization of message with correlationID "
+ correlationId + ": ";
+ correlationId + ": ";
throw new TransformException(HttpStatus.INTERNAL_SERVER_ERROR.value(),
message + e.getMessage());
}
@@ -165,21 +166,24 @@ public class QueueTransformService
{
String message =
"Exception during T-Request deserialization of message with correlationID "
+ correlationId + ": ";
+ correlationId + ": ";
throw new TransformException(HttpStatus.INTERNAL_SERVER_ERROR.value(),
message + e.getMessage());
}
}
private void replyWithInternalSvErr(final Destination destination, final String msg, final String correlationId)
private void replyWithInternalSvErr(final Destination destination, final String msg,
final String correlationId)
{
replyWithError(destination, HttpStatus.INTERNAL_SERVER_ERROR, msg, correlationId);
}
private void replyWithError(final Destination destination, final HttpStatus status, final String msg,
private void replyWithError(final Destination destination, final HttpStatus status,
final String msg,
final String correlationId)
{
final TransformReply reply = TransformReply.builder()
final TransformReply reply = TransformReply
.builder()
.withStatus(status.value())
.withErrorDetails(msg)
.build();

View File

@@ -53,7 +53,7 @@ public class TransformInterceptor extends HandlerInterceptorAdapter
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
HttpServletResponse response, Object handler, Exception ex)
{
// TargetFile cannot be deleted until completion, otherwise 0 bytes are sent.
deleteFile(request, SOURCE_FILE);

View File

@@ -26,12 +26,12 @@
*/
package org.alfresco.transformer.config;
import org.alfresco.transform.client.model.TransformRequestValidator;
import org.alfresco.transformer.TransformInterceptor;
import org.alfresco.transformer.clients.AlfrescoSharedFileStoreClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.alfresco.transform.client.model.TransformRequestValidator;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@@ -40,16 +40,18 @@ public class WebApplicationConfig implements WebMvcConfigurer
{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(transformInterceptor()).addPathPatterns("/transform", "/live", "/ready");
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(transformInterceptor()).addPathPatterns("/transform", "/live",
"/ready");
}
@Bean
public TransformInterceptor transformInterceptor() {
public TransformInterceptor transformInterceptor()
{
return new TransformInterceptor();
}
@Bean
public RestTemplate restTemplate()
{
@@ -57,7 +59,8 @@ public class WebApplicationConfig implements WebMvcConfigurer
}
@Bean
public AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient(){
public AlfrescoSharedFileStoreClient alfrescoSharedFileStoreClient()
{
return new AlfrescoSharedFileStoreClient();
}

View File

@@ -37,12 +37,13 @@ import org.alfresco.util.exec.RuntimeExec;
import org.alfresco.util.exec.RuntimeExec.ExecutionResult;
/**
*
*/
public abstract class AbstractCommandExecutor implements CommandExecutor
{
private final RuntimeExec transformCommand = createTransformCommand();
private final RuntimeExec checkCommand = createCheckCommand();
protected abstract RuntimeExec createTransformCommand();
protected abstract RuntimeExec createCheckCommand();

View File

@@ -34,7 +34,7 @@ import org.alfresco.transformer.logging.LogEntry;
/**
* Basic interface for executing transformations via Shell commands
*
*
* @author Cezar Leahu
*/
public interface CommandExecutor

View File

@@ -32,7 +32,7 @@ import org.alfresco.transform.exceptions.TransformException;
/**
* Basic interface for executing transformations inside Java/JVM
*
*
* @author Cezar Leahu
*/
public interface JavaExecutor

View File

@@ -51,6 +51,7 @@ import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;
/**
*
*/
public class FileManager
{
@@ -76,7 +77,7 @@ public class FileManager
public static File buildFile(String filename)
{
filename = checkFilename( false, filename);
filename = checkFilename(false, filename);
LogEntry.setTarget(filename);
return TempFileProvider.createTempFile("target_", "_" + filename);
}
@@ -103,7 +104,8 @@ public class FileManager
{
String sourceOrTarget = source ? "source" : "target";
int statusCode = source ? BAD_REQUEST.value() : INTERNAL_SERVER_ERROR.value();
throw new TransformException(statusCode, "The " + sourceOrTarget + " filename was not supplied");
throw new TransformException(statusCode,
"The " + sourceOrTarget + " filename was not supplied");
}
return filename;
}
@@ -112,7 +114,8 @@ public class FileManager
{
try
{
Files.copy(multipartFile.getInputStream(), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
Files.copy(multipartFile.getInputStream(), file.toPath(),
StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e)
{
@@ -129,7 +132,8 @@ public class FileManager
}
catch (IOException e)
{
throw new TransformException(INSUFFICIENT_STORAGE.value(), "Failed to store the source file", e);
throw new TransformException(INSUFFICIENT_STORAGE.value(),
"Failed to store the source file", e);
}
}
@@ -171,28 +175,31 @@ public class FileManager
return filename;
}
/**
* Returns the file name for the target file
*
* @param fileName Desired file name
* @param fileName Desired file name
* @param targetExtension File extension
* @return Target file name
*/
public static String createTargetFileName(String fileName, String targetExtension)
public static String createTargetFileName(final String fileName, final String targetExtension)
{
String targetFilename = null;
String sourceFilename = fileName;
sourceFilename = StringUtils.getFilename(sourceFilename);
if (sourceFilename != null && !sourceFilename.isEmpty())
final String sourceFilename = StringUtils.getFilename(fileName);
if (sourceFilename == null || sourceFilename.isEmpty())
{
String ext = StringUtils.getFilenameExtension(sourceFilename);
targetFilename = (ext != null && !ext.isEmpty()
? sourceFilename.substring(0, sourceFilename.length()-ext.length()-1)
: sourceFilename)+
'.'+targetExtension;
return null;
}
return targetFilename;
final String ext = StringUtils.getFilenameExtension(sourceFilename);
if (ext == null || ext.isEmpty())
{
return sourceFilename + '.' + targetExtension;
}
return sourceFilename.substring(0, sourceFilename.length() - ext.length() - 1) +
'.' + targetExtension;
}
/**
@@ -207,7 +214,7 @@ public class FileManager
{
String filename = multipartFile.getOriginalFilename();
long size = multipartFile.getSize();
filename = checkFilename( true, filename);
filename = checkFilename(true, filename);
File file = TempFileProvider.createTempFile("source_", "_" + filename);
request.setAttribute(SOURCE_FILE, file);
save(multipartFile, file);
@@ -229,7 +236,7 @@ public class FileManager
{
Resource targetResource = load(targetFile);
targetFilename = UriUtils.encodePath(StringUtils.getFilename(targetFilename), "UTF-8");
return ResponseEntity.ok().header(HttpHeaders
return ResponseEntity.ok().header(HttpHeaders
.CONTENT_DISPOSITION,
"attachment; filename*= UTF-8''" + targetFilename).body(targetResource);
}

View File

@@ -135,7 +135,7 @@ public final class LogEntry
int i = filename.lastIndexOf('.');
if (i != -1)
{
filename = filename.substring(i+1);
filename = filename.substring(i + 1);
}
return filename;
}
@@ -201,7 +201,8 @@ public final class LogEntry
if (logEntry.statusCode == OK.value())
{
logEntry.durationStreamOut = System.currentTimeMillis() - logEntry.start -
logEntry.durationStreamIn - max(logEntry.durationTransform, 0) - max(logEntry.durationDelay, 0);
logEntry.durationStreamIn - max(logEntry.durationTransform,
0) - max(logEntry.durationDelay, 0);
}
currentLogEntry.remove();
@@ -228,17 +229,19 @@ public final class LogEntry
public String getDuration()
{
long duration = durationStreamIn + max(durationTransform, 0) + max(durationDelay, 0) + max(durationStreamOut, 0);
long duration = durationStreamIn + max(durationTransform, 0) + max(durationDelay, 0) + max(
durationStreamOut, 0);
return duration <= 5
? ""
: time(duration)+
" ("+
(time(durationStreamIn)+' '+
time(durationTransform)+' '+
(durationDelay > 0
? time(durationDelay)+' '+(durationStreamOut < 0 ? "-" : time(durationStreamOut))
: time(durationStreamOut))).trim()+
")";
: time(duration) +
" (" +
(time(durationStreamIn) + ' ' +
time(durationTransform) + ' ' +
(durationDelay > 0
? time(durationDelay) + ' ' + (durationStreamOut < 0 ? "-" : time(
durationStreamOut))
: time(durationStreamOut))).trim() +
")";
}
public String getSource()
@@ -274,16 +277,16 @@ public final class LogEntry
private String time(long ms)
{
return ms == -1 ? "" : size(ms, "1ms",
new String[] { "ms", "s", "min", "hr" },
new long[] { 1000, 60*1000, 60*60*1000, Long.MAX_VALUE});
new String[]{"ms", "s", "min", "hr"},
new long[]{1000, 60 * 1000, 60 * 60 * 1000, Long.MAX_VALUE});
}
private String size(long size)
{
// TODO fix numeric overflow in TB expression
return size == -1 ? "" : size(size, "1 byte",
new String[] { "bytes", " KB", " MB", " GB", " TB" },
new long[] { 1024, 1024*1024, 1024*1024*1024, 1024*1024*1024*1024, Long.MAX_VALUE });
new String[]{"bytes", " KB", " MB", " GB", " TB"},
new long[]{1024, 1024 * 1024, 1024 * 1024 * 1024, 1024 * 1024 * 1024 * 1024, Long.MAX_VALUE});
}
private String size(long size, String singleValue, String[] units, long[] dividers)
@@ -293,16 +296,16 @@ public final class LogEntry
return singleValue;
}
long divider = 1;
for(int i = 0; i < units.length-1; i++)
for (int i = 0; i < units.length - 1; i++)
{
long nextDivider = dividers[i];
if(size < nextDivider)
if (size < nextDivider)
{
return unitFormat(size, divider, units[i]);
}
divider = nextDivider;
}
return unitFormat(size, divider, units[units.length-1]);
return unitFormat(size, divider, units[units.length - 1]);
}
private String unitFormat(long size, long divider, String unit)
@@ -311,7 +314,7 @@ public final class LogEntry
int decimalPoint = (int) size % 10;
StringBuilder sb = new StringBuilder();
sb.append(size/10);
sb.append(size / 10);
if (decimalPoint != 0)
{
sb.append(".");

View File

@@ -31,5 +31,5 @@ public interface StandardMessages
String LICENCE =
"License rights for this program may be obtained from Alfresco Software, Ltd. pursuant to a written agreement\n" +
"and any use of this program without such an agreement is prohibited.\n" +
"\n" ;
"\n";
}

View File

@@ -98,7 +98,8 @@ public class MessagingConfig implements JmsListenerConfigurer
@Bean
@ConditionalOnProperty(name = "activemq.url")
public Queue engineRequestQueue(@Value("${queue.engineRequestQueue}") String engineRequestQueueValue)
public Queue engineRequestQueue(
@Value("${queue.engineRequestQueue}") String engineRequestQueueValue)
{
return new ActiveMQQueue(engineRequestQueueValue);
}

View File

@@ -90,13 +90,13 @@ public class TransformMessageConverter implements MessageConverter
@NonNull final Object object,
@NonNull final Session session) throws JMSException, MessageConversionException
{
return converter.toMessage(object, session);
return converter.toMessage(object, session);
}
@Override
@NonNull
public Object fromMessage(@NonNull final Message message) throws JMSException
{
return converter.fromMessage(message);
return converter.fromMessage(message);
}
}

View File

@@ -56,7 +56,8 @@ public class TransformReplySender
send(destination, reply, reply.getRequestId());
}
public void send(final Destination destination, final TransformReply reply, final String correlationId)
public void send(final Destination destination, final TransformReply reply,
final String correlationId)
{
try
{

View File

@@ -37,18 +37,18 @@ public class FileRefEntity
{
private String fileRef;
public FileRefEntity()
{
}
public FileRefEntity() {}
public FileRefEntity(String fileRef)
{
this.fileRef = fileRef;
}
public void setFileRef(String fileRef){
public void setFileRef(String fileRef)
{
this.fileRef = fileRef;
}
public String getFileRef()
{
return fileRef;

View File

@@ -43,8 +43,8 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.servlet.http.HttpServletRequest;
import org.alfresco.transformer.AbstractTransformerController;
import org.alfresco.transform.exceptions.TransformException;
import org.alfresco.transformer.AbstractTransformerController;
import org.alfresco.transformer.logging.LogEntry;
import org.alfresco.util.TempFileProvider;
import org.slf4j.Logger;
@@ -65,11 +65,11 @@ import org.slf4j.LoggerFactory;
* code resulting in the k8s pod being terminated, after a predefined number of transformations have been performed or
* if any transformation takes a long time. These are controlled by environment variables:</p>
* <ul>
* <li>livenessPercent - The percentage slower the small test transform must be to indicate there is a problem.</li>
* <li>livenessTransformPeriodSeconds - As liveness probes should be frequent, not every request should result in
* a test transformation. This value defines the gap between transformations.</li>
* <li>maxTransforms - the maximum number of transformation to be performed before a restart.</li>
* <li>maxTransformSeconds - the maximum time for a transformation, including failed ones.</li>
* <li>livenessPercent - The percentage slower the small test transform must be to indicate there is a problem.</li>
* <li>livenessTransformPeriodSeconds - As liveness probes should be frequent, not every request should result in
* a test transformation. This value defines the gap between transformations.</li>
* <li>maxTransforms - the maximum number of transformation to be performed before a restart.</li>
* <li>maxTransformSeconds - the maximum time for a transformation, including failed ones.</li>
* </ul>
*/
public abstract class ProbeTestTransform
@@ -111,28 +111,30 @@ public abstract class ProbeTestTransform
/**
* See Probes.md for more info.
* @param expectedLength was the length of the target file during testing
* @param plusOrMinus simply allows for some variation in the transformed size caused by new versions of dates
* @param livenessPercent indicates that for this type of transform a variation up to 2 and a half times is not
* unreasonable under load
* @param maxTransforms default values normally supplied by helm. Not identical so we can be sure which value is used.
* @param maxTransformSeconds default values normally supplied by helm. Not identical so we can be sure which value is used.
* @param livenessTransformPeriodSeconds default values normally supplied by helm. Not identical so we can be sure which value is used.
*
* @param expectedLength was the length of the target file during testing
* @param plusOrMinus simply allows for some variation in the transformed size caused by new versions of dates
* @param livenessPercent indicates that for this type of transform a variation up to 2 and a half times is not
* unreasonable under load
* @param maxTransforms default values normally supplied by helm. Not identical so we can be sure which value is used.
* @param maxTransformSeconds default values normally supplied by helm. Not identical so we can be sure which value is used.
* @param livenessTransformPeriodSeconds default values normally supplied by helm. Not identical so we can be sure which value is used.
*/
public ProbeTestTransform(AbstractTransformerController controller,
String sourceFilename, String targetFilename, long expectedLength, long plusOrMinus,
int livenessPercent, long maxTransforms, long maxTransformSeconds,
long livenessTransformPeriodSeconds)
String sourceFilename, String targetFilename, long expectedLength, long plusOrMinus,
int livenessPercent, long maxTransforms, long maxTransformSeconds,
long livenessTransformPeriodSeconds)
{
this.sourceFilename = sourceFilename;
this.targetFilename = targetFilename;
minExpectedLength = Math.max(0, expectedLength-plusOrMinus);
maxExpectedLength = expectedLength+plusOrMinus;
minExpectedLength = Math.max(0, expectedLength - plusOrMinus);
maxExpectedLength = expectedLength + plusOrMinus;
this.livenessPercent = (int) getPositiveLongEnv("livenessPercent", livenessPercent);
maxTransformCount = getPositiveLongEnv("maxTransforms", maxTransforms);
maxTransformTime = getPositiveLongEnv("maxTransformSeconds", maxTransformSeconds)*1000;
livenessTransformPeriod = getPositiveLongEnv("livenessTransformPeriodSeconds", livenessTransformPeriodSeconds)*1000;
maxTransformTime = getPositiveLongEnv("maxTransformSeconds", maxTransformSeconds) * 1000;
livenessTransformPeriod = getPositiveLongEnv("livenessTransformPeriodSeconds",
livenessTransformPeriodSeconds) * 1000;
livenessTransformEnabled = getBooleanEnvVar("livenessTransformEnabled", false);
}
@@ -182,9 +184,9 @@ public abstract class ProbeTestTransform
}
return (isLiveProbe && livenessTransformPeriod > 0 &&
(transCount <= AVERAGE_OVER_TRANSFORMS || nextTransformTime < System.currentTimeMillis()))
|| !initialised.get()
? doTransform(request, isLiveProbe)
: doNothing(isLiveProbe);
|| !initialised.get()
? doTransform(request, isLiveProbe)
: doNothing(isLiveProbe);
}
private String doNothing(boolean isLiveProbe)
@@ -238,39 +240,39 @@ public abstract class ProbeTestTransform
checkMaxTransformTimeAndCount(isLiveProbe);
return getProbeMessage(isLiveProbe)+message;
return getProbeMessage(isLiveProbe) + message;
}
private void checkMaxTransformTimeAndCount(boolean isLiveProbe)
{
if (die.get())
{
throw new TransformException(TOO_MANY_REQUESTS.value(), getMessagePrefix(isLiveProbe) +
"Transformer requested to die. A transform took longer than "+
(maxTransformTime *1000)+" seconds");
throw new TransformException(TOO_MANY_REQUESTS.value(),
getMessagePrefix(isLiveProbe) + "Transformer requested to die. A transform took " +
"longer than " + (maxTransformTime * 1000) + " seconds");
}
if (maxTransformCount > 0 && transformCount.get() > maxTransformCount)
{
throw new TransformException(TOO_MANY_REQUESTS.value(), getMessagePrefix(isLiveProbe) +
"Transformer requested to die. It has performed more than "+
maxTransformCount+" transformations");
throw new TransformException(TOO_MANY_REQUESTS.value(),
getMessagePrefix(isLiveProbe) + "Transformer requested to die. It has performed " +
"more than " + maxTransformCount + " transformations");
}
}
private File getSourceFile(HttpServletRequest request, boolean isLiveProbe)
{
incrementTransformerCount();
File sourceFile = TempFileProvider.createTempFile("source_", "_"+ sourceFilename);
File sourceFile = TempFileProvider.createTempFile("source_", "_" + sourceFilename);
request.setAttribute(SOURCE_FILE, sourceFile);
try (InputStream inputStream = this.getClass().getResourceAsStream('/'+sourceFilename))
try (InputStream inputStream = this.getClass().getResourceAsStream('/' + sourceFilename))
{
Files.copy(inputStream, sourceFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e)
{
throw new TransformException(INSUFFICIENT_STORAGE.value(), getMessagePrefix(isLiveProbe)+
"Failed to store the source file", e);
throw new TransformException(INSUFFICIENT_STORAGE.value(),
getMessagePrefix(isLiveProbe) + "Failed to store the source file", e);
}
long length = sourceFile.length();
LogEntry.setSource(sourceFilename, length);
@@ -279,7 +281,7 @@ public abstract class ProbeTestTransform
private File getTargetFile(HttpServletRequest request)
{
File targetFile = TempFileProvider.createTempFile("target_", "_"+targetFilename);
File targetFile = TempFileProvider.createTempFile("target_", "_" + targetFilename);
request.setAttribute(TARGET_FILE, targetFile);
LogEntry.setTarget(targetFilename);
return targetFile;
@@ -302,13 +304,15 @@ public abstract class ProbeTestTransform
String message = getMessagePrefix(isLiveProbe) + "Success - Transform " + time + "ms";
if (++transCount > 1)
{
normalTime = (normalTime * (transCount-2) + time) / (transCount-1);
normalTime = (normalTime * (transCount - 2) + time) / (transCount - 1);
maxTime = (normalTime * (livenessPercent + 100)) / 100;
if ((!isLiveProbe && !readySent.getAndSet(true)) || transCount > AVERAGE_OVER_TRANSFORMS)
if ((!isLiveProbe && !readySent.getAndSet(
true)) || transCount > AVERAGE_OVER_TRANSFORMS)
{
nextTransformTime = System.currentTimeMillis() + livenessTransformPeriod;
logger.trace("{} - {}ms+{}%={}ms", message, normalTime, livenessPercent, maxTime);
logger.trace("{} - {}ms+{}%={}ms", message, normalTime, livenessPercent,
maxTime);
}
}
else if (!isLiveProbe && !readySent.getAndSet(true))
@@ -362,7 +366,6 @@ public abstract class ProbeTestTransform
public long getNormalTime()
{
return normalTime;
}
}

View File

@@ -27,6 +27,7 @@
package org.alfresco.transformer.util;
/**
*
*/
public class Util
{
@@ -49,6 +50,6 @@ public class Util
*/
public static Boolean stringToBoolean(String param)
{
return param == null? null : Boolean.parseBoolean(param);
return param == null ? null : Boolean.parseBoolean(param);
}
}

View File

@@ -26,16 +26,20 @@
*/
package org.alfresco.transformer;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
/**
* Super class for testing controllers with a server. Includes tests for the AbstractTransformerController itself.
* Note: Currently uses json rather than HTML as json is returned by this spring boot test harness.
@@ -64,7 +68,8 @@ public abstract class AbstractHttpRequestTest
@Test
public void logPageExists()
{
String result = restTemplate.getForObject("http://localhost:" + port + "/log", String.class);
String result = restTemplate.getForObject("http://localhost:" + port + "/log",
String.class);
String title = getTransformerName() + ' ' + "Log";
assertTrue("\"" + title + "\" should be part of the page title", result.contains(title));
@@ -73,10 +78,12 @@ public abstract class AbstractHttpRequestTest
@Test
public void errorPageExists()
{
String result = restTemplate.getForObject("http://localhost:" + port + "/error", String.class);
String result = restTemplate.getForObject("http://localhost:" + port + "/error",
String.class);
String title = getTransformerName() + ' ' + "Error Page";
assertTrue("\"" + title + "\" should be part of the page title", result.contains("Error Page"));
assertTrue("\"" + title + "\" should be part of the page title",
result.contains("Error Page"));
}
@Test
@@ -84,7 +91,7 @@ public abstract class AbstractHttpRequestTest
{
// Transformer name is not part of the title as this is checked by another handler
assertTransformError(false,
"Required request part 'file' is not present");
"Required request part 'file' is not present");
}
@Test
@@ -96,7 +103,7 @@ public abstract class AbstractHttpRequestTest
private void assertMissingParameter(String name)
{
assertTransformError(true,
getTransformerName() + " - Request parameter '" + name + "' is missing");
getTransformerName() + " - Request parameter '" + name + "' is missing");
}
private void assertTransformError(boolean addFile, String errorMessage)
@@ -104,12 +111,15 @@ public abstract class AbstractHttpRequestTest
LinkedMultiValueMap<String, Object> parameters = new LinkedMultiValueMap<>();
if (addFile)
{
parameters.add("file", new org.springframework.core.io.ClassPathResource("quick."+getSourceExtension()));
parameters.add("file",
new org.springframework.core.io.ClassPathResource("quick." + getSourceExtension()));
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<LinkedMultiValueMap<String, Object>> entity = new HttpEntity<>(parameters, headers);
ResponseEntity<String> response = restTemplate.exchange("/transform", HttpMethod.POST, entity, String.class, "");
HttpEntity<LinkedMultiValueMap<String, Object>> entity = new HttpEntity<>(parameters,
headers);
ResponseEntity<String> response = restTemplate.exchange("/transform", HttpMethod.POST,
entity, String.class, "");
assertEquals(errorMessage, getErrorMessage(response.getBody()));
}
@@ -125,7 +135,7 @@ public abstract class AbstractHttpRequestTest
int j = content.indexOf("\",\"path\":", i);
if (j != -1)
{
message = content.substring(i+11, j);
message = content.substring(i + 11, j);
}
}
return message;

View File

@@ -54,11 +54,12 @@ public abstract class AbstractQueueTransformServiceIT
@Autowired
private JmsTemplate jmsTemplate;
private final ActiveMQQueue testingQueue = new ActiveMQQueue("org.alfresco.transform.engine.IT");
private final ActiveMQQueue testingQueue = new ActiveMQQueue(
"org.alfresco.transform.engine.IT");
@Test
public void queueTransformServiceIT() {
public void queueTransformServiceIT()
{
TransformRequest request = buildRequest();
jmsTemplate.convertAndSend(engineRequestQueue, request, m -> {

View File

@@ -30,9 +30,11 @@ import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@@ -107,7 +109,8 @@ public abstract class AbstractTransformerControllerTest
protected abstract AbstractTransformerController getController();
protected abstract void updateTransformRequestWithSpecificOptions(TransformRequest transformRequest);
protected abstract void updateTransformRequestWithSpecificOptions(
TransformRequest transformRequest);
/**
* This method ends up being the core of the mock.
@@ -151,14 +154,17 @@ public abstract class AbstractTransformerControllerTest
URL testFileUrl = classLoader.getResource(testFilename);
if (required && testFileUrl == null)
{
throw new IOException("The test file " + testFilename + " does not exist in the resources directory");
throw new IOException("The test file " + testFilename +
" does not exist in the resources directory");
}
return testFileUrl == null ? null : new File(testFileUrl.getFile());
}
protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile, String... params)
protected MockHttpServletRequestBuilder mockMvcRequest(String url, MockMultipartFile sourceFile,
String... params)
{
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/transform").file(sourceFile);
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart("/transform").file(
sourceFile);
if (params.length % 2 != 0)
{
@@ -175,20 +181,24 @@ public abstract class AbstractTransformerControllerTest
@Test
public void simpleTransformTest() throws Exception
{
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
mockMvc.perform(
mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
.andExpect(status().is(OK.value()))
.andExpect(content().bytes(expectedTargetFileBytes))
.andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension));
.andExpect(header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension));
}
@Test
public void testDelayTest() throws Exception
{
long start = System.currentTimeMillis();
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension, "testDelay", "400"))
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension,
"testDelay", "400"))
.andExpect(status().is(OK.value()))
.andExpect(content().bytes(expectedTargetFileBytes))
.andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension));
.andExpect(header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension));
long ms = System.currentTimeMillis() - start;
System.out.println("Transform incluing test delay was " + ms);
assertTrue("Delay sending the result back was too small " + ms, ms >= 400);
@@ -206,24 +216,30 @@ public abstract class AbstractTransformerControllerTest
// Looks dangerous but is okay as we only use the final filename
public void dotDotSourceFilenameTest() throws Exception
{
sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype, expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "../quick." + sourceExtension, sourceMimetype,
expectedSourceFileBytes);
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
mockMvc.perform(
mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
.andExpect(status().is(OK.value()))
.andExpect(content().bytes(expectedTargetFileBytes))
.andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension));
.andExpect(header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension));
}
@Test
// Is okay, as the target filename is built up from the whole source filename and the targetExtenstion
public void noExtensionSourceFilenameTest() throws Exception
{
sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype, expectedSourceFileBytes);
sourceFile = new MockMultipartFile("file", "../quick", sourceMimetype,
expectedSourceFileBytes);
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
mockMvc.perform(
mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
.andExpect(status().is(OK.value()))
.andExpect(content().bytes(expectedTargetFileBytes))
.andExpect(header().string("Content-Disposition", "attachment; filename*= UTF-8''quick." + targetExtension));
.andExpect(header().string("Content-Disposition",
"attachment; filename*= UTF-8''quick." + targetExtension));
}
@Test
@@ -232,7 +248,8 @@ public abstract class AbstractTransformerControllerTest
{
sourceFile = new MockMultipartFile("file", "abc/", sourceMimetype, expectedSourceFileBytes);
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
mockMvc.perform(
mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
.andExpect(status().is(BAD_REQUEST.value()))
.andExpect(status().reason(containsString("The source filename was not supplied")));
}
@@ -242,7 +259,8 @@ public abstract class AbstractTransformerControllerTest
{
sourceFile = new MockMultipartFile("file", "", sourceMimetype, expectedSourceFileBytes);
mockMvc.perform(mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
mockMvc.perform(
mockMvcRequest("/transform", sourceFile, "targetExtension", targetExtension))
.andExpect(status().is(BAD_REQUEST.value()))
.andExpect(status().reason(containsString("The source filename was not supplied")));
}
@@ -252,7 +270,8 @@ public abstract class AbstractTransformerControllerTest
{
mockMvc.perform(mockMvcRequest("/transform", sourceFile))
.andExpect(status().is(BAD_REQUEST.value()))
.andExpect(status().reason(containsString("Request parameter 'targetExtension' is missing")));
.andExpect(status().reason(
containsString("Request parameter 'targetExtension' is missing")));
}
@Test
@@ -296,12 +315,13 @@ public abstract class AbstractTransformerControllerTest
.perform(MockMvcRequestBuilders
.post("/transform")
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header(CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.content(tr))
.andExpect(status().is(BAD_REQUEST.value()))
.andReturn().getResponse().getContentAsString();
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString, TransformReply.class);
TransformReply transformReply = objectMapper.readValue(transformationReplyAsString,
TransformReply.class);
// Assert the reply
assertEquals(BAD_REQUEST.value(), transformReply.getStatus());
@@ -317,9 +337,10 @@ public abstract class AbstractTransformerControllerTest
ReflectionTestUtils
.setField(AbstractTransformerController.class, "ENGINE_CONFIG", "engine_config.json");
String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value())).andExpect(
header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE))
String response = mockMvc
.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value()))
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
.andReturn().getResponse().getContentAsString();
TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class);
@@ -335,9 +356,10 @@ public abstract class AbstractTransformerControllerTest
ReflectionTestUtils.setField(AbstractTransformerController.class, "ENGINE_CONFIG",
"engine_config_with_duplicates.json");
String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value())).andExpect(
header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE))
String response = mockMvc
.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value()))
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
.andReturn().getResponse().getContentAsString();
TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class);
@@ -349,7 +371,6 @@ public abstract class AbstractTransformerControllerTest
transformConfig.getTransformers().get(0).getSupportedSourceAndTargetList().size());
assertEquals(1,
transformConfig.getTransformers().get(0).getTransformOptions().size());
}
@Test
@@ -363,9 +384,9 @@ public abstract class AbstractTransformerControllerTest
"engine_config_incomplete.json");
String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value())).andExpect(
header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE))
.andReturn().getResponse().getContentAsString();
.andExpect(status().is(OK.value())).andExpect(
header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
.andReturn().getResponse().getContentAsString();
TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class);
@@ -384,9 +405,10 @@ public abstract class AbstractTransformerControllerTest
ReflectionTestUtils.setField(AbstractTransformerController.class, "ENGINE_CONFIG",
"engine_config_no_transform_options.json");
String response = mockMvc.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value())).andExpect(
header().string(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE))
String response = mockMvc
.perform(MockMvcRequestBuilders.get("/transform/config"))
.andExpect(status().is(OK.value()))
.andExpect(header().string(CONTENT_TYPE, APPLICATION_JSON_UTF8_VALUE))
.andReturn().getResponse().getContentAsString();
TransformConfig transformConfig = objectMapper.readValue(response, TransformConfig.class);
@@ -405,7 +427,8 @@ public abstract class AbstractTransformerControllerTest
new TransformOptionValue(false, "page"),
new TransformOptionValue(false, "width"),
new TransformOptionGroup(false, transformOptionGroup));
Map<String, Set<TransformOption>> transformOptionsMap = ImmutableMap.of("engineXOptions", transformOptions);
Map<String, Set<TransformOption>> transformOptionsMap = ImmutableMap.of("engineXOptions",
transformOptions);
Transformer transformer = buildTransformer("application/pdf", "image/png", "engineXOptions",
"engineX");

View File

@@ -27,12 +27,16 @@
package org.alfresco.transformer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import org.alfresco.transform.client.model.TransformReply;
import org.alfresco.transform.client.model.TransformRequest;
import org.alfresco.transformer.messaging.TransformMessageConverter;
@@ -48,10 +52,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jms.support.converter.MessageConversionException;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
public class QueueTransformServiceTest
{
@Mock
@@ -98,10 +98,13 @@ public class QueueTransformServiceTest
ActiveMQQueue destination = new ActiveMQQueue();
msg.setJMSReplyTo(destination);
TransformReply reply = TransformReply.builder()
.withStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()).withErrorDetails(
TransformReply reply = TransformReply
.builder()
.withStatus(HttpStatus.INTERNAL_SERVER_ERROR.value())
.withErrorDetails(
"JMS exception during T-Request deserialization of message with correlationID "
+ msg.getCorrelationId() + ": null").build();
+ msg.getCorrelationId() + ": null")
.build();
doReturn(null).when(transformMessageConverter).fromMessage(msg);
@@ -122,10 +125,13 @@ public class QueueTransformServiceTest
ActiveMQQueue destination = new ActiveMQQueue();
msg.setJMSReplyTo(destination);
TransformReply reply = TransformReply.builder().withStatus(HttpStatus.BAD_REQUEST.value())
TransformReply reply = TransformReply
.builder()
.withStatus(HttpStatus.BAD_REQUEST.value())
.withErrorDetails(
"Message conversion exception during T-Request deserialization of message with correlationID"
+ msg.getCorrelationId() + ": null").build();
+ msg.getCorrelationId() + ": null")
.build();
doThrow(MessageConversionException.class).when(transformMessageConverter).fromMessage(msg);
@@ -146,10 +152,12 @@ public class QueueTransformServiceTest
ActiveMQQueue destination = new ActiveMQQueue();
msg.setJMSReplyTo(destination);
TransformReply reply = TransformReply.builder()
TransformReply reply = TransformReply
.builder()
.withStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()).withErrorDetails(
"JMSException during T-Request deserialization of message with correlationID " + msg
.getCorrelationId() + ": null").build();
.getCorrelationId() + ": null")
.build();
doThrow(JMSException.class).when(transformMessageConverter).fromMessage(msg);
@@ -169,7 +177,9 @@ public class QueueTransformServiceTest
msg.setJMSReplyTo(destination);
TransformRequest request = new TransformRequest();
TransformReply reply = TransformReply.builder().withStatus(HttpStatus.CREATED.value())
TransformReply reply = TransformReply
.builder()
.withStatus(HttpStatus.CREATED.value())
.build();
doReturn(request).when(transformMessageConverter).fromMessage(msg);
@@ -208,8 +218,9 @@ public class QueueTransformServiceTest
doReturn(destination).when(msg).getJMSReplyTo();
TransformRequest request = new TransformRequest();
TransformReply reply = TransformReply.builder().withStatus(HttpStatus.CREATED.value())
.build();
TransformReply reply = TransformReply.builder()
.withStatus(HttpStatus.CREATED.value())
.build();
doReturn(request).when(transformMessageConverter).fromMessage(msg);
doReturn(new ResponseEntity<>(reply, HttpStatus.valueOf(reply.getStatus())))