Adding all the changes that was reverted

This commit is contained in:
bansari
2026-04-14 16:40:44 +05:30
parent 6c976d4d01
commit a7c1c2c3e1
4 changed files with 252 additions and 36 deletions

View File

@@ -30,11 +30,14 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.util.CollectionUtils;
import org.alfresco.transform.config.AddSupported;
import org.alfresco.transform.config.OverrideSupported;
import org.alfresco.transform.config.RemoveSupported;
@@ -71,6 +74,7 @@ public class CombinedTransformConfig
private final Map<String, Set<TransformOption>> combinedTransformOptions = new HashMap<>();
private List<Origin<Transformer>> combinedTransformers = new ArrayList<>();
private final Defaults defaults = new Defaults();
private final List<DeferredOverride> deferredOverrides = new ArrayList<>();
public static void combineAndRegister(TransformConfig transformConfig, String readFrom, String baseUrl,
AbstractTransformRegistry registry)
@@ -86,6 +90,7 @@ public class CombinedTransformConfig
combinedTransformOptions.clear();
combinedTransformers.clear();
defaults.clear();
deferredOverrides.clear();
}
public void addTransformConfig(List<Origin<TransformConfig>> transformConfigList, AbstractTransformRegistry registry)
@@ -101,7 +106,7 @@ public class CombinedTransformConfig
removeSupported(transformConfig.getRemoveSupported(), readFrom, registry);
addSupported(transformConfig.getAddSupported(), readFrom, registry);
overrideSupported(transformConfig.getOverrideSupported(), readFrom, registry);
storeOverridesForDeferredProcessing(transformConfig.getOverrideSupported(), readFrom);
// Add transform options and transformers from the new transformConfig
transformConfig.getTransformOptions().forEach(combinedTransformOptions::put);
@@ -218,23 +223,68 @@ public class CombinedTransformConfig
}));
}
private void overrideSupported(Set<OverrideSupported> overrideSupportedSet, String readFrom, AbstractTransformRegistry registry)
{
processSupported(overrideSupportedSet, readFrom, registry, "overrideSupported",
(leftOver, overrideSupported) -> combinedTransformers.stream().map(Origin::get).filter(transformer -> transformer.getTransformerName().equals(overrideSupported.getTransformerName())).forEach(transformerWithName -> {
Set<SupportedSourceAndTarget> supportedSourceAndTargetList = transformerWithName.getSupportedSourceAndTargetList();
SupportedSourceAndTarget existingSupported = getExistingSupported(
supportedSourceAndTargetList,
overrideSupported.getSourceMediaType(), overrideSupported.getTargetMediaType());
if (existingSupported != null)
{
supportedSourceAndTargetList.remove(existingSupported);
existingSupported.setMaxSourceSizeBytes(overrideSupported.getMaxSourceSizeBytes());
existingSupported.setPriority(overrideSupported.getPriority());
supportedSourceAndTargetList.add(existingSupported);
leftOver.remove(overrideSupported);
}
}));
/**
* Store overrides for deferred processing. Overrides are applied AFTER wildcard generation in the combineTransformerConfig() method, ensuring that pipeline transformers have their supportedSourceAndTargetList populated before overrides are applied.
*
* @param overrideSupportedSet the set of overrides to store
* @param readFrom where the overrides were read from
*/
private void storeOverridesForDeferredProcessing(Set<OverrideSupported> overrideSupportedSet, String readFrom) {
if (!CollectionUtils.isEmpty(overrideSupportedSet)) {
overrideSupportedSet.forEach(override -> deferredOverrides.add(new DeferredOverride(override, readFrom)));
}
}
/**
* Apply all stored overrides AFTER wildcard generation. This ensures that pipeline and failover transformers have their supportedSourceAndTargetList populated before overrides are applied.
*
* @param registry used for logging
*/
private void applyDeferredOverrides(AbstractTransformRegistry registry) {
if (CollectionUtils.isEmpty(deferredOverrides)) {
return;
}
Map<String, Set<OverrideSupported>> leftoverBySource = new HashMap<>();
for (DeferredOverride deferredOverride : deferredOverrides) {
OverrideSupported override = deferredOverride.getOverrideSupported();
String readFrom = deferredOverride.getReadFrom();
List<Transformer> matchedTransformers = combinedTransformers.stream()
.map(Origin::get)
.filter(transformer -> transformer.getTransformerName().equals(override.getTransformerName()))
.collect(Collectors.toList());
if (matchedTransformers.isEmpty()) {
leftoverBySource.computeIfAbsent(readFrom, k -> new HashSet<>()).add(override);
continue;
}
if (matchedTransformers.size() > 1) {
throw new IllegalStateException("Multiple transformers found for " + readFrom + " with name: " + override.getTransformerName() + ". This should not be possible as removeInvalidTransformers should have removed duplicates.");
}
Set<SupportedSourceAndTarget> supportedList = matchedTransformers.get(0).getSupportedSourceAndTargetList();
Optional<SupportedSourceAndTarget> existingSupportedOpt = supportedList.stream()
.filter(supported -> supported.getSourceMediaType().equals(override.getSourceMediaType()) &&
supported.getTargetMediaType().equals(override.getTargetMediaType()))
.findFirst();
if (existingSupportedOpt.isPresent()) {
SupportedSourceAndTarget existingSupported = existingSupportedOpt.get();
supportedList.remove(existingSupported);
if (override.getMaxSourceSizeBytes() != null) {
existingSupported.setMaxSourceSizeBytes(override.getMaxSourceSizeBytes());
}
if (override.getPriority() != null) {
existingSupported.setPriority(override.getPriority());
}
supportedList.add(existingSupported);
} else {
leftoverBySource.computeIfAbsent(readFrom, k -> new HashSet<>()).add(override);
}
}
// Warn about overrides that didn't match anything
leftoverBySource.forEach((readFrom, leftOvers) -> logWarn(leftOvers, readFrom, registry, "overrideSupported"));
deferredOverrides.clear();
}
private SupportedSourceAndTarget getExistingSupported(Set<SupportedSourceAndTarget> supportedSourceAndTargetList,
@@ -250,8 +300,9 @@ public class CombinedTransformConfig
{
removeInvalidTransformers(registry);
sortTransformers(registry);
applyDefaults();
addWildcardSupportedSourceAndTarget(registry);
applyDefaults();
applyDeferredOverrides(registry);
removePipelinesWithUnsupportedTransforms(registry);
setCoreVersionOnCombinedMultiStepTransformers();
}
@@ -584,28 +635,47 @@ public class CombinedTransformConfig
}
/**
* Applies priority and size defaults. Must be called before {@link #addWildcardSupportedSourceAndTarget(AbstractTransformRegistry)} as it uses the priority value.
* Applies priority and size defaults to a SupportedSourceAndTarget entry.
*/
private void applyDefaults()
{
private SupportedSourceAndTarget applyDefaultsToSupportedSourceAndTarget(
SupportedSourceAndTarget supportedSourceAndTarget,
String transformerName,
Set<String> supportedDefaultTransformerNames,
Defaults defaults) {
Integer priority = supportedSourceAndTarget.getPriority();
Long maxSourceSizeBytes = supportedSourceAndTarget.getMaxSourceSizeBytes();
String sourceMediaType = supportedSourceAndTarget.getSourceMediaType();
if (defaults.valuesUnset(priority, maxSourceSizeBytes)) {
supportedSourceAndTarget.setPriority(defaults.getPriority(transformerName, sourceMediaType, priority));
supportedSourceAndTarget.setMaxSourceSizeBytes(defaults.getMaxSourceSizeBytes(transformerName, sourceMediaType, maxSourceSizeBytes));
}
if (supportedDefaultTransformerNames.contains(transformerName)) {
supportedSourceAndTarget.setPriority(defaults.getPriority(transformerName, sourceMediaType, null));
supportedSourceAndTarget.setMaxSourceSizeBytes(defaults.getMaxSourceSizeBytes(transformerName, sourceMediaType, null));
}
return supportedSourceAndTarget;
}
/**
* Applies priority and size defaults to supported source/target entries.
* <p>
* Previously, this method was called before {@link #addWildcardSupportedSourceAndTarget(AbstractTransformRegistry)} because it relied on the priority value. As of MNT-25426, it is now called after wildcard generation, ensuring that pipeline transformers also receive the correct defaults.
*/
private void applyDefaults() {
Set<String> supportedDefaultTransformerNames = defaults.getSupportedDefaults()
.stream()
.map(SupportedDefaults::getTransformerName)
.collect(toSet());
combinedTransformers.stream()
.map(Origin::get)
.forEach(transformer -> {
transformer.setSupportedSourceAndTargetList(
transformer.getSupportedSourceAndTargetList().stream().map(supportedSourceAndTarget -> {
Integer priority = supportedSourceAndTarget.getPriority();
Long maxSourceSizeBytes = supportedSourceAndTarget.getMaxSourceSizeBytes();
if (defaults.valuesUnset(priority, maxSourceSizeBytes))
{
String transformerName = transformer.getTransformerName();
String sourceMediaType = supportedSourceAndTarget.getSourceMediaType();
supportedSourceAndTarget.setPriority(defaults.getPriority(transformerName, sourceMediaType, priority));
supportedSourceAndTarget.setMaxSourceSizeBytes(defaults.getMaxSourceSizeBytes(transformerName, sourceMediaType, maxSourceSizeBytes));
}
return supportedSourceAndTarget;
}).collect(toSet()));
transformer.getSupportedSourceAndTargetList()
.stream()
.map(supportedSourceAndTarget -> applyDefaultsToSupportedSourceAndTarget(supportedSourceAndTarget, transformer.getTransformerName(), supportedDefaultTransformerNames, defaults))
.collect(toSet()));
});
defaults.clear();
}
@@ -865,4 +935,8 @@ public class CombinedTransformConfig
{
return combinedTransformers.stream().collect(Collectors.toMap(origin -> origin.get().getTransformerName(), origin -> origin));
}
List<DeferredOverride> getDeferredOverrides() {
return deferredOverrides;
}
}

View File

@@ -0,0 +1,45 @@
/*
* #%L
* Alfresco Transform Model
* %%
* Copyright (C) 2026 Alfresco Software Limited
* %%
* This program 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.
*
* This program 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 General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/lgpl-3.0.html>.
* #L%
*/
package org.alfresco.transform.registry;
import org.alfresco.transform.config.OverrideSupported;
/**
* Holds override information for deferred processing after wildcard generation.
*/
class DeferredOverride {
private final OverrideSupported overrideSupported;
private final String readFrom;
public DeferredOverride(OverrideSupported overrideSupported, String readFrom) {
this.overrideSupported = overrideSupported;
this.readFrom = readFrom;
}
public OverrideSupported getOverrideSupported() {
return overrideSupported;
}
public String getReadFrom() {
return readFrom;
}
}

View File

@@ -39,6 +39,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.junit.jupiter.api.Test;
import org.alfresco.transform.config.OverrideSupported;
import org.alfresco.transform.config.SupportedSourceAndTarget;
import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transform.config.TransformStep;
@@ -300,6 +301,25 @@ public class CombinedTransformConfigTest
assertEquals(0, config.buildTransformConfig().getTransformOptions().size());
}
@Test
public void testClearAlsoRemovesDeferredOverrides() {
// Add a config with an overrideSupported entry to populate deferredOverrides
TransformConfig overrideConfig = TransformConfig.builder()
.withOverrideSupported(ImmutableSet.of(
OverrideSupported.builder()
.withTransformerName("pipeline1")
.withSourceMediaType("mimetype/a")
.withTargetMediaType("mimetype/b")
.withPriority(99)
.build()))
.build();
config.addTransformConfig(overrideConfig, READ_FROM_B, BASE_URL_B, registry);
assertEquals(1, config.getDeferredOverrides().size());
config.clear();
assertEquals(0, config.getDeferredOverrides().size());
}
@Test
public void testCombineTransformerConfigNoOp()
{

View File

@@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.collect.ImmutableList;
@@ -37,6 +38,7 @@ import org.alfresco.transform.config.RemoveSupported;
import org.alfresco.transform.config.SupportedDefaults;
import org.alfresco.transform.config.SupportedSourceAndTarget;
import org.alfresco.transform.config.TransformConfig;
import org.alfresco.transform.config.TransformStep;
import org.alfresco.transform.config.Transformer;
/**
@@ -433,7 +435,82 @@ public class OverrideTransformConfigTests
"{\"sourceMediaType\": \"mimetype/x\", \"targetMediaType\": \"mimetype/y\", \"maxSourceSizeBytes\": \"200\", \"priority\": \"23\"}" +
"]";
addTransformConfig(secondConfig, expectedWarnMessage, expectedSupported, expectedToString);
config.addTransformConfig(secondConfig, READ_FROM_B, BASE_URL_B, registry);
config.combineTransformerConfig(registry);
assertEquals(1, registry.warnMessages.size());
assertEquals(expectedWarnMessage, registry.warnMessages.get(0));
Set<SupportedSourceAndTarget> supportedSourceAndTargetList = config.buildTransformConfig().getTransformers().get(0).getSupportedSourceAndTargetList();
assertEquals(expectedSupported, supportedSourceAndTargetList);
assertEquals(expectedToString, supportedSourceAndTargetList.toString());
}
@Test
public void testDeferredOverrideForPipelineTransformer() {
// Add step transformers first
Transformer step1 = Transformer.builder()
.withTransformerName("step1")
.withSupportedSourceAndTargetList(Set.of(
SupportedSourceAndTarget.builder()
.withSourceMediaType("mimetype/document")
.withTargetMediaType("mimetype/pdf")
.build()))
.build();
Transformer step2 = Transformer.builder()
.withTransformerName("step2")
.withSupportedSourceAndTargetList(Set.of(
SupportedSourceAndTarget.builder()
.withSourceMediaType("mimetype/pdf")
.withTargetMediaType("mimetype/image")
.build()))
.build();
// Add pipeline transformer
Transformer pipelineTransformer = Transformer.builder()
.withTransformerName("pipeline1")
.withTransformerPipeline(List.of(
new TransformStep("step1", "mimetype/pdf"),
new TransformStep("step2", null)))
.build();
TransformConfig pipelineConfig = TransformConfig.builder()
.withTransformers(List.of(step1, step2, pipelineTransformer))
.build();
config.addTransformConfig(pipelineConfig, READ_FROM_A, BASE_URL_A, registry);
// Add override for pipeline transformer
OverrideSupported override = OverrideSupported.builder()
.withTransformerName("pipeline1")
.withSourceMediaType("mimetype/document")
.withTargetMediaType("mimetype/image")
.withPriority(40)
.build();
TransformConfig overrideConfig = TransformConfig.builder()
.withOverrideSupported(Set.of(override))
.build();
config.addTransformConfig(overrideConfig, READ_FROM_B, BASE_URL_B, registry);
// Combine configs
config.combineTransformerConfig(registry);
// Assert override applied
List<Transformer> transformers = config.buildTransformConfig().getTransformers();
assertTrue(!transformers.isEmpty(), "Pipeline transformer should exist after valid setup");
Set<SupportedSourceAndTarget> supportedList = transformers.stream()
.filter(t -> "pipeline1".equals(t.getTransformerName()))
.findFirst()
.orElseThrow()
.getSupportedSourceAndTargetList();
boolean found = supportedList.stream().anyMatch(s -> "mimetype/document".equals(s.getSourceMediaType()) &&
"mimetype/image".equals(s.getTargetMediaType()) &&
s.getPriority() == 40);
assertTrue(found, "Deferred override for pipeline transformer should be applied after wildcard generation");
}
private void addTransformConfig_A2B_X2Y_100_23()