Save point: [skip ci]
* pick up alfresco-t-engine-base in 5 base t-engines * Switch over to using new base * Moved files in 5 base t-engines so we can remove the -boot package in the next round of changes
@@ -9,15 +9,15 @@ Contains the common transformer (T-Engine) code, plus a few implementations.
|
|||||||
configuration files and messages sent between clients, T-Engines and T-Router. Also contains code to
|
configuration files and messages sent between clients, T-Engines and T-Router. Also contains code to
|
||||||
work out which transform should be used for a combination of configuration files; see the sub-project's
|
work out which transform should be used for a combination of configuration files; see the sub-project's
|
||||||
[README](https://github.com/Alfresco/alfresco-transform-core/blob/master/alfresco-transform-model/README.md)
|
[README](https://github.com/Alfresco/alfresco-transform-core/blob/master/alfresco-transform-model/README.md)
|
||||||
* `alfresco-transformer-base` - library packaged as a jar file which contains code that is common
|
* `alfresco-t-engine-base` - library packaged as a jar file which contains code that is common
|
||||||
to all the transformers; see the sub-project's
|
to all the transformers; see the sub-project's
|
||||||
[README](https://github.com/Alfresco/alfresco-transform-core/blob/master/alfresco-transformer-base/README.md)
|
[README](https://github.com/Alfresco/alfresco-transform-core/blob/master/alfresco-t-engine-base/README.md)
|
||||||
* `alfresco-transform-<name>` - multiple T-Engines; each one of them builds both a SpringBoot fat jar
|
* `alfresco-transform-<name>` - multiple T-Engines; each one of them builds both a SpringBoot fat jar
|
||||||
and a [Docker image](https://github.com/Alfresco/alfresco-transform-core#docker)
|
and a [Docker image](https://github.com/Alfresco/alfresco-transform-core#docker)
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
In addition to the subprojects (such as `alfresco-transformer-base` README above) some additional documentation can be found in:
|
In addition to the subprojects (such as `alfresco-t-engine-base` README above) some additional documentation can be found in:
|
||||||
|
|
||||||
* [this project's docs](docs) folder
|
* [this project's docs](docs) folder
|
||||||
* [ACS Packaging docs](https://github.com/Alfresco/acs-packaging/tree/master/docs) folder
|
* [ACS Packaging docs](https://github.com/Alfresco/acs-packaging/tree/master/docs) folder
|
||||||
@@ -49,7 +49,7 @@ The artifacts can be obtained by:
|
|||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>version</version>
|
<version>version</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>tests</classifier>
|
<classifier>tests</classifier>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
|
@@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.aio;
|
|
||||||
|
|
||||||
import org.alfresco.transform.config.TransformConfig;
|
|
||||||
import org.alfresco.transform.common.TransformException;
|
|
||||||
import org.alfresco.transform.base.executors.Transformer;
|
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
|
||||||
import org.alfresco.transformer.probes.ProbeTestTransform;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML;
|
|
||||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
|
|
||||||
import static org.alfresco.transform.config.CoreVersionDecorator.setOrClearCoreVersion;
|
|
||||||
import static org.alfresco.transform.common.RequestParamMap.CONFIG_VERSION_DEFAULT;
|
|
||||||
import static org.alfresco.transform.base.util.RequestParamMap.CONFIG_VERSION;
|
|
||||||
import static org.alfresco.transform.base.util.RequestParamMap.SOURCE_ENCODING;
|
|
||||||
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
|
|
||||||
import static org.springframework.http.HttpStatus.OK;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
public class AIOController extends AbstractTransformerController
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AIOController.class);
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AIOTransformRegistry transformRegistry;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTransformerName()
|
|
||||||
{
|
|
||||||
return "All in One Transformer";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String version()
|
|
||||||
{
|
|
||||||
return getTransformerName() + " available";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProbeTestTransform getProbeTestTransform()
|
|
||||||
{
|
|
||||||
return new ProbeTestTransform(this, "quick.html", "quick.txt",
|
|
||||||
119, 30, 150, 1024,
|
|
||||||
60 * 2 + 1, 60 * 2)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void executeTransformCommand(File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
Map<String, String> parameters = new HashMap<>();
|
|
||||||
parameters.put(SOURCE_ENCODING, "UTF-8");
|
|
||||||
transformImpl("html", MIMETYPE_HTML, MIMETYPE_TEXT_PLAIN, parameters, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResponseEntity<TransformConfig> info(
|
|
||||||
@RequestParam(value = CONFIG_VERSION, defaultValue = CONFIG_VERSION_DEFAULT) int configVersion)
|
|
||||||
{
|
|
||||||
logger.info("GET Transform Config version: " + configVersion);
|
|
||||||
TransformConfig transformConfig = transformRegistry.getTransformConfig();
|
|
||||||
transformConfig = setOrClearCoreVersion(transformConfig, configVersion);
|
|
||||||
return new ResponseEntity<>(transformConfig, OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
logger.debug("Processing transform with: transformName; '{}', sourceFile '{}', targetFile '{}', transformOptions" +
|
|
||||||
" {}", transformName, sourceFile, targetFile, transformOptions);
|
|
||||||
|
|
||||||
Transformer transformer = transformRegistry.getByTransformName(transformName);
|
|
||||||
if (transformer == null)
|
|
||||||
{
|
|
||||||
throw new TransformException(INTERNAL_SERVER_ERROR.value(), "No transformer mapping for - transform:"
|
|
||||||
+ transformName + " sourceMimetype:" + sourceMimetype + " targetMimetype:" + targetMimetype);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
logger.debug("Performing transform with name '{}' using transformer with id '{}'.", transformName, transformer.getTransformerId());
|
|
||||||
}
|
|
||||||
|
|
||||||
transformer.transformExtractOrEmbed(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.aio;
|
|
||||||
|
|
||||||
import org.alfresco.transform.registry.TransformServiceRegistry;
|
|
||||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickCommandExecutor;
|
|
||||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
|
||||||
import org.alfresco.transform.pdfRenderer.transformers.PdfRendererCommandExecutor;
|
|
||||||
import org.alfresco.transform.base.executors.Transformer;
|
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
|
||||||
import org.alfresco.transform.misc.transformers.SelectingTransformer;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Primary;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
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;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.exe}")
|
|
||||||
private String imageMagickExePath;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.dyn}")
|
|
||||||
private String imageMagickDynPath;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.root}")
|
|
||||||
private String imageMagickRootPath;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.coders}")
|
|
||||||
private String imageMagickCodersPath;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.config}")
|
|
||||||
private String imageMagickConfigPath;
|
|
||||||
|
|
||||||
@Value("${transform.core.tika.pdfBox.notExtractBookmarksTextDefault:false}")
|
|
||||||
private boolean notExtractBookmarksTextDefault;
|
|
||||||
|
|
||||||
@Value("${transform.core.version}")
|
|
||||||
private String coreVersion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return Override the TransformRegistryImpl used in {@link AbstractTransformerController}
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@Primary
|
|
||||||
public TransformServiceRegistry aioTransformRegistry() throws Exception
|
|
||||||
{
|
|
||||||
AIOTransformRegistry aioTransformRegistry = new AIOTransformRegistry();
|
|
||||||
aioTransformRegistry.setCoreVersion(coreVersion);
|
|
||||||
|
|
||||||
// T-Engines are sorted by name so they are combined in the same order as in the T-Router
|
|
||||||
// and Content Repository with individual T-Engines. See TransformersConfigRegistry#retrieveRemoteConfig and
|
|
||||||
// LocalTransformServiceRegistry#getTEngineUrlsSortedByName.
|
|
||||||
for (Transformer tEngine : getTEnginesSortedByName())
|
|
||||||
{
|
|
||||||
aioTransformRegistry.registerTransformer(tEngine); // now a poor name - should be combineTransformers
|
|
||||||
}
|
|
||||||
aioTransformRegistry.registerCombinedTransformers();
|
|
||||||
return aioTransformRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Transformer> getTEnginesSortedByName()
|
|
||||||
{
|
|
||||||
return Stream.of(new SelectingTransformer(),
|
|
||||||
// new TikaJavaExecutor(notExtractBookmarksTextDefault),
|
|
||||||
new ImageMagickCommandExecutor(imageMagickExePath, imageMagickDynPath, imageMagickRootPath, imageMagickCodersPath, imageMagickConfigPath),
|
|
||||||
new LibreOfficeJavaExecutor(libreofficePath, libreofficeMaxTasksPerProcess, libreofficeTimeout, libreofficePortNumbers, libreofficeTemplateProfileDir, libreofficeIsEnabled),
|
|
||||||
new PdfRendererCommandExecutor(pdfRendererPath))
|
|
||||||
.sorted(Comparator.comparing(Transformer::getTransformerId))
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -1,183 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.aio;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.alfresco.transform.config.TransformConfig;
|
|
||||||
import org.alfresco.transform.registry.AbstractTransformRegistry;
|
|
||||||
import org.alfresco.transform.registry.CombinedTransformConfig;
|
|
||||||
import org.alfresco.transform.registry.TransformCache;
|
|
||||||
import org.alfresco.transform.base.executors.Transformer;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
|
||||||
import static org.alfresco.transform.config.CoreVersionDecorator.setCoreVersionOnSingleStepTransformers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AIOTransformRegistry manages all of the sub transformers registered to it and provides aggregated TransformConfig.
|
|
||||||
*/
|
|
||||||
public class AIOTransformRegistry extends AbstractTransformRegistry
|
|
||||||
{
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(AIOTransformRegistry.class);
|
|
||||||
|
|
||||||
private static final String ENGINE_CONFIG_LOCATION_POSTFIX = "_engine_config.json";
|
|
||||||
|
|
||||||
private String coreVersion;
|
|
||||||
|
|
||||||
private CombinedTransformConfig combinedTransformConfig = new CombinedTransformConfig();
|
|
||||||
|
|
||||||
// Holds the structures used by AbstractTransformRegistry to look up what is supported.
|
|
||||||
// Unlike other sub classes this class does not extend Data or replace it at run time.
|
|
||||||
private TransformCache data = new TransformCache();
|
|
||||||
|
|
||||||
private ObjectMapper jsonObjectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
// Represents the mapping between a transform and a transformer, multiple mappings can point to the same transformer.
|
|
||||||
private Map<String, Transformer> transformerEngineMapping = new HashMap();
|
|
||||||
|
|
||||||
public void setCoreVersion(String coreVersion)
|
|
||||||
{
|
|
||||||
this.coreVersion = coreVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a transformer's (T-Engine) config to the configuration and creates a map of transforms to the T-Engine.
|
|
||||||
* The name of this method is now misleading as the registry of transforms takes place in
|
|
||||||
* {@link #registerCombinedTransformers()} .
|
|
||||||
* @param tEngine The transformer implementation, this could be a single transformer
|
|
||||||
* or a transformer managing multiple sub transformers. The transformer's configuration file will
|
|
||||||
* be read based on the {@link Transformer#getTransformerId()} value.
|
|
||||||
*/
|
|
||||||
public void registerTransformer(final Transformer tEngine) throws Exception
|
|
||||||
{
|
|
||||||
// Load config for the transformer
|
|
||||||
String location = getTransformConfigLocation(tEngine);
|
|
||||||
TransformConfig transformConfig = loadTransformConfig(location);
|
|
||||||
setCoreVersionOnSingleStepTransformers(transformConfig, coreVersion);
|
|
||||||
String transformerId = tEngine.getTransformerId();
|
|
||||||
combinedTransformConfig.addTransformConfig(transformConfig, location, transformerId, this);
|
|
||||||
|
|
||||||
// Map all of the transforms defined in the config to this Transformer implementation
|
|
||||||
for (org.alfresco.transform.config.Transformer transformerConfig : transformConfig.getTransformers())
|
|
||||||
{
|
|
||||||
String transformerName = transformerConfig.getTransformerName();
|
|
||||||
// A later tEngine 'might' override one that has already been defined. That is fine.
|
|
||||||
Transformer originalTEngine = transformerEngineMapping.get(transformerName);
|
|
||||||
if (originalTEngine != null)
|
|
||||||
{
|
|
||||||
log.debug("Overriding transform with name: '{}' originally defined in '{}'.", transformerName, originalTEngine.getTransformerId());
|
|
||||||
}
|
|
||||||
transformerEngineMapping.put(transformerName, tEngine);
|
|
||||||
log.debug("Registered transform with name: '{}' defined in '{}'.", transformerName, transformerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerCombinedTransformers()
|
|
||||||
{
|
|
||||||
combinedTransformConfig.combineTransformerConfig(this);
|
|
||||||
combinedTransformConfig.registerCombinedTransformers(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param transformName The transform name as it appears in TransformConfig.
|
|
||||||
* @return The transformer implementation mapped to the transform name.
|
|
||||||
*/
|
|
||||||
public Transformer getByTransformName(final String transformName)
|
|
||||||
{
|
|
||||||
return getTransformerEngineMapping().get(transformName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return The aggregated config of all the registered transformers
|
|
||||||
*/
|
|
||||||
public TransformConfig getTransformConfig()
|
|
||||||
{
|
|
||||||
return combinedTransformConfig.buildTransformConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getTransformConfigLocation(final Transformer transformer)
|
|
||||||
{
|
|
||||||
String location = transformer.getTransformerId() + ENGINE_CONFIG_LOCATION_POSTFIX;
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected TransformConfig loadTransformConfig(final String name) throws Exception
|
|
||||||
{
|
|
||||||
if (getClass().getClassLoader().getResource(name) == null)
|
|
||||||
{
|
|
||||||
throw new Exception("Configuration '" + name + "' does not exist on the classpath.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try (InputStream is = getClass().getClassLoader().getResourceAsStream(name);
|
|
||||||
Reader reader = new InputStreamReader(is, UTF_8))
|
|
||||||
{
|
|
||||||
return jsonObjectMapper.readValue(reader, TransformConfig.class);
|
|
||||||
}
|
|
||||||
catch (IOException e)
|
|
||||||
{
|
|
||||||
throw new Exception("Could not read '" + name + "' from the classpath.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Transformer> getTransformerEngineMapping()
|
|
||||||
{
|
|
||||||
return transformerEngineMapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTransformerEngineMapping(Map<String, Transformer> transformerEngineMapping)
|
|
||||||
{
|
|
||||||
this.transformerEngineMapping = transformerEngineMapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TransformCache getData()
|
|
||||||
{
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logError(String msg)
|
|
||||||
{
|
|
||||||
log.error(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void logWarn(String msg)
|
|
||||||
{
|
|
||||||
log.warn(msg);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.TransformEngine;
|
||||||
|
import org.alfresco.transform.base.TransformRegistryImpl;
|
||||||
|
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
||||||
|
import org.alfresco.transform.config.TransformConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.alfresco.transform.base.logging.StandardMessages.COMMUNITY_LICENCE;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AIOTransformEngine implements TransformEngine
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private TransformRegistryImpl transformRegistry;
|
||||||
|
@Autowired(required = false)
|
||||||
|
private List<TransformEngine> transformEngines;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTransformEngineName()
|
||||||
|
{
|
||||||
|
return "0060-AllInOne";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStartupMessage()
|
||||||
|
{
|
||||||
|
String message = "";
|
||||||
|
if (transformEngines != null)
|
||||||
|
{
|
||||||
|
// Combines the messages of the component TransformEngines. Removes duplicate community license messages.
|
||||||
|
message = transformEngines.stream()
|
||||||
|
.filter(transformEngine -> transformEngine != this)
|
||||||
|
.map(transformEngine -> transformEngine.getStartupMessage())
|
||||||
|
.collect( Collectors.joining("\\n"));
|
||||||
|
message.replace(COMMUNITY_LICENCE + "\\n", "");
|
||||||
|
}
|
||||||
|
return COMMUNITY_LICENCE + "\\n" + message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformConfig getTransformConfig()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbeTestTransform getLivenessAndReadinessProbeTestTransform()
|
||||||
|
{
|
||||||
|
return new ProbeTestTransform("quick.pdf", "quick.txt",
|
||||||
|
MIMETYPE_PDF, MIMETYPE_TEXT_PLAIN, Collections.emptyMap(),
|
||||||
|
60, 16, 400, 10240, 60 * 30 + 1, 60 * 15 + 20);
|
||||||
|
}
|
||||||
|
}
|
@@ -24,9 +24,9 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transformer.AbstractHttpRequestTest;
|
import org.alfresco.transform.base.AbstractHttpRequestTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
@@ -24,14 +24,14 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.transform.libreoffice.LibreOfficeControllerTest;
|
import org.alfresco.transform.libreoffice.LibreOfficeControllerTest;
|
||||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
|
||||||
import org.alfresco.transform.base.executors.Transformer;
|
import org.alfresco.transform.base.executors.Transformer;
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
import org.alfresco.transformer.AbstractTransformerController;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@@ -62,7 +62,7 @@ public class AIOControllerLibreOfficeTest extends LibreOfficeControllerTest
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
// Used by the super class to mock the javaExecutor, a different implementation is required here
|
// Used by the super class to mock the javaExecutor, a different implementation is required here
|
||||||
protected void setJavaExecutor(AbstractTransformerController controller, LibreOfficeJavaExecutor javaExecutor)
|
protected void setJavaExecutor(AbstractTransformerController controller, LibreOfficeTransformer javaExecutor)
|
||||||
{
|
{
|
||||||
//Need to wire in the mocked javaExecutor into the controller...
|
//Need to wire in the mocked javaExecutor into the controller...
|
||||||
Map<String,Transformer> transformers = transformRegistry.getTransformerEngineMapping();
|
Map<String,Transformer> transformers = transformRegistry.getTransformerEngineMapping();
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
@@ -24,16 +24,13 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.transform.aio.AIOController;
|
|
||||||
import org.alfresco.transform.aio.AIOCustomConfig;
|
|
||||||
import org.alfresco.transform.aio.AIOTransformRegistry;
|
|
||||||
import org.alfresco.transform.pdfRenderer.AlfrescoPdfRendererControllerTest;
|
import org.alfresco.transform.pdfRenderer.AlfrescoPdfRendererControllerTest;
|
||||||
import org.alfresco.transform.base.executors.Transformer;
|
import org.alfresco.transform.base.executors.Transformer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.aio.AIOController;
|
import org.alfresco.transform.aio.AIOController;
|
||||||
import org.alfresco.transform.aio.AIOCustomConfig;
|
import org.alfresco.transform.aio.AIOCustomConfig;
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.imagemagick.ImageMagickTransformationIT;
|
import org.alfresco.transform.imagemagick.ImageMagickTransformationIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.libreoffice.LibreOfficeTransformationIT;
|
import org.alfresco.transform.libreoffice.LibreOfficeTransformationIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.misc.MiscMetadataExtractsIT;
|
import org.alfresco.transform.misc.MiscMetadataExtractsIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.misc.MiscTransformsIT;
|
import org.alfresco.transform.misc.MiscTransformsIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.pdfRenderer.AlfrescoPdfRendererTransformationIT;
|
import org.alfresco.transform.pdfRenderer.AlfrescoPdfRendererTransformationIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML;
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_HTML;
|
||||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_TEXT_PLAIN;
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.tika.TikaMetadataExtractsIT;
|
import org.alfresco.transform.tika.TikaMetadataExtractsIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import org.alfresco.transform.tika.TikaTransformationIT;
|
import org.alfresco.transform.tika.TikaTransformationIT;
|
||||||
|
|
@@ -24,7 +24,7 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.transform.aio;
|
package org.alfresco.transform.coreaio;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.alfresco.transform.aio.AIOTransformRegistry;
|
import org.alfresco.transform.aio.AIOTransformRegistry;
|
||||||
@@ -49,7 +49,7 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.alfresco.transform.base.util.RequestParamMap.PAGE_LIMIT;
|
import static org.alfresco.transform.common.RequestParamMap.PAGE_LIMIT;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
@@ -20,12 +20,12 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>tests</classifier>
|
<classifier>tests</classifier>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
|
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.imagemagick;
|
|
||||||
|
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
|
||||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickCommandExecutor;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.alfresco.transformer.logging.StandardMessages.LICENCE;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
|
||||||
public class Application
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
|
||||||
|
|
||||||
@Value("${container.name}")
|
|
||||||
private String containerName;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags()
|
|
||||||
{
|
|
||||||
return registry -> registry.config().commonTags("containerName", containerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
SpringApplication.run(Application.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
|
||||||
public void startup()
|
|
||||||
{
|
|
||||||
logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------");
|
|
||||||
Arrays.stream(LICENCE.split("\\n")).forEach(logger::info);
|
|
||||||
logger.info(ImageMagickCommandExecutor.LICENCE);
|
|
||||||
logger.info("--------------------------------------------------------------------------------------------------------------------------------------------------------------");
|
|
||||||
|
|
||||||
logger.info("Starting application components... Done");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.imagemagick;
|
|
||||||
|
|
||||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickCommandExecutor;
|
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
|
||||||
import org.alfresco.transformer.probes.ProbeTestTransform;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for the Docker based ImageMagick transformer.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Status Codes:
|
|
||||||
*
|
|
||||||
* 200 Success
|
|
||||||
* 400 Bad Request: Invalid cropGravity value (North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest, Center)
|
|
||||||
* 400 Bad Request: Request parameter <name> is missing (missing mandatory parameter)
|
|
||||||
* 400 Bad Request: Request parameter <name> is of the wrong type
|
|
||||||
* 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)
|
|
||||||
* 400 Bad Request: The source filename was not supplied
|
|
||||||
* 500 Internal Server Error: (no message with low level IO problems)
|
|
||||||
* 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)
|
|
||||||
* 500 Internal Server Error: Transformer version check exit code was not 0
|
|
||||||
* 500 Internal Server Error: Transformer version check failed to create any output
|
|
||||||
* 500 Internal Server Error: Could not read the target file
|
|
||||||
* 500 Internal Server Error: The target filename was malformed (should not happen because of other checks)
|
|
||||||
* 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
|
|
||||||
* 500 Internal Server Error: Filename encoding error
|
|
||||||
* 507 Insufficient Storage: Failed to store the source file
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
public class ImageMagickController extends AbstractTransformerController
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ImageMagickController.class);
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.exe}")
|
|
||||||
private String EXE;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.dyn}")
|
|
||||||
private String DYN;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.root}")
|
|
||||||
private String ROOT;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.coders}")
|
|
||||||
private String CODERS;
|
|
||||||
|
|
||||||
@Value("${transform.core.imagemagick.config}")
|
|
||||||
private String CONFIG;
|
|
||||||
|
|
||||||
ImageMagickCommandExecutor commandExecutor;
|
|
||||||
|
|
||||||
@PostConstruct
|
|
||||||
private void init()
|
|
||||||
{
|
|
||||||
commandExecutor = new ImageMagickCommandExecutor(EXE, DYN, ROOT, CODERS, CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTransformerName()
|
|
||||||
{
|
|
||||||
return "ImageMagick";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String version()
|
|
||||||
{
|
|
||||||
return commandExecutor.version();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProbeTestTransform getProbeTestTransform()
|
|
||||||
{
|
|
||||||
// See the Javadoc on this method and Probes.md for the choice of these values.
|
|
||||||
return new ProbeTestTransform(this, "quick.jpg", "quick.png",
|
|
||||||
35593, 1024, 150, 1024, 60 * 15 + 1, 60 * 15)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void executeTransformCommand(File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
transformImpl(null, null, null, Collections.emptyMap(), sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransformerName(final File sourceFile, final String sourceMimetype,
|
|
||||||
final String targetMimetype, final Map<String, String> transformOptions)
|
|
||||||
{
|
|
||||||
return null; // does not matter what value is returned, as it is not used because there is only one.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
commandExecutor.transformExtractOrEmbed(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@@ -32,8 +32,8 @@ import org.alfresco.transform.common.TransformException;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringJoiner;
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
import static org.alfresco.transformer.util.Util.stringToBoolean;
|
import static org.alfresco.transform.base.util.Util.stringToBoolean;
|
||||||
import static org.alfresco.transformer.util.Util.stringToInteger;
|
import static org.alfresco.transform.base.util.Util.stringToInteger;
|
||||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.imagemagick;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.TransformEngine;
|
||||||
|
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
||||||
|
import org.alfresco.transform.common.TransformConfigResourceReader;
|
||||||
|
import org.alfresco.transform.config.TransformConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.alfresco.transform.base.logging.StandardMessages.COMMUNITY_LICENCE;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_JPEG;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_IMAGE_PNG;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ImageMagickTransformEngine implements TransformEngine
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private TransformConfigResourceReader transformConfigResourceReader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTransformEngineName()
|
||||||
|
{
|
||||||
|
return "0030-ImageMagick";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStartupMessage()
|
||||||
|
{
|
||||||
|
return COMMUNITY_LICENCE +
|
||||||
|
"This transformer uses ImageMagick from ImageMagick Studio LLC. " +
|
||||||
|
"See the license at http://www.imagemagick.org/script/license.php or in /ImageMagick-license.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformConfig getTransformConfig()
|
||||||
|
{
|
||||||
|
return transformConfigResourceReader.read("classpath:imagemagick_engine_config.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbeTestTransform getLivenessAndReadinessProbeTestTransform()
|
||||||
|
{
|
||||||
|
return new ProbeTestTransform("quick.jpg", "quick.png",
|
||||||
|
MIMETYPE_IMAGE_JPEG, MIMETYPE_IMAGE_PNG, Collections.emptyMap(),
|
||||||
|
35593, 1024, 150, 1024, 60 * 15 + 1, 60 * 15);
|
||||||
|
}
|
||||||
|
}
|
@@ -26,104 +26,106 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.transform.imagemagick.transformers;
|
package org.alfresco.transform.imagemagick.transformers;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
|
import org.alfresco.transform.base.executors.AbstractCommandExecutor;
|
||||||
|
import org.alfresco.transform.base.executors.RuntimeExec;
|
||||||
import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder;
|
import org.alfresco.transform.imagemagick.ImageMagickOptionsBuilder;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.alfresco.transformer.executors.AbstractCommandExecutor;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.alfresco.transformer.executors.RuntimeExec;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.ALLOW_ENLARGEMENT;
|
import static org.alfresco.transform.base.util.Util.stringToInteger;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.ALPHA_REMOVE;
|
import static org.alfresco.transform.base.util.Util.stringToLong;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.AUTO_ORIENT;
|
import static org.alfresco.transform.common.RequestParamMap.ALLOW_ENLARGEMENT;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.COMMAND_OPTIONS;
|
import static org.alfresco.transform.common.RequestParamMap.ALPHA_REMOVE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_GRAVITY;
|
import static org.alfresco.transform.common.RequestParamMap.AUTO_ORIENT;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_HEIGHT;
|
import static org.alfresco.transform.common.RequestParamMap.COMMAND_OPTIONS;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_PERCENTAGE;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_GRAVITY;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_WIDTH;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_HEIGHT;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_X_OFFSET;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_PERCENTAGE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_Y_OFFSET;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_WIDTH;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.END_PAGE;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_X_OFFSET;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.MAINTAIN_ASPECT_RATIO;
|
import static org.alfresco.transform.common.RequestParamMap.CROP_Y_OFFSET;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_HEIGHT;
|
import static org.alfresco.transform.common.RequestParamMap.END_PAGE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_PERCENTAGE;
|
import static org.alfresco.transform.common.RequestParamMap.MAINTAIN_ASPECT_RATIO;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_WIDTH;
|
import static org.alfresco.transform.common.RequestParamMap.RESIZE_HEIGHT;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.START_PAGE;
|
import static org.alfresco.transform.common.RequestParamMap.RESIZE_PERCENTAGE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.THUMBNAIL;
|
import static org.alfresco.transform.common.RequestParamMap.RESIZE_WIDTH;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.TIMEOUT;
|
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
||||||
import static org.alfresco.transformer.util.Util.stringToInteger;
|
import static org.alfresco.transform.common.RequestParamMap.THUMBNAIL;
|
||||||
import static org.alfresco.transformer.util.Util.stringToLong;
|
import static org.alfresco.transform.common.RequestParamMap.TIMEOUT;
|
||||||
|
|
||||||
/**
|
@Component
|
||||||
* CommandExecutor implementation for running ImageMagick transformations. It runs the
|
public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformer
|
||||||
* transformation logic as a separate Shell process.
|
|
||||||
*/
|
|
||||||
public class ImageMagickCommandExecutor extends AbstractCommandExecutor
|
|
||||||
{
|
{
|
||||||
private static final String ID = "imagemagick";
|
@Value("${transform.core.imagemagick.exe}")
|
||||||
|
private String exe;
|
||||||
|
@Value("${transform.core.imagemagick.dyn}")
|
||||||
|
private String dyn;
|
||||||
|
@Value("${transform.core.imagemagick.root}")
|
||||||
|
private String root;
|
||||||
|
|
||||||
private final String ROOT;
|
// Not currently used, but may be again in the future if we need an ImageMagick extension
|
||||||
private final String DYN;
|
@Value("${transform.core.imagemagick.coders}")
|
||||||
private final String EXE;
|
private String coders;
|
||||||
private final String CODERS;
|
@Value("${transform.core.imagemagick.config}")
|
||||||
private final String CONFIG;
|
private String config;
|
||||||
|
|
||||||
public ImageMagickCommandExecutor(String exe, String dyn, String root, String coders, String config)
|
@PostConstruct
|
||||||
|
private void createCommands()
|
||||||
{
|
{
|
||||||
if (exe == null || exe.isEmpty())
|
if (exe == null || exe.isEmpty())
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("ImageMagickCommandExecutor EXE variable cannot be null or empty");
|
throw new IllegalArgumentException("ImageMagickTransformer IMAGEMAGICK_EXE variable cannot be null or empty");
|
||||||
}
|
}
|
||||||
if (dyn == null || dyn.isEmpty())
|
if (dyn == null || dyn.isEmpty())
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("ImageMagickCommandExecutor DYN variable cannot be null or empty");
|
throw new IllegalArgumentException("ImageMagickTransformer IMAGEMAGICK_DYN variable cannot be null or empty");
|
||||||
}
|
}
|
||||||
if (root == null || root.isEmpty())
|
if (root == null || root.isEmpty())
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("ImageMagickCommandExecutor ROOT variable cannot be null or empty");
|
throw new IllegalArgumentException("ImageMagickTransformer IMAGEMAGICK_ROOT variable cannot be null or empty");
|
||||||
}
|
}
|
||||||
this.EXE = exe;
|
|
||||||
this.DYN = dyn;
|
|
||||||
this.ROOT = root;
|
|
||||||
this.CODERS = coders;
|
|
||||||
this.CONFIG = config;
|
|
||||||
|
|
||||||
super.transformCommand = createTransformCommand();
|
super.transformCommand = createTransformCommand();
|
||||||
super.checkCommand = createCheckCommand();
|
super.checkCommand = createCheckCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformerId()
|
public String getTransformerName()
|
||||||
{
|
{
|
||||||
return ID;
|
return "imagemagick";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String LICENCE = "This transformer uses ImageMagick from ImageMagick Studio LLC. See the license at http://www.imagemagick.org/script/license.php or in /ImageMagick-license.txt";
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RuntimeExec createTransformCommand()
|
protected RuntimeExec createTransformCommand()
|
||||||
{
|
{
|
||||||
RuntimeExec runtimeExec = new RuntimeExec();
|
RuntimeExec runtimeExec = new RuntimeExec();
|
||||||
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||||
commandsAndArguments.put(".*",
|
commandsAndArguments.put(".*",
|
||||||
new String[]{EXE, "${source}", "SPLIT:${options}", "-strip", "-quiet", "${target}"});
|
new String[]{exe, "${source}", "SPLIT:${options}", "-strip", "-quiet", "${target}"});
|
||||||
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||||
|
|
||||||
Map<String, String> processProperties = new HashMap<>();
|
Map<String, String> processProperties = new HashMap<>();
|
||||||
processProperties.put("MAGICK_HOME", ROOT);
|
processProperties.put("MAGICK_HOME", root);
|
||||||
processProperties.put("DYLD_FALLBACK_LIBRARY_PATH", DYN);
|
processProperties.put("DYLD_FALLBACK_LIBRARY_PATH", dyn);
|
||||||
processProperties.put("LD_LIBRARY_PATH", DYN);
|
processProperties.put("LD_LIBRARY_PATH", dyn);
|
||||||
|
|
||||||
//Optional properties (see also https://imagemagick.org/script/resources.php#environment)
|
//Optional properties (see also https://imagemagick.org/script/resources.php#environment)
|
||||||
if (CODERS != null && !CODERS.isBlank())
|
if (coders != null && !coders.isBlank())
|
||||||
{
|
{
|
||||||
processProperties.put("MAGICK_CODER_MODULE_PATH", CODERS);
|
processProperties.put("MAGICK_CODER_MODULE_PATH", coders);
|
||||||
}
|
}
|
||||||
if (CONFIG != null && !CONFIG.isBlank())
|
if (config != null && !config.isBlank())
|
||||||
{
|
{
|
||||||
processProperties.put("MAGICK_CONFIGURE_PATH", CONFIG);
|
processProperties.put("MAGICK_CONFIGURE_PATH", config);
|
||||||
}
|
}
|
||||||
runtimeExec.setProcessProperties(processProperties);
|
runtimeExec.setProcessProperties(processProperties);
|
||||||
|
|
||||||
@@ -142,12 +144,18 @@ public class ImageMagickCommandExecutor extends AbstractCommandExecutor
|
|||||||
{
|
{
|
||||||
RuntimeExec runtimeExec = new RuntimeExec();
|
RuntimeExec runtimeExec = new RuntimeExec();
|
||||||
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||||
commandsAndArguments.put(".*", new String[]{EXE, "-version"});
|
commandsAndArguments.put(".*", new String[]{exe, "-version"});
|
||||||
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||||
return runtimeExec;
|
return runtimeExec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
||||||
|
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
||||||
|
Map<String, String> transformOptions) throws Exception
|
||||||
|
{
|
||||||
|
throw new TransformException(500, "TODO ImageMagick transform");
|
||||||
|
}
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
Map<String, String> transformOptions,
|
Map<String, String> transformOptions,
|
||||||
File sourceFile, File targetFile) throws TransformException
|
File sourceFile, File targetFile) throws TransformException
|
@@ -3,8 +3,6 @@ queue:
|
|||||||
transform:
|
transform:
|
||||||
core:
|
core:
|
||||||
version: @project.version@
|
version: @project.version@
|
||||||
config:
|
|
||||||
location: classpath:imagemagick_engine_config.json
|
|
||||||
imagemagick:
|
imagemagick:
|
||||||
root: ${IMAGEMAGICK_ROOT:/usr/lib64/ImageMagick-7.0.10}
|
root: ${IMAGEMAGICK_ROOT:/usr/lib64/ImageMagick-7.0.10}
|
||||||
dyn: ${IMAGEMAGICK_DYN:/usr/lib64/ImageMagick-7.0.10/lib}
|
dyn: ${IMAGEMAGICK_DYN:/usr/lib64/ImageMagick-7.0.10/lib}
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -58,7 +58,7 @@ import javax.annotation.PostConstruct;
|
|||||||
|
|
||||||
import org.alfresco.transform.client.model.TransformReply;
|
import org.alfresco.transform.client.model.TransformReply;
|
||||||
import org.alfresco.transform.client.model.TransformRequest;
|
import org.alfresco.transform.client.model.TransformRequest;
|
||||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickCommandExecutor;
|
import org.alfresco.transform.imagemagick.transformers.ImageMagickTransformer;
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
import org.alfresco.transformer.AbstractTransformerController;
|
||||||
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
||||||
import org.alfresco.transformer.executors.RuntimeExec;
|
import org.alfresco.transformer.executors.RuntimeExec;
|
||||||
@@ -119,12 +119,12 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest
|
|||||||
@Value("${transform.core.imagemagick.config}")
|
@Value("${transform.core.imagemagick.config}")
|
||||||
protected String CONFIG;
|
protected String CONFIG;
|
||||||
|
|
||||||
ImageMagickCommandExecutor commandExecutor;
|
ImageMagickTransformer commandExecutor;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
commandExecutor = new ImageMagickCommandExecutor(EXE, DYN, ROOT, CODERS, CONFIG);
|
commandExecutor = new ImageMagickTransformer(EXE, DYN, ROOT, CODERS, CONFIG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
Before Width: | Height: | Size: 297 KiB After Width: | Height: | Size: 297 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
@@ -20,12 +20,12 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<classifier>tests</classifier>
|
<classifier>tests</classifier>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
|
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.libreoffice;
|
|
||||||
|
|
||||||
import io.micrometer.core.instrument.MeterRegistry;
|
|
||||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.event.EventListener;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import static org.alfresco.transformer.logging.StandardMessages.LICENCE;
|
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
|
||||||
public class Application
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
|
||||||
|
|
||||||
@Value("${container.name}")
|
|
||||||
private String containerName;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
MeterRegistryCustomizer<MeterRegistry> metricsCommonTags()
|
|
||||||
{
|
|
||||||
return registry -> registry.config().commonTags("containerName", containerName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// To run the LibreOffice T-Engine from the command line on a Mac, you generally need to
|
|
||||||
// install LibreOffice and add: -Dtransform.core.libreoffice.path=/Applications/LibreOffice.app/Contents/
|
|
||||||
// to the start up command.
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
SpringApplication.run(Application.class, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventListener(ApplicationReadyEvent.class)
|
|
||||||
public void startup()
|
|
||||||
{
|
|
||||||
logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------");
|
|
||||||
Arrays.stream(LICENCE.split("\\n")).forEach(logger::info);
|
|
||||||
logger.info(LibreOfficeJavaExecutor.LICENCE);
|
|
||||||
logger.info("-------------------------------------------------------------------------------------------------------------------------------------------------------");
|
|
||||||
|
|
||||||
logger.info("Starting application components... Done");
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,134 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Transform Core
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* -
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
* -
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
* -
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
* -
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.transform.libreoffice;
|
|
||||||
|
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
|
||||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
|
||||||
import org.alfresco.transformer.probes.ProbeTestTransform;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for the Docker based LibreOffice transformer.
|
|
||||||
*
|
|
||||||
* Status Codes:
|
|
||||||
*
|
|
||||||
* 200 Success
|
|
||||||
* 400 Bad Request: Request parameter <name> is missing (missing mandatory parameter)
|
|
||||||
* 400 Bad Request: Request parameter <name> is of the wrong type
|
|
||||||
* 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)
|
|
||||||
* 400 Bad Request: The source filename was not supplied
|
|
||||||
* 500 Internal Server Error: (no message with low level IO problems)
|
|
||||||
* 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)
|
|
||||||
* 500 Internal Server Error: Transformer version check exit code was not 0
|
|
||||||
* 500 Internal Server Error: Transformer version check failed to create any output
|
|
||||||
* 500 Internal Server Error: Could not read the target file
|
|
||||||
* 500 Internal Server Error: The target filename was malformed (should not happen because of other checks)
|
|
||||||
* 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
|
|
||||||
* 500 Internal Server Error: Filename encoding error
|
|
||||||
* 507 Insufficient Storage: Failed to store the source file
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
public class LibreOfficeController extends AbstractTransformerController
|
|
||||||
{
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeController.class);
|
|
||||||
|
|
||||||
@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, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, isEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getTransformerName()
|
|
||||||
{
|
|
||||||
return "LibreOffice";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String version()
|
|
||||||
{
|
|
||||||
return "LibreOffice available";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ProbeTestTransform getProbeTestTransform()
|
|
||||||
{
|
|
||||||
// See the Javadoc on this method and Probes.md for the choice of these values.
|
|
||||||
return new ProbeTestTransform(this, "quick.doc", "quick.pdf",
|
|
||||||
11817, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20)
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void executeTransformCommand(File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
transformImpl(null, null, null, Collections.emptyMap(), sourceFile, targetFile);
|
|
||||||
javaExecutor.call(sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTransformerName(final File sourceFile, final String sourceMimetype,
|
|
||||||
final String targetMimetype, final Map<String, String> transformOptions)
|
|
||||||
{
|
|
||||||
return null; // does not matter what value is returned, as it is not used because there is only one.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
|
||||||
{
|
|
||||||
javaExecutor.transformExtractOrEmbed(transformName, sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,7 +14,7 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-transformer-base</artifactId>
|
<artifactId>alfresco-t-engine-base</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transform.libreoffice;
|
||||||
|
|
||||||
|
import org.alfresco.transform.base.TransformEngine;
|
||||||
|
import org.alfresco.transform.base.probes.ProbeTestTransform;
|
||||||
|
import org.alfresco.transform.common.TransformConfigResourceReader;
|
||||||
|
import org.alfresco.transform.config.TransformConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.alfresco.transform.base.logging.StandardMessages.COMMUNITY_LICENCE;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
|
||||||
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_WORD;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class LibreOfficeTransformEngine implements TransformEngine
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
private TransformConfigResourceReader transformConfigResourceReader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTransformEngineName()
|
||||||
|
{
|
||||||
|
return "0020-LibreOffice";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStartupMessage()
|
||||||
|
{
|
||||||
|
return COMMUNITY_LICENCE +
|
||||||
|
"This transformer uses LibreOffice from The Document Foundation. " +
|
||||||
|
"See the license at https://www.libreoffice.org/download/license/ or in /libreoffice.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TransformConfig getTransformConfig()
|
||||||
|
{
|
||||||
|
|
||||||
|
return transformConfigResourceReader.read("classpath:libreoffice_engine_config.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbeTestTransform getLivenessAndReadinessProbeTestTransform()
|
||||||
|
{
|
||||||
|
return new ProbeTestTransform("quick.doc", "quick.pdf",
|
||||||
|
MIMETYPE_WORD, MIMETYPE_PDF, Collections.emptyMap(),
|
||||||
|
11817, 1024, 150, 10240, 60 * 30 + 1, 60 * 15 + 20);
|
||||||
|
}
|
||||||
|
}
|
@@ -28,8 +28,8 @@ package org.alfresco.transform.libreoffice.transformers;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.sun.star.task.ErrorCodeIOException;
|
import com.sun.star.task.ErrorCodeIOException;
|
||||||
|
import org.alfresco.transform.base.CustomTransformer;
|
||||||
import org.alfresco.transform.common.TransformException;
|
import org.alfresco.transform.common.TransformException;
|
||||||
import org.alfresco.transformer.executors.JavaExecutor;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
@@ -39,9 +39,14 @@ import org.artofsolving.jodconverter.office.OfficeException;
|
|||||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -52,105 +57,92 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
|
|||||||
* JavaExecutor implementation for running LibreOffice transformations. It loads the
|
* JavaExecutor implementation for running LibreOffice transformations. It loads the
|
||||||
* transformation logic in the same JVM (check the {@link JodConverter} implementation).
|
* transformation logic in the same JVM (check the {@link JodConverter} implementation).
|
||||||
*/
|
*/
|
||||||
public class LibreOfficeJavaExecutor implements JavaExecutor
|
@Component
|
||||||
|
public class LibreOfficeTransformer implements CustomTransformer
|
||||||
{
|
{
|
||||||
private static String ID = "libreoffice";
|
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformer.class);
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeJavaExecutor.class);
|
|
||||||
|
|
||||||
private static final int JODCONVERTER_TRANSFORMATION_ERROR_CODE = 3088;
|
private static final int JODCONVERTER_TRANSFORMATION_ERROR_CODE = 3088;
|
||||||
|
|
||||||
private static String LIBREOFFICE_HOME;
|
@Value("${transform.core.libreoffice.path}")
|
||||||
|
private String path;
|
||||||
|
@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;
|
||||||
|
|
||||||
private static String LIBREOFFICE_MAX_TASKS_PER_PROCESS;
|
private JodConverter jodconverter;
|
||||||
|
|
||||||
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();
|
private final ObjectMapper jsonObjectMapper = new ObjectMapper();
|
||||||
|
|
||||||
public LibreOfficeJavaExecutor(String path, String maxTasksPerProcess, String timeout, String portNumbers, String templateProfileDir, String isEnabled)
|
@PostConstruct
|
||||||
|
private void createJodConverter()
|
||||||
{
|
{
|
||||||
if (path == null || path.isEmpty())
|
if (path == null || path.isEmpty())
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor OFFICE_HOME cannot be null or empty");
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_HOME cannot be null or empty");
|
||||||
}
|
}
|
||||||
LIBREOFFICE_HOME = path;
|
if (maxTasksPerProcess == null || maxTasksPerProcess.isEmpty() || !StringUtils.isNumeric(maxTasksPerProcess))
|
||||||
|
|
||||||
if(timeout == null || timeout.isEmpty() || !StringUtils.isNumeric(timeout))
|
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor TIMEOUT must have a numeric value");
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_MAX_TASKS_PER_PROCESS must have a numeric value");
|
||||||
}
|
}
|
||||||
LIBREOFFICE_TIMEOUT = timeout;
|
if (timeout == null || timeout.isEmpty() || !StringUtils.isNumeric(timeout))
|
||||||
|
|
||||||
if(maxTasksPerProcess == null || maxTasksPerProcess.isEmpty() || !StringUtils.isNumeric(maxTasksPerProcess))
|
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor MAX_TASKS_PER_PROCESS must have a numeric value");
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_TIMEOUT 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)
|
// value parsed and validated in JodConverterSharedInstance#parsePortNumbers(String s, String sys)
|
||||||
LIBREOFFICE_PORT_NUMBERS = portNumbers;
|
if (portNumbers == null || portNumbers.isEmpty())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_PORT_NUMBERS variable cannot be null or empty");
|
||||||
|
}
|
||||||
if (templateProfileDir == null)
|
if (templateProfileDir == null)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor TEMPLATE_PROFILE_DIR variable cannot be null");
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_TEMPLATE_PROFILE_DIR variable cannot be null");
|
||||||
}
|
}
|
||||||
LIBREOFFICE_TEMPLATE_PROFILE_DIR = templateProfileDir;
|
if (isEnabled == null || isEnabled.isEmpty() || !(isEnabled.equalsIgnoreCase("true")|| isEnabled.equalsIgnoreCase("false")))
|
||||||
|
|
||||||
if(isEnabled == null || isEnabled.isEmpty() || !(isEnabled.equalsIgnoreCase("true")|| isEnabled.equalsIgnoreCase("false")))
|
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor IS_ENABLED variable must be set to true/false");
|
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_IS_ENABLED variable must be set to true/false");
|
||||||
}
|
}
|
||||||
LIBREOFFICE_IS_ENABLED = isEnabled;
|
|
||||||
|
|
||||||
jodconverter = createJodConverter();
|
JodConverterSharedInstance sharedInstance = new JodConverterSharedInstance();
|
||||||
}
|
jodconverter = sharedInstance;
|
||||||
|
sharedInstance.setOfficeHome(path);
|
||||||
private static JodConverter createJodConverter()
|
sharedInstance.setMaxTasksPerProcess(maxTasksPerProcess);
|
||||||
{
|
sharedInstance.setTaskExecutionTimeout(timeout);
|
||||||
final JodConverterSharedInstance jodconverter = new JodConverterSharedInstance();
|
sharedInstance.setTaskQueueTimeout(timeout);
|
||||||
|
sharedInstance.setConnectTimeout(timeout);
|
||||||
jodconverter.setOfficeHome(LIBREOFFICE_HOME); // jodconverter.officeHome
|
sharedInstance.setPortNumbers(portNumbers);
|
||||||
jodconverter.setMaxTasksPerProcess(LIBREOFFICE_MAX_TASKS_PER_PROCESS); // jodconverter.maxTasksPerProcess
|
sharedInstance.setTemplateProfileDir(templateProfileDir);
|
||||||
jodconverter.setTaskExecutionTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.maxTaskExecutionTimeout
|
sharedInstance.setEnabled(isEnabled);
|
||||||
jodconverter.setTaskQueueTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.taskQueueTimeout
|
sharedInstance.afterPropertiesSet();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTransformerId()
|
public String getTransformerName()
|
||||||
{
|
{
|
||||||
return ID;
|
return "libreoffice";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
public void transform(String sourceMimetype, String sourceEncoding, InputStream inputStream,
|
||||||
|
String targetMimetype, String targetEncoding, OutputStream outputStream,
|
||||||
|
Map<String, String> transformOptions) throws Exception
|
||||||
|
{
|
||||||
|
throw new TransformException(500, "TODO LibreOffice transform");
|
||||||
|
}
|
||||||
|
|
||||||
public void transform(String transformName, String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
public void transform(String transformName, String sourceMimetype, String targetMimetype, Map<String, String> transformOptions,
|
||||||
File sourceFile, File targetFile)
|
File sourceFile, File targetFile)
|
||||||
{
|
{
|
||||||
call(sourceFile, targetFile);
|
call(sourceFile, targetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void call(File sourceFile, File targetFile, String... args)
|
public void call(File sourceFile, File targetFile, String... args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -229,7 +221,6 @@ public class LibreOfficeJavaExecutor implements JavaExecutor
|
|||||||
* This code exists in case there are custom implementations, that need to be converted to T-Engines.
|
* This code exists in case there are custom implementations, that need to be converted to T-Engines.
|
||||||
* It is simply a copy and paste from the content repository and has received limited testing.
|
* It is simply a copy and paste from the content repository and has received limited testing.
|
||||||
*/
|
*/
|
||||||
@Override
|
|
||||||
public void extractMetadata(String transformName, String sourceMimetype, String targetMimetype,
|
public void extractMetadata(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
Map<String, String> transformOptions,
|
Map<String, String> transformOptions,
|
||||||
File sourceFile, File targetFile)
|
File sourceFile, File targetFile)
|
@@ -3,8 +3,6 @@ queue:
|
|||||||
transform:
|
transform:
|
||||||
core:
|
core:
|
||||||
version: @project.version@
|
version: @project.version@
|
||||||
config:
|
|
||||||
location: classpath:libreoffice_engine_config.json
|
|
||||||
libreoffice:
|
libreoffice:
|
||||||
path: ${LIBREOFFICE_HOME:/opt/libreoffice7.2}
|
path: ${LIBREOFFICE_HOME:/opt/libreoffice7.2}
|
||||||
maxTasksPerProcess: ${LIBREOFFICE_MAX_TASKS_PER_PROCESS:200}
|
maxTasksPerProcess: ${LIBREOFFICE_MAX_TASKS_PER_PROCESS:200}
|
@@ -28,9 +28,9 @@ package org.alfresco.transform.libreoffice;
|
|||||||
|
|
||||||
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
|
import static org.alfresco.transform.common.Mimetype.MIMETYPE_PDF;
|
||||||
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
|
import static org.alfresco.transform.common.RequestParamMap.ENDPOINT_TRANSFORM;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.SOURCE_MIMETYPE;
|
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.TARGET_EXTENSION;
|
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.TARGET_MIMETYPE;
|
import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
@@ -58,9 +58,9 @@ import javax.annotation.PostConstruct;
|
|||||||
|
|
||||||
import org.alfresco.transform.client.model.TransformReply;
|
import org.alfresco.transform.client.model.TransformReply;
|
||||||
import org.alfresco.transform.client.model.TransformRequest;
|
import org.alfresco.transform.client.model.TransformRequest;
|
||||||
|
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
|
||||||
import org.alfresco.transformer.AbstractTransformerController;
|
import org.alfresco.transformer.AbstractTransformerController;
|
||||||
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
||||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
|
||||||
import org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
|
import org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
|
||||||
import org.alfresco.transformer.model.FileRefEntity;
|
import org.alfresco.transformer.model.FileRefEntity;
|
||||||
import org.alfresco.transformer.model.FileRefResponse;
|
import org.alfresco.transformer.model.FileRefResponse;
|
||||||
@@ -114,12 +114,12 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
@Value("${transform.core.libreoffice.isEnabled}")
|
@Value("${transform.core.libreoffice.isEnabled}")
|
||||||
private String isEnabled;
|
private String isEnabled;
|
||||||
|
|
||||||
protected LibreOfficeJavaExecutor javaExecutor;
|
protected LibreOfficeTransformer javaExecutor;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
javaExecutor = Mockito.spy(new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, isEnabled));
|
javaExecutor = Mockito.spy(new LibreOfficeTransformer(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, isEnabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -172,7 +172,7 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void setJavaExecutor(AbstractTransformerController controller, LibreOfficeJavaExecutor javaExecutor)
|
protected void setJavaExecutor(AbstractTransformerController controller, LibreOfficeTransformer javaExecutor)
|
||||||
{
|
{
|
||||||
ReflectionTestUtils.setField(controller, "javaExecutor", javaExecutor);
|
ReflectionTestUtils.setField(controller, "javaExecutor", javaExecutor);
|
||||||
}
|
}
|
||||||
@@ -314,14 +314,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new LibreOfficeJavaExecutor(execPath, "INVALID", timeout, portNumbers, templateProfileDir, isEnabled);
|
new LibreOfficeTransformer(execPath, "INVALID", timeout, portNumbers, templateProfileDir, isEnabled);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
errorMessage = e.getMessage();
|
errorMessage = e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("LibreOfficeJavaExecutor MAX_TASKS_PER_PROCESS must have a numeric value", errorMessage);
|
assertEquals("LibreOfficeTransformer MAX_TASKS_PER_PROCESS must have a numeric value", errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -330,14 +330,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, "INVALID", portNumbers, templateProfileDir, isEnabled);
|
new LibreOfficeTransformer(execPath, maxTasksPerProcess, "INVALID", portNumbers, templateProfileDir, isEnabled);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
errorMessage = e.getMessage();
|
errorMessage = e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("LibreOfficeJavaExecutor TIMEOUT must have a numeric value", errorMessage);
|
assertEquals("LibreOfficeTransformer TIMEOUT must have a numeric value", errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -346,14 +346,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, null, templateProfileDir, isEnabled);
|
new LibreOfficeTransformer(execPath, maxTasksPerProcess, timeout, null, templateProfileDir, isEnabled);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
errorMessage = e.getMessage();
|
errorMessage = e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("LibreOfficeJavaExecutor PORT variable cannot be null or empty", errorMessage);
|
assertEquals("LibreOfficeTransformer PORT variable cannot be null or empty", errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -362,13 +362,13 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
|||||||
String errorMessage = "";
|
String errorMessage = "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, "INVALID");
|
new LibreOfficeTransformer(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, "INVALID");
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e)
|
catch (IllegalArgumentException e)
|
||||||
{
|
{
|
||||||
errorMessage = e.getMessage();
|
errorMessage = e.getMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("LibreOfficeJavaExecutor IS_ENABLED variable must be set to true/false", errorMessage);
|
assertEquals("LibreOfficeTransformer IS_ENABLED variable must be set to true/false", errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|