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
This commit is contained in:
alandavis
2022-07-01 17:14:01 +01:00
parent 2e05eb71fb
commit c44ff5016a
373 changed files with 967 additions and 2119 deletions

View File

@@ -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>

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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;
/**

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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}

View File

@@ -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