MNT-21869 libreoffice timeout set too high (#295)

* MNT-21869 libreoffice timeout set too high
   Reduce default value of timeout for libreoffice from 2000min to 20min
   Add option to configure libreoffice timeout externally.
   Enable to configure externally the port on which the app starts.
  Add external-engine-configuration.md
This commit is contained in:
Alexandru-Eusebiu Epure 2020-09-25 10:54:06 +03:00 committed by GitHub
parent 608fdc1ab4
commit 32e48b413b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 316 additions and 19 deletions

View File

@ -43,6 +43,21 @@ public class AIOCustomConfig
@Value("${transform.core.libreoffice.path}")
private String libreofficePath;
@Value("${transform.core.libreoffice.maxTasksPerProcess}")
private String libreofficeMaxTasksPerProcess;
@Value("${transform.core.libreoffice.timeout}")
private String libreofficeTimeout;
@Value("${transform.core.libreoffice.portNumbers}")
private String libreofficePortNumbers;
@Value("${transform.core.libreoffice.templateProfileDir}")
private String libreofficeTemplateProfileDir;
@Value("${transform.core.libreoffice.isEnabled}")
private String libreofficeIsEnabled;
@Value("${transform.core.pdfrenderer.exe}")
private String pdfRendererPath;
@ -73,7 +88,7 @@ public class AIOCustomConfig
aioTransformRegistry.registerTransformer(new SelectingTransformer());
aioTransformRegistry.registerTransformer(new TikaJavaExecutor());
aioTransformRegistry.registerTransformer(new ImageMagickCommandExecutor(imageMagickExePath, imageMagickDynPath, imageMagickRootPath, imageMagickCodersPath, imageMagickConfigPath));
aioTransformRegistry.registerTransformer(new LibreOfficeJavaExecutor(libreofficePath));
aioTransformRegistry.registerTransformer(new LibreOfficeJavaExecutor(libreofficePath, libreofficeMaxTasksPerProcess, libreofficeTimeout, libreofficePortNumbers, libreofficeTemplateProfileDir, libreofficeIsEnabled));
aioTransformRegistry.registerTransformer(new PdfRendererCommandExecutor(pdfRendererPath));
return aioTransformRegistry;
}

View File

@ -6,6 +6,11 @@ transform:
exe: ${PDFRENDERER_EXE:/usr/bin/alfresco-pdf-renderer}
libreoffice:
path: ${LIBREOFFICE_HOME:/opt/libreoffice6.3}
maxTasksPerProcess: ${LIBREOFFICE_MAX_TASKS_PER_PROCESS:200}
timeout: ${LIBREOFFICE_TIMEOUT:1200000}
portNumbers: ${LIBREOFFICE_PORT_NUMBERS:8100}
templateProfileDir: ${LIBREOFFICE_TEMPLATE_PROFILE_DIR:}
isEnabled: ${LIBREOFFICE_IS_ENABLED:true}
imagemagick:
root: ${IMAGEMAGICK_ROOT:/usr/lib64/ImageMagick-7.0.10}
dyn: ${IMAGEMAGICK_DYN:/usr/lib64/ImageMagick-7.0.10/lib}

View File

@ -66,12 +66,27 @@ public class LibreOfficeController extends AbstractTransformerController
@Value("${transform.core.libreoffice.path}")
private String execPath;
@Value("${transform.core.libreoffice.maxTasksPerProcess}")
private String maxTasksPerProcess;
@Value("${transform.core.libreoffice.timeout}")
private String timeout;
@Value("${transform.core.libreoffice.portNumbers}")
private String portNumbers;
@Value("${transform.core.libreoffice.templateProfileDir}")
private String templateProfileDir;
@Value("${transform.core.libreoffice.isEnabled}")
private String isEnabled;
LibreOfficeJavaExecutor javaExecutor;
@PostConstruct
private void init()
{
javaExecutor = new LibreOfficeJavaExecutor(execPath);
javaExecutor = new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, isEnabled);
}
@Override

View File

@ -5,4 +5,9 @@ transform:
config:
location: classpath:libreoffice_engine_config.json
libreoffice:
path: ${LIBREOFFICE_HOME:/opt/libreoffice6.3}
path: ${LIBREOFFICE_HOME:/opt/libreoffice6.3}
maxTasksPerProcess: ${LIBREOFFICE_MAX_TASKS_PER_PROCESS:200}
timeout: ${LIBREOFFICE_TIMEOUT:1200000}
portNumbers: ${LIBREOFFICE_PORT_NUMBERS:8100}
templateProfileDir: ${LIBREOFFICE_TEMPLATE_PROFILE_DIR:}
isEnabled: ${LIBREOFFICE_IS_ENABLED:true}

View File

@ -45,7 +45,6 @@ import static org.springframework.http.HttpHeaders.CONTENT_TYPE;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.IMAGE_PNG_VALUE;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.util.StringUtils.getFilenameExtension;
@ -97,14 +96,29 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
protected ExecutionResult mockExecutionResult;
@Value("${transform.core.libreoffice.path}")
protected String execPath;
private String execPath;
@Value("${transform.core.libreoffice.maxTasksPerProcess}")
private String maxTasksPerProcess;
@Value("${transform.core.libreoffice.timeout}")
private String timeout;
@Value("${transform.core.libreoffice.portNumbers}")
private String portNumbers;
@Value("${transform.core.libreoffice.templateProfileDir}")
private String templateProfileDir;
@Value("${transform.core.libreoffice.isEnabled}")
private String isEnabled;
protected LibreOfficeJavaExecutor javaExecutor;
@PostConstruct
private void init()
{
javaExecutor = Mockito.spy(new LibreOfficeJavaExecutor(execPath));
javaExecutor = Mockito.spy(new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, isEnabled));
}
@Autowired
@ -267,4 +281,103 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
//System test property value can me modified in the pom.xml
assertEquals(execPath, System.getProperty("LIBREOFFICE_HOME"));
}
@Test
public void testOverridingExecutorMaxTasksPerProcess()
{
//System test property value can me modified in the pom.xml
assertEquals(maxTasksPerProcess, System.getProperty("LIBREOFFICE_MAX_TASKS_PER_PROCESS"));
}
@Test
public void testOverridingExecutorTimeout()
{
//System test property value can me modified in the pom.xml
assertEquals(timeout, System.getProperty("LIBREOFFICE_TIMEOUT"));
}
@Test
public void testOverridingExecutorPortNumbers()
{
//System test property value can me modified in the pom.xml
assertEquals(portNumbers, System.getProperty("LIBREOFFICE_PORT_NUMBERS"));
}
@Test
public void testOverridingExecutorTemplateProfileDir()
{
//System test property value can me modified in the pom.xml
assertEquals(templateProfileDir, System.getProperty("LIBREOFFICE_TEMPLATE_PROFILE_DIR"));
}
@Test
public void testOverridingExecutorIsEnabled()
{
//System test property value can me modified in the pom.xml
assertEquals(isEnabled, System.getProperty("LIBREOFFICE_IS_ENABLED"));
}
@Test
public void testInvalidExecutorMaxTasksPerProcess()
{
String errorMessage = "";
try
{
new LibreOfficeJavaExecutor(execPath, "INVALID", timeout, portNumbers, templateProfileDir, isEnabled);
}
catch (IllegalArgumentException e)
{
errorMessage = e.getMessage();
}
assertEquals("LibreOfficeJavaExecutor MAX_TASKS_PER_PROCESS must have a numeric value", errorMessage);
}
@Test
public void testInvalidExecutorTimeout()
{
String errorMessage = "";
try
{
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, "INVALID", portNumbers, templateProfileDir, isEnabled);
}
catch (IllegalArgumentException e)
{
errorMessage = e.getMessage();
}
assertEquals("LibreOfficeJavaExecutor TIMEOUT must have a numeric value", errorMessage);
}
@Test
public void testInvalidExecutorPortNumbers()
{
String errorMessage = "";
try
{
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, null, templateProfileDir, isEnabled);
}
catch (IllegalArgumentException e)
{
errorMessage = e.getMessage();
}
assertEquals("LibreOfficeJavaExecutor PORT variable cannot be null or empty", errorMessage);
}
@Test
public void testInvalidExecutorIsEnabled()
{
String errorMessage = "";
try
{
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, "INVALID");
}
catch (IllegalArgumentException e)
{
errorMessage = e.getMessage();
}
assertEquals("LibreOfficeJavaExecutor IS_ENABLED variable must be set to true/false", errorMessage);
}
}

View File

@ -29,6 +29,7 @@ package org.alfresco.transformer.executors;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.star.task.ErrorCodeIOException;
import org.alfresco.transform.exceptions.TransformException;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -60,36 +61,76 @@ public class LibreOfficeJavaExecutor implements JavaExecutor
private static String LIBREOFFICE_HOME;
private static String LIBREOFFICE_MAX_TASKS_PER_PROCESS;
private static String LIBREOFFICE_TIMEOUT;
private static String LIBREOFFICE_PORT_NUMBERS;
private static String LIBREOFFICE_TEMPLATE_PROFILE_DIR;
private static String LIBREOFFICE_IS_ENABLED;
public static final String LICENCE = "This transformer uses LibreOffice from The Document Foundation. See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt";
private final JodConverter jodconverter;
private final ObjectMapper jsonObjectMapper = new ObjectMapper();
public LibreOfficeJavaExecutor(String path)
public LibreOfficeJavaExecutor(String path, String maxTasksPerProcess, String timeout, String portNumbers, String templateProfileDir, String isEnabled)
{
if (path == null || path.isEmpty())
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor OFFICE_HOME variable cannot be null or empty");
throw new IllegalArgumentException("LibreOfficeJavaExecutor OFFICE_HOME cannot be null or empty");
}
LIBREOFFICE_HOME = path;
if(timeout == null || timeout.isEmpty() || !StringUtils.isNumeric(timeout))
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor TIMEOUT must have a numeric value");
}
LIBREOFFICE_TIMEOUT = timeout;
if(maxTasksPerProcess == null || maxTasksPerProcess.isEmpty() || !StringUtils.isNumeric(maxTasksPerProcess))
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor MAX_TASKS_PER_PROCESS must have a numeric value");
}
LIBREOFFICE_MAX_TASKS_PER_PROCESS = maxTasksPerProcess;
if(portNumbers == null || portNumbers.isEmpty())
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor PORT variable cannot be null or empty");
}
// value parsed and validated in JodConverterSharedInstance#parsePortNumbers(String s, String sys)
LIBREOFFICE_PORT_NUMBERS = portNumbers;
if (templateProfileDir == null)
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor TEMPLATE_PROFILE_DIR variable cannot be null");
}
LIBREOFFICE_TEMPLATE_PROFILE_DIR = templateProfileDir;
if(isEnabled == null || isEnabled.isEmpty() || !(isEnabled.equalsIgnoreCase("true")|| isEnabled.equalsIgnoreCase("false")))
{
throw new IllegalArgumentException("LibreOfficeJavaExecutor IS_ENABLED variable must be set to true/false");
}
LIBREOFFICE_IS_ENABLED = isEnabled;
jodconverter = createJodConverter();
}
private static JodConverter createJodConverter()
{
final String timeout = "120000000";
final JodConverterSharedInstance jodconverter = new JodConverterSharedInstance();
jodconverter.setOfficeHome(LIBREOFFICE_HOME); // jodconverter.officeHome
jodconverter.setMaxTasksPerProcess("200"); // jodconverter.maxTasksPerProcess
jodconverter.setTaskExecutionTimeout(timeout); // jodconverter.maxTaskExecutionTimeout
jodconverter.setTaskQueueTimeout(timeout); // jodconverter.taskQueueTimeout
jodconverter.setConnectTimeout(timeout); // jodconverter.connectTimeout
jodconverter.setPortNumbers("8100"); // jodconverter.portNumbers
jodconverter.setTemplateProfileDir(""); // jodconverter.templateProfileDir
jodconverter.setEnabled("true"); // jodconverter.enabled
jodconverter.setOfficeHome(LIBREOFFICE_HOME); // jodconverter.officeHome
jodconverter.setMaxTasksPerProcess(LIBREOFFICE_MAX_TASKS_PER_PROCESS); // jodconverter.maxTasksPerProcess
jodconverter.setTaskExecutionTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.maxTaskExecutionTimeout
jodconverter.setTaskQueueTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.taskQueueTimeout
jodconverter.setConnectTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.connectTimeout
jodconverter.setPortNumbers(LIBREOFFICE_PORT_NUMBERS); // jodconverter.portNumbers
jodconverter.setTemplateProfileDir(LIBREOFFICE_TEMPLATE_PROFILE_DIR); // jodconverter.templateProfileDir
jodconverter.setEnabled(LIBREOFFICE_IS_ENABLED); // jodconverter.enabled
jodconverter.afterPropertiesSet();
return jodconverter;

View File

@ -18,7 +18,7 @@ activemq:
url: ${ACTIVEMQ_URL:false}
server:
port: 8090
port: ${SERVER.PORT:8090}
error:
include-message: ALWAYS

View File

@ -0,0 +1,97 @@
# T-engine properties can be configured externally
In order to configure an external property it needs to be set as ENV property.
The following externalized T-engines properties are available:
## Tika
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port. | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for receiving async requests. | org.alfresco.transform.engine.tika.acs |
## Pdf-renderer
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.alfresco-pdf-renderer.acs |
| PDFRENDERER_EXE | Path to Pdf-renderer EXE. | /usr/bin/alfresco-pdf-renderer |
## Misc
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.misc.acs |
## Libreoffice
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.libreoffice.acs |
| LIBREOFFICE_HOME | Path to LibreOffice_Home. | /opt/libreoffice6.3 |
| LIBREOFFICE_MAX_TASKS_PER_PROCESS | Number of maximum tasks per process. | 200 |
| LIBREOFFICE_TIMEOUT | Timeout value for LibreOffice `execution timeout`, `queue timeout` and `connection timeout`. | 1200000 |
| LIBREOFFICE_PORT_NUMBERS | LibreOffice port. | 8100 |
| LIBREOFFICE_TEMPLATE_PROFILE_DIR | Path to user profile. | |
| LIBREOFFICE_IS_ENABLED | Enables Libreoffice executioner. | true |
## Imagemagick
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.imagemagick.acs |
| IMAGEMAGICK_ROOT | Path to Imagemagick Root. | /usr/lib64/ImageMagick-7.0.10 |
| IMAGEMAGICK_DYN | Path to Imagemagick DYLD. | /usr/lib64/ImageMagick-7.0.10/lib |
| IMAGEMAGICK_EXE | Path to Imagemagick EXE. | /usr/bin/convert |
| IMAGEMAGICK_CODERS | Path to Imagemagick custom coders. | |
| IMAGEMAGICK_CONFIG | Path to Imagemagick custom config. | |
## Core-aio
| Property | Description | Default value |
|----------|-------------|---------------|
| SERVER.PORT | T-Engine Port | 8090 |
| HOSTNAME | T-Engine Name. | t-engine |
| ACTIVEMQ_URL | ActiveMQ URL. | nio://localhost:61616 |
| ACTIVEMQ_USER | ActiveMQ User. | admin |
| ACTIVEMQ_PASSWORD | ActiveMQ Password. | admin |
| FILE_STORE_URL | T-Engine Port. | http://localhost:8099/alfresco/api/-default-/private/sfs/versions/1/file |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.aio.acs |
| PDFRENDERER_EXE | Path to Pdf-renderer EXE. | /usr/bin/alfresco-pdf-renderer |
| TRANSFORM_ENGINE_REQUEST_QUEUE | T-Engine queue used for async requests. | org.alfresco.transform.engine.libreoffice.acs |
| LIBREOFFICE_HOME | Path to LibreOffice_Home. | /opt/libreoffice6.3 |
| LIBREOFFICE_MAX_TASKS_PER_PROCESS | Number of maximum tasks per process. | 200 |
| LIBREOFFICE_TIMEOUT | Timeout value for LibreOffice `execution timeout`, `queue timeout` and `connection timeout`. | 1200000 |
| LIBREOFFICE_PORT_NUMBERS | LibreOffice port. | 8100 |
| LIBREOFFICE_TEMPLATE_PROFILE_DIR | Path to user profile. | |
| LIBREOFFICE_IS_ENABLED | Enables Libreoffice executioner. | true |
| IMAGEMAGICK_ROOT | Path to Imagemagick Root. | /usr/lib64/ImageMagick-7.0.10 |
| IMAGEMAGICK_DYN | Path to Imagemagick DYLD. | /usr/lib64/ImageMagick-7.0.10/lib |
| IMAGEMAGICK_EXE | Path to Imagemagick EXE. | /usr/bin/convert |
| IMAGEMAGICK_CODERS | Path to Imagemagick custom coders. | |
| IMAGEMAGICK_CONFIG | Path to Imagemagick custom config. | |

View File

@ -349,7 +349,13 @@
<IMAGEMAGICK_DYN>/usr/lib64/ImageMagick-7.0.10/lib</IMAGEMAGICK_DYN>
<IMAGEMAGICK_ROOT>/usr/lib64/ImageMagick-7.0.10</IMAGEMAGICK_ROOT>
<LIBREOFFICE_HOME>/opt/libreoffice6.3</LIBREOFFICE_HOME>
<LIBREOFFICE_MAX_TASKS_PER_PROCESS>200</LIBREOFFICE_MAX_TASKS_PER_PROCESS>
<LIBREOFFICE_TIMEOUT>1200000</LIBREOFFICE_TIMEOUT>
<LIBREOFFICE_PORT_NUMBERS>8100</LIBREOFFICE_PORT_NUMBERS>
<LIBREOFFICE_TEMPLATE_PROFILE_DIR></LIBREOFFICE_TEMPLATE_PROFILE_DIR>
<LIBREOFFICE_IS_ENABLED>true</LIBREOFFICE_IS_ENABLED>
<PDF_RENDERER_EXE>/usr/bin/alfresco-pdf-renderer</PDF_RENDERER_EXE>
<SERVER.PORT>8090</SERVER.PORT>
<buildDirectory>${project.build.directory}</buildDirectory>
</systemPropertyVariables>
</configuration>