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
|
||||
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)
|
||||
* `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
|
||||
[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
|
||||
and a [Docker image](https://github.com/Alfresco/alfresco-transform-core#docker)
|
||||
|
||||
### 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
|
||||
* [ACS Packaging docs](https://github.com/Alfresco/acs-packaging/tree/master/docs) folder
|
||||
@@ -49,7 +49,7 @@ The artifacts can be obtained by:
|
||||
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>version</version>
|
||||
</dependency>
|
||||
```
|
||||
|
@@ -20,7 +20,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -30,7 +30,7 @@
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<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>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</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/>.
|
||||
* #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.WebEnvironment;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
@@ -24,14 +24,14 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.transformer.AbstractTransformerController;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -62,7 +62,7 @@ public class AIOControllerLibreOfficeTest extends LibreOfficeControllerTest
|
||||
|
||||
@Override
|
||||
// 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...
|
||||
Map<String,Transformer> transformers = transformRegistry.getTransformerEngineMapping();
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
@@ -24,16 +24,13 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
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.base.executors.Transformer;
|
||||
import org.junit.jupiter.api.Test;
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.aio.AIOController;
|
||||
import org.alfresco.transform.aio.AIOCustomConfig;
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.imagemagick.ImageMagickTransformationIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.libreoffice.LibreOfficeTransformationIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.misc.MiscMetadataExtractsIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.misc.MiscTransformsIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.pdfRenderer.AlfrescoPdfRendererTransformationIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #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_TEXT_PLAIN;
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.tika.TikaMetadataExtractsIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import org.alfresco.transform.tika.TikaTransformationIT;
|
||||
|
@@ -24,7 +24,7 @@
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.transform.aio;
|
||||
package org.alfresco.transform.coreaio;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.alfresco.transform.aio.AIOTransformRegistry;
|
||||
@@ -49,7 +49,7 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
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.assertTrue;
|
||||
|
@@ -20,12 +20,12 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<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>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
@@ -32,8 +32,8 @@ import org.alfresco.transform.common.TransformException;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import static org.alfresco.transformer.util.Util.stringToBoolean;
|
||||
import static org.alfresco.transformer.util.Util.stringToInteger;
|
||||
import static org.alfresco.transform.base.util.Util.stringToBoolean;
|
||||
import static org.alfresco.transform.base.util.Util.stringToInteger;
|
||||
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;
|
||||
|
||||
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.common.TransformException;
|
||||
import org.alfresco.transformer.executors.AbstractCommandExecutor;
|
||||
import org.alfresco.transformer.executors.RuntimeExec;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.alfresco.transformer.util.RequestParamMap.ALLOW_ENLARGEMENT;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.ALPHA_REMOVE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.AUTO_ORIENT;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.COMMAND_OPTIONS;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_GRAVITY;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_HEIGHT;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_PERCENTAGE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_WIDTH;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_X_OFFSET;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.CROP_Y_OFFSET;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.END_PAGE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.MAINTAIN_ASPECT_RATIO;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_HEIGHT;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_PERCENTAGE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.RESIZE_WIDTH;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.START_PAGE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.THUMBNAIL;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.TIMEOUT;
|
||||
import static org.alfresco.transformer.util.Util.stringToInteger;
|
||||
import static org.alfresco.transformer.util.Util.stringToLong;
|
||||
import static org.alfresco.transform.base.util.Util.stringToInteger;
|
||||
import static org.alfresco.transform.base.util.Util.stringToLong;
|
||||
import static org.alfresco.transform.common.RequestParamMap.ALLOW_ENLARGEMENT;
|
||||
import static org.alfresco.transform.common.RequestParamMap.ALPHA_REMOVE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.AUTO_ORIENT;
|
||||
import static org.alfresco.transform.common.RequestParamMap.COMMAND_OPTIONS;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_GRAVITY;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_HEIGHT;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_PERCENTAGE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_WIDTH;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_X_OFFSET;
|
||||
import static org.alfresco.transform.common.RequestParamMap.CROP_Y_OFFSET;
|
||||
import static org.alfresco.transform.common.RequestParamMap.END_PAGE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.MAINTAIN_ASPECT_RATIO;
|
||||
import static org.alfresco.transform.common.RequestParamMap.RESIZE_HEIGHT;
|
||||
import static org.alfresco.transform.common.RequestParamMap.RESIZE_PERCENTAGE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.RESIZE_WIDTH;
|
||||
import static org.alfresco.transform.common.RequestParamMap.START_PAGE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.THUMBNAIL;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TIMEOUT;
|
||||
|
||||
/**
|
||||
* CommandExecutor implementation for running ImageMagick transformations. It runs the
|
||||
* transformation logic as a separate Shell process.
|
||||
*/
|
||||
public class ImageMagickCommandExecutor extends AbstractCommandExecutor
|
||||
@Component
|
||||
public class ImageMagickTransformer extends AbstractCommandExecutor implements CustomTransformer
|
||||
{
|
||||
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;
|
||||
private final String DYN;
|
||||
private final String EXE;
|
||||
private final String CODERS;
|
||||
private final String CONFIG;
|
||||
// Not currently used, but may be again in the future if we need an ImageMagick extension
|
||||
@Value("${transform.core.imagemagick.coders}")
|
||||
private String coders;
|
||||
@Value("${transform.core.imagemagick.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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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.checkCommand = createCheckCommand();
|
||||
}
|
||||
|
||||
@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
|
||||
protected RuntimeExec createTransformCommand()
|
||||
{
|
||||
RuntimeExec runtimeExec = new RuntimeExec();
|
||||
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||
commandsAndArguments.put(".*",
|
||||
new String[]{EXE, "${source}", "SPLIT:${options}", "-strip", "-quiet", "${target}"});
|
||||
new String[]{exe, "${source}", "SPLIT:${options}", "-strip", "-quiet", "${target}"});
|
||||
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||
|
||||
Map<String, String> processProperties = new HashMap<>();
|
||||
processProperties.put("MAGICK_HOME", ROOT);
|
||||
processProperties.put("DYLD_FALLBACK_LIBRARY_PATH", DYN);
|
||||
processProperties.put("LD_LIBRARY_PATH", DYN);
|
||||
processProperties.put("MAGICK_HOME", root);
|
||||
processProperties.put("DYLD_FALLBACK_LIBRARY_PATH", dyn);
|
||||
processProperties.put("LD_LIBRARY_PATH", dyn);
|
||||
|
||||
//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);
|
||||
|
||||
@@ -142,12 +144,18 @@ public class ImageMagickCommandExecutor extends AbstractCommandExecutor
|
||||
{
|
||||
RuntimeExec runtimeExec = new RuntimeExec();
|
||||
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||
commandsAndArguments.put(".*", new String[]{EXE, "-version"});
|
||||
commandsAndArguments.put(".*", new String[]{exe, "-version"});
|
||||
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||
return runtimeExec;
|
||||
}
|
||||
|
||||
@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,
|
||||
Map<String, String> transformOptions,
|
||||
File sourceFile, File targetFile) throws TransformException
|
@@ -3,8 +3,6 @@ queue:
|
||||
transform:
|
||||
core:
|
||||
version: @project.version@
|
||||
config:
|
||||
location: classpath:imagemagick_engine_config.json
|
||||
imagemagick:
|
||||
root: ${IMAGEMAGICK_ROOT:/usr/lib64/ImageMagick-7.0.10}
|
||||
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.TransformRequest;
|
||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickCommandExecutor;
|
||||
import org.alfresco.transform.imagemagick.transformers.ImageMagickTransformer;
|
||||
import org.alfresco.transformer.AbstractTransformerController;
|
||||
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
||||
import org.alfresco.transformer.executors.RuntimeExec;
|
||||
@@ -119,12 +119,12 @@ public class ImageMagickControllerTest extends AbstractTransformerControllerTest
|
||||
@Value("${transform.core.imagemagick.config}")
|
||||
protected String CONFIG;
|
||||
|
||||
ImageMagickCommandExecutor commandExecutor;
|
||||
ImageMagickTransformer commandExecutor;
|
||||
|
||||
@PostConstruct
|
||||
private void init()
|
||||
{
|
||||
commandExecutor = new ImageMagickCommandExecutor(EXE, DYN, ROOT, CODERS, CONFIG);
|
||||
commandExecutor = new ImageMagickTransformer(EXE, DYN, ROOT, CODERS, CONFIG);
|
||||
}
|
||||
|
||||
@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>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<classifier>tests</classifier>
|
||||
<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>
|
||||
<dependency>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-transformer-base</artifactId>
|
||||
<artifactId>alfresco-t-engine-base</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</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.sun.star.task.ErrorCodeIOException;
|
||||
import org.alfresco.transform.base.CustomTransformer;
|
||||
import org.alfresco.transform.common.TransformException;
|
||||
import org.alfresco.transformer.executors.JavaExecutor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
@@ -39,9 +39,14 @@ import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
import org.slf4j.Logger;
|
||||
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.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
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
|
||||
* 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(LibreOfficeJavaExecutor.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(LibreOfficeTransformer.class);
|
||||
|
||||
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 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 JodConverter jodconverter;
|
||||
|
||||
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())
|
||||
{
|
||||
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(timeout == null || timeout.isEmpty() || !StringUtils.isNumeric(timeout))
|
||||
if (maxTasksPerProcess == null || maxTasksPerProcess.isEmpty() || !StringUtils.isNumeric(maxTasksPerProcess))
|
||||
{
|
||||
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(maxTasksPerProcess == null || maxTasksPerProcess.isEmpty() || !StringUtils.isNumeric(maxTasksPerProcess))
|
||||
if (timeout == null || timeout.isEmpty() || !StringUtils.isNumeric(timeout))
|
||||
{
|
||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor MAX_TASKS_PER_PROCESS must have a numeric value");
|
||||
}
|
||||
LIBREOFFICE_MAX_TASKS_PER_PROCESS = maxTasksPerProcess;
|
||||
|
||||
if(portNumbers == null || portNumbers.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException("LibreOfficeJavaExecutor PORT variable cannot be null or empty");
|
||||
throw new IllegalArgumentException("LibreOfficeTransformer LIBREOFFICE_TIMEOUT must have a numeric value");
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
private static JodConverter createJodConverter()
|
||||
{
|
||||
final JodConverterSharedInstance jodconverter = new JodConverterSharedInstance();
|
||||
|
||||
jodconverter.setOfficeHome(LIBREOFFICE_HOME); // jodconverter.officeHome
|
||||
jodconverter.setMaxTasksPerProcess(LIBREOFFICE_MAX_TASKS_PER_PROCESS); // jodconverter.maxTasksPerProcess
|
||||
jodconverter.setTaskExecutionTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.maxTaskExecutionTimeout
|
||||
jodconverter.setTaskQueueTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.taskQueueTimeout
|
||||
jodconverter.setConnectTimeout(LIBREOFFICE_TIMEOUT); // jodconverter.connectTimeout
|
||||
jodconverter.setPortNumbers(LIBREOFFICE_PORT_NUMBERS); // jodconverter.portNumbers
|
||||
jodconverter.setTemplateProfileDir(LIBREOFFICE_TEMPLATE_PROFILE_DIR); // jodconverter.templateProfileDir
|
||||
jodconverter.setEnabled(LIBREOFFICE_IS_ENABLED); // jodconverter.enabled
|
||||
jodconverter.afterPropertiesSet();
|
||||
|
||||
return jodconverter;
|
||||
JodConverterSharedInstance sharedInstance = new JodConverterSharedInstance();
|
||||
jodconverter = sharedInstance;
|
||||
sharedInstance.setOfficeHome(path);
|
||||
sharedInstance.setMaxTasksPerProcess(maxTasksPerProcess);
|
||||
sharedInstance.setTaskExecutionTimeout(timeout);
|
||||
sharedInstance.setTaskQueueTimeout(timeout);
|
||||
sharedInstance.setConnectTimeout(timeout);
|
||||
sharedInstance.setPortNumbers(portNumbers);
|
||||
sharedInstance.setTemplateProfileDir(templateProfileDir);
|
||||
sharedInstance.setEnabled(isEnabled);
|
||||
sharedInstance.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTransformerId()
|
||||
public String getTransformerName()
|
||||
{
|
||||
return ID;
|
||||
return "libreoffice";
|
||||
}
|
||||
|
||||
@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,
|
||||
File sourceFile, File targetFile)
|
||||
{
|
||||
call(sourceFile, targetFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(File sourceFile, File targetFile, String... args)
|
||||
{
|
||||
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.
|
||||
* 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,
|
||||
Map<String, String> transformOptions,
|
||||
File sourceFile, File targetFile)
|
@@ -3,8 +3,6 @@ queue:
|
||||
transform:
|
||||
core:
|
||||
version: @project.version@
|
||||
config:
|
||||
location: classpath:libreoffice_engine_config.json
|
||||
libreoffice:
|
||||
path: ${LIBREOFFICE_HOME:/opt/libreoffice7.2}
|
||||
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.RequestParamMap.ENDPOINT_TRANSFORM;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.SOURCE_MIMETYPE;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.TARGET_EXTENSION;
|
||||
import static org.alfresco.transformer.util.RequestParamMap.TARGET_MIMETYPE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.SOURCE_MIMETYPE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TARGET_MIMETYPE;
|
||||
import static org.alfresco.transform.common.RequestParamMap.TARGET_EXTENSION;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
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.TransformRequest;
|
||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeTransformer;
|
||||
import org.alfresco.transformer.AbstractTransformerController;
|
||||
import org.alfresco.transformer.AbstractTransformerControllerTest;
|
||||
import org.alfresco.transform.libreoffice.transformers.LibreOfficeJavaExecutor;
|
||||
import org.alfresco.transformer.executors.RuntimeExec.ExecutionResult;
|
||||
import org.alfresco.transformer.model.FileRefEntity;
|
||||
import org.alfresco.transformer.model.FileRefResponse;
|
||||
@@ -114,12 +114,12 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
||||
@Value("${transform.core.libreoffice.isEnabled}")
|
||||
private String isEnabled;
|
||||
|
||||
protected LibreOfficeJavaExecutor javaExecutor;
|
||||
protected LibreOfficeTransformer javaExecutor;
|
||||
|
||||
@PostConstruct
|
||||
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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -314,14 +314,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
||||
String errorMessage = "";
|
||||
try
|
||||
{
|
||||
new LibreOfficeJavaExecutor(execPath, "INVALID", timeout, portNumbers, templateProfileDir, isEnabled);
|
||||
new LibreOfficeTransformer(execPath, "INVALID", timeout, portNumbers, templateProfileDir, isEnabled);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
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
|
||||
@@ -330,14 +330,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
||||
String errorMessage = "";
|
||||
try
|
||||
{
|
||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, "INVALID", portNumbers, templateProfileDir, isEnabled);
|
||||
new LibreOfficeTransformer(execPath, maxTasksPerProcess, "INVALID", portNumbers, templateProfileDir, isEnabled);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
errorMessage = e.getMessage();
|
||||
}
|
||||
|
||||
assertEquals("LibreOfficeJavaExecutor TIMEOUT must have a numeric value", errorMessage);
|
||||
assertEquals("LibreOfficeTransformer TIMEOUT must have a numeric value", errorMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -346,14 +346,14 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
||||
String errorMessage = "";
|
||||
try
|
||||
{
|
||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, null, templateProfileDir, isEnabled);
|
||||
new LibreOfficeTransformer(execPath, maxTasksPerProcess, timeout, null, templateProfileDir, isEnabled);
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
errorMessage = e.getMessage();
|
||||
}
|
||||
|
||||
assertEquals("LibreOfficeJavaExecutor PORT variable cannot be null or empty", errorMessage);
|
||||
assertEquals("LibreOfficeTransformer PORT variable cannot be null or empty", errorMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -362,13 +362,13 @@ public class LibreOfficeControllerTest extends AbstractTransformerControllerTest
|
||||
String errorMessage = "";
|
||||
try
|
||||
{
|
||||
new LibreOfficeJavaExecutor(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, "INVALID");
|
||||
new LibreOfficeTransformer(execPath, maxTasksPerProcess, timeout, portNumbers, templateProfileDir, "INVALID");
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|