MMKB-5027: do some refactorings + tests

This commit is contained in:
Schneider Roland 2024-11-25 15:04:22 +01:00
parent 394a5c42bf
commit af29265e11
12 changed files with 252 additions and 26 deletions

View File

@ -22,7 +22,7 @@ Module Updates funktionieren hierbei genauso wie SimpleUpdates. Es gibt 3 versch
* Yaml Bootstrap Files
* Tasks die nachdem Bootstrap ausgeführt werden sollen
Jedes Module muss eine Version gesetzt haben und muss mit einem Timestamp (ddMMyyyyHHmm) starten.
Jedes ModuleUpdate File muss der folgenden NamingConvention entsprechen `V<yyyyMMddHHmmss>_<SomeDescription>.java`.
## Allgemeine Funktionsweise

10
pom.xml
View File

@ -6,10 +6,11 @@
<javaVersion>21</javaVersion>
<magnoliaBundleVersion>6.2.46</magnoliaBundleVersion>
<version.lombok>1.18.34</version.lombok>
<version.mockito>5.13.0</version.mockito>
</properties>
<groupId>at.ucs.magnolia</groupId>
<artifactId>ucs-intranet-magnolia-updates</artifactId>
<version>1.0.0</version>
<version>1.0.1</version>
<name>ucs-intranet-magnolia-updates</name>
<url>http://maven.apache.org</url>
<packaging>jar</packaging>
@ -42,7 +43,12 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${version.mockito}</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -2,6 +2,7 @@ package at.ucs.magnolia.updates;
import at.ucs.magnolia.updates.util.TaskWrapper;
import at.ucs.magnolia.updates.util.VersionComparator;
import at.ucs.magnolia.updates.util.VersionNumberUtil;
import at.ucs.magnolia.updates.util.VersionUtil;
import info.magnolia.module.DefaultModuleVersionHandler;
import info.magnolia.module.InstallContext;
@ -9,6 +10,7 @@ import info.magnolia.module.delta.Delta;
import info.magnolia.module.delta.DeltaBuilder;
import info.magnolia.module.delta.Task;
import info.magnolia.module.model.Version;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
@ -20,10 +22,17 @@ import java.util.*;
import java.util.function.Predicate;
import java.util.stream.IntStream;
@Getter
@Slf4j
public abstract class IntranetUpdateModuleVersionHandler extends DefaultModuleVersionHandler {
public class IntranetUpdateModuleVersionHandler extends DefaultModuleVersionHandler {
protected IntranetUpdateModuleConfig moduleConfig;
public IntranetUpdateModuleVersionHandler(IntranetUpdateModuleConfig moduleConfig){
super();
this.moduleConfig = moduleConfig;
}
protected abstract IntranetUpdateModuleConfig getModuleConfig();
@Override
protected List<Task> getExtraInstallTasks(InstallContext installContext) {
@ -62,9 +71,7 @@ public abstract class IntranetUpdateModuleVersionHandler extends DefaultModuleVe
private ModuleUpdate initiateModuleUpdate(Class<? extends ModuleUpdate> moduleUpdateClass) {
try {
ModuleUpdate moduleUpdate = moduleUpdateClass.getConstructor().newInstance();
moduleUpdate.setYamlPath(getModuleConfig().getYamlUpdateDir());
return moduleUpdate;
return moduleUpdateClass.getConstructor().newInstance();
} catch (RuntimeException | NoSuchMethodException | InstantiationException |
IllegalAccessException |
InvocationTargetException e) {
@ -84,11 +91,13 @@ public abstract class IntranetUpdateModuleVersionHandler extends DefaultModuleVe
}
private Delta buildDelta(InstallContext installContext, ModuleUpdate moduleUpdate) {
final String version = moduleUpdate.getVersion();
List<Task> wrappedTasks = IntStream.range(0, moduleUpdate.getAllTasks().size())
final String version = VersionNumberUtil.getVersion(moduleUpdate);
List<Task> moduleUpdateTasks = moduleUpdate.getAllTasks(moduleConfig,version);
List<Task> wrappedTasks = IntStream.range(0,moduleUpdateTasks .size())
.mapToObj(i -> {
final String wrappedVersion = MessageFormat.format("{0}_{1}", version, i);
final Task task = moduleUpdate.getAllTasks().get(i);
final Task task = moduleUpdateTasks.get(i);
return new TaskWrapper(task, wrappedVersion);
})
.filter(installNecessary(installContext))

View File

@ -3,22 +3,16 @@ package at.ucs.magnolia.updates;
import at.ucs.magnolia.updates.util.BootstrapUpdateYamlsWithProperties;
import at.ucs.magnolia.updates.util.LoggingTask;
import info.magnolia.module.delta.Task;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Getter
@Setter
@RequiredArgsConstructor
public abstract class ModuleUpdate {
private final String version;
private String yamlPath;
public List<Task> getUpdateTasks() {
return Collections.emptyList();
@ -28,14 +22,14 @@ public abstract class ModuleUpdate {
return Collections.emptyList();
}
public List<Task> getAllTasks() {
public List<Task> getAllTasks(IntranetUpdateModuleConfig config, String version) {
List<Task> tasks = new ArrayList<>();
tasks.add(new LoggingTask("updating to version: " + version, ""));
tasks.addAll(getUpdateTasks());
tasks.add(new LoggingTask("Importing bootsrap Yamls for: " + version, ""));
tasks.add(new BootstrapUpdateYamlsWithProperties(
"Import bootstrap YAML folder",
MessageFormat.format("Imports bootstrap YAML files from {0}{1}", yamlPath, version), version, yamlPath));
MessageFormat.format("Imports bootstrap YAML files from {0}{1}", config.getYamlUpdateDir(), version), version, config.getYamlUpdateDir()));
tasks.addAll(getUpdateTasksAfterBootstrap());
return tasks;
}

View File

@ -8,14 +8,13 @@ import info.magnolia.module.delta.TaskExecutionException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
@Getter
@Slf4j
public class TaskWrapper extends AbstractTask {
private final Task task;
@Getter
private final String version;
public TaskWrapper(Task task, String version) {

View File

@ -9,14 +9,15 @@ import java.util.Comparator;
@Slf4j
public class VersionComparator implements Comparator<ModuleUpdate> {
public static final String VERSION_DATE_FORMAT = "yyyyMMddHHmmss";
@Override
public int compare(ModuleUpdate o1, ModuleUpdate o2) {
var o1Version = o1.getVersion();
var o2Version = o2.getVersion();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("ddMMyyyyHHmm");
LocalDateTime first = LocalDateTime.from(dateTimeFormatter.parse(o1Version.substring(0, 12)));
LocalDateTime second = LocalDateTime.from(dateTimeFormatter.parse(o2Version.substring(0, 12)));
var o1Version = VersionNumberUtil.getVersion(o1);
var o2Version = VersionNumberUtil.getVersion(o2);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(VERSION_DATE_FORMAT);
LocalDateTime first = LocalDateTime.from(dateTimeFormatter.parse(o1Version));
LocalDateTime second = LocalDateTime.from(dateTimeFormatter.parse(o2Version));
return first.compareTo(second);
}

View File

@ -0,0 +1,15 @@
package at.ucs.magnolia.updates.util;
import at.ucs.magnolia.updates.ModuleUpdate;
import org.apache.commons.lang3.StringUtils;
public class VersionNumberUtil {
public static String getVersion(ModuleUpdate update) {
if (update == null) {
return null;
}
return StringUtils.substring(update.getClass().getSimpleName(), 1, VersionComparator.VERSION_DATE_FORMAT.length()+1);
}
}

View File

@ -38,4 +38,5 @@ public class VersionUtil {
}
}
}

View File

@ -0,0 +1,159 @@
package at.ucs.magnolia.updates;
import at.ucs.magnolia.updates.util.TaskWrapper;
import at.ucs.magnolia.updates.util.VersionUtil;
import info.magnolia.module.InstallContext;
import info.magnolia.module.delta.Delta;
import info.magnolia.module.delta.Task;
import info.magnolia.module.model.ModuleDefinition;
import info.magnolia.module.model.Version;
import org.junit.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import javax.jcr.RepositoryException;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
public class IntranetUpdateModuleVersionHandlerTest {
private static final List<String> appliedUpdates = new ArrayList<>();
@Test
public void testGetDeltas_mustReturnSimpleTask() throws RepositoryException {
try (MockedStatic<VersionUtil> utilities = Mockito.mockStatic(VersionUtil.class)) {
mockVersionUtil(utilities);
InstallContext installContext = Mockito.mock(InstallContext.class);
ModuleDefinition moduleDefinition = Mockito.mock(ModuleDefinition.class);
Mockito.when(installContext.getCurrentModuleDefinition()).thenReturn(moduleDefinition);
Mockito.when(moduleDefinition.getVersion()).thenReturn(Version.parseVersion("9.9.9"));
IntranetUpdateModuleConfig config = new IntranetUpdateModuleConfig() {
@Override
public List<Task> getInitialUpdateTasks() {
return List.of();
}
@Override
public String getYamlUpdateDir() {
return "";
}
@Override
public String getUpdateTaskPackage() {
return "at.ucs.magnolia.updates.test.updates1";
}
};
List<Delta> deltas = new IntranetUpdateModuleVersionHandler(config).getDeltas(installContext, installContext.getCurrentModuleDefinition().getVersion());
assertThat(deltas.size(), equalTo(1));
// the TestTask contained by the class V20241125113012_TestUpdate1 should be returned
List<Task> matching = deltas.stream().flatMap(delta -> delta.getTasks().stream()).filter( task -> (task instanceof TaskWrapper && ((TaskWrapper)task).getTask() instanceof TestTask) || (task instanceof TestTask)).toList();
assertThat("count of testtask must be 1", matching.size(), equalTo(1));
}
}
@Test
public void testGetDeltas_mustReturnAlsoInstallTasks() throws RepositoryException {
try (MockedStatic<VersionUtil> utilities = Mockito.mockStatic(VersionUtil.class)) {
mockVersionUtil(utilities);
InstallContext installContext = Mockito.mock(InstallContext.class);
ModuleDefinition moduleDefinition = Mockito.mock(ModuleDefinition.class);
Mockito.when(installContext.getCurrentModuleDefinition()).thenReturn(moduleDefinition);
Mockito.when(moduleDefinition.getVersion()).thenReturn(null);
IntranetUpdateModuleConfig config = new IntranetUpdateModuleConfig() {
@Override
public List<Task> getInitialUpdateTasks() {
return List.of(new TestTask("install1","install1desc"));
}
@Override
public String getYamlUpdateDir() {
return "";
}
@Override
public String getUpdateTaskPackage() {
return "at.ucs.magnolia.updates.test.updates1";
}
};
List<Delta> deltas = new IntranetUpdateModuleVersionHandler(config).getDeltas(installContext, installContext.getCurrentModuleDefinition().getVersion());
assertThat(deltas.size(), equalTo(2));
// the TestTask contained by the class V20241125113012_TestUpdate1 must be returned
// The TestTask returned by the IntranetUpdateModuleConfig#getInitialUpdateTasks must be contained
List<Task> matching = deltas.stream().flatMap(delta -> delta.getTasks().stream()).filter( task -> (task instanceof TaskWrapper && ((TaskWrapper)task).getTask() instanceof TestTask) || (task instanceof TestTask)).toList();
assertThat("count of testtask must be 2", matching.size(), equalTo(2));
}
}
@Test
public void testGetDeltas_mustNotReturnInstallTasks() throws RepositoryException {
try (MockedStatic<VersionUtil> utilities = Mockito.mockStatic(VersionUtil.class)) {
mockVersionUtil(utilities);
InstallContext installContext = Mockito.mock(InstallContext.class);
ModuleDefinition moduleDefinition = Mockito.mock(ModuleDefinition.class);
Mockito.when(installContext.getCurrentModuleDefinition()).thenReturn(moduleDefinition);
Mockito.when(moduleDefinition.getVersion()).thenReturn(Version.parseVersion("9.9.9"));
IntranetUpdateModuleConfig config = new IntranetUpdateModuleConfig() {
@Override
public List<Task> getInitialUpdateTasks() {
return List.of(new TestTask("install1","install1desc"));
}
@Override
public String getYamlUpdateDir() {
return "";
}
@Override
public String getUpdateTaskPackage() {
return "at.ucs.magnolia.updates.test.updates1";
}
};
List<Delta> deltas = new IntranetUpdateModuleVersionHandler(config).getDeltas(installContext, installContext.getCurrentModuleDefinition().getVersion());
assertThat(deltas.size(), equalTo(1));
// the TestTask contained by the class V20241125113012_TestUpdate1 should be returned
// The TestTask returned by the IntranetUpdateModuleConfig#getInitialUpdateTasks must not be contained
List<Task> matching = deltas.stream().flatMap(delta -> delta.getTasks().stream()).filter( task -> (task instanceof TaskWrapper && ((TaskWrapper)task).getTask() instanceof TestTask) || (task instanceof TestTask)).toList();
assertThat("count of testtask must be 1", matching.size(), equalTo(1));
}
}
private void mockVersionUtil(MockedStatic<VersionUtil> utilities) throws RepositoryException {
utilities.when(() -> VersionUtil.containsVersion(Mockito.any(), Mockito.any()))
.thenAnswer(
invocation -> {
String version = invocation.getArgument(1, String.class);
return appliedUpdates.contains(version);
}
);
utilities.when(() -> VersionUtil.addVersion(Mockito.any(), Mockito.any(), Mockito.any()))
.thenAnswer(
invocation -> {
String version = invocation.getArgument(1, String.class);
return appliedUpdates.add(version);
}
);
utilities.when(() -> VersionUtil.addVersion(Mockito.any(), Mockito.any(), Mockito.any()))
.thenAnswer(
invocation -> {
String version = invocation.getArgument(1, String.class);
return appliedUpdates.add(version);
}
);
String testVersion = "123456";
assertThat(VersionUtil.containsVersion(null, testVersion), equalTo(false));
VersionUtil.addVersion(null, testVersion, null);
assertThat(VersionUtil.containsVersion(null, testVersion), equalTo(true));
// cleanup versions
appliedUpdates.clear();
}
}

View File

@ -0,0 +1,10 @@
package at.ucs.magnolia.updates;
import at.ucs.magnolia.updates.util.LoggingTask;
public class TestTask extends LoggingTask {
public TestTask(String taskName, String taskDescription) {
super(taskName, taskDescription);
}
}

View File

@ -0,0 +1,15 @@
package at.ucs.magnolia.updates.test.updates1;
import at.ucs.magnolia.updates.ModuleUpdate;
import at.ucs.magnolia.updates.TestTask;
import info.magnolia.module.delta.Task;
import java.util.List;
public class V20241125113012_TestUpdate1 extends ModuleUpdate {
@Override
public List<Task> getUpdateTasks() {
return List.of(new TestTask("test1","V20241125113012_TestUpdate1"));
}
}

View File

@ -0,0 +1,17 @@
package at.ucs.magnolia.updates.util;
import at.ucs.magnolia.updates.test.updates1.V20241125113012_TestUpdate1;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
public class VersionNumberUtilTest {
@Test
public void testGetVersion() {
String version = VersionNumberUtil.getVersion(new V20241125113012_TestUpdate1());
assertThat("version must match",version,equalTo("20241125113012"));
}
}