From 66ef87aeef7b2aa7e94985c92eadc2a029b4e329 Mon Sep 17 00:00:00 2001 From: Mustapha Zorgati <15628173+mustaphazorgati@users.noreply.github.com> Date: Wed, 17 Feb 2021 08:28:12 +0100 Subject: [PATCH] TSK-1572: replaced CURRENT_TIMESTAMP db function with Instant --- .../taskana/common/internal/JobMapper.java | 2 +- .../monitor/internal/MonitorMapper.java | 56 +++++---- ...assificationCategoryReportBuilderImpl.java | 2 + .../ClassificationReportBuilderImpl.java | 3 + ...TaskCustomFieldValueReportBuilderImpl.java | 2 + .../TimeIntervalReportBuilderImpl.java | 2 + .../reports/TimestampReportBuilderImpl.java | 2 + .../reports/WorkbasketReportBuilderImpl.java | 2 + .../java/pro/taskana/ArchitectureTest.java | 105 ++++++++++++++--- ...ficationCategoryReportBuilderImplTest.java | 64 ++++++----- .../ClassificationReportBuilderImplTest.java | 104 +++++++++-------- ...CustomFieldValueReportBuilderImplTest.java | 43 +++---- .../WorkbasketReportBuilderImplTest.java | 108 ++++++++++-------- 13 files changed, 306 insertions(+), 189 deletions(-) diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobMapper.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobMapper.java index 48e69c0c9..6d8d3c430 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/JobMapper.java @@ -38,7 +38,7 @@ public interface JobMapper { @Select( "") diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java index 6a6fd14b2..43177da7c 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/MonitorMapper.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal; +import java.time.Instant; import java.util.List; import java.util.Map; import org.apache.ibatis.annotations.Param; @@ -23,9 +24,9 @@ public interface MonitorMapper { @Select( "") List getTaskIdsForSelectedItems( + @Param("now") Instant now, @Param("workbasketIds") List workbasketIds, @Param("states") List states, @Param("classificationCategories") List classificationCategories, @@ -429,9 +436,9 @@ public interface MonitorMapper { // overhead / complexity. It's worth the trade-off of not computing the AGE_IN_DAYS column // twice. + "SELECT W.ORG_LEVEL_1, W.ORG_LEVEL_2, W.ORG_LEVEL_3, W.ORG_LEVEL_4, " - + "(DAYS(T.${status}) - DAYS(CURRENT_TIMESTAMP))" - + "DATEDIFF('DAY', CURRENT_TIMESTAMP, T.${status})" - + "DATE_PART('DAY', T.${status} - CURRENT_TIMESTAMP)" + + "(DAYS(T.${status}) - DAYS(#{now}))" + + "DATEDIFF('DAY', #{now}, T.${status})" + + "DATE_PART('DAY', T.${status} - #{now})" + " as AGE_IN_DAYS " + "FROM TASK AS T INNER JOIN WORKBASKET AS W ON T.WORKBASKET_KEY=W.KEY " + "" @@ -465,6 +472,7 @@ public interface MonitorMapper { @Result(column = "ORG_LEVEL_3", property = "orgLevel3") @Result(column = "ORG_LEVEL_4", property = "orgLevel4") List getTasksCountForStatusGroupedByOrgLevel( + @Param("now") Instant now, @Param("status") TaskTimestamp status, @Param("classificationCategories") List classificationCategories, @Param("classificationIds") List classificationIds, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationCategoryReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationCategoryReportBuilderImpl.java index 3b189493f..39c76ef9c 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationCategoryReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationCategoryReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +46,7 @@ public class ClassificationCategoryReportBuilderImpl ClassificationCategoryReport report = new ClassificationCategoryReport(this.columnHeaders); List monitorQueryItems = this.monitorMapper.getTaskCountOfCategories( + Instant.now(), this.workbasketIds, this.states, this.classificationCategory, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationReportBuilderImpl.java index 179b6136b..84f10ef60 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/ClassificationReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -55,6 +56,7 @@ public class ClassificationReportBuilderImpl ClassificationReport report = new ClassificationReport(this.columnHeaders); List monitorQueryItems = this.monitorMapper.getTaskCountOfClassifications( + Instant.now(), this.workbasketIds, this.states, this.classificationCategory, @@ -104,6 +106,7 @@ public class ClassificationReportBuilderImpl DetailedClassificationReport report = new DetailedClassificationReport(this.columnHeaders); List detailedMonitorQueryItems = this.monitorMapper.getTaskCountOfDetailedClassifications( + Instant.now(), this.workbasketIds, this.states, this.classificationCategory, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TaskCustomFieldValueReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TaskCustomFieldValueReportBuilderImpl.java index c92e14710..ca9eaf8a7 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TaskCustomFieldValueReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TaskCustomFieldValueReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -51,6 +52,7 @@ public class TaskCustomFieldValueReportBuilderImpl TaskCustomFieldValueReport report = new TaskCustomFieldValueReport(this.columnHeaders); List monitorQueryItems = this.monitorMapper.getTaskCountOfTaskCustomFieldValues( + Instant.now(), this.taskCustomField, this.workbasketIds, this.states, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java index 16ff4ed3b..b3dc0ebb8 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimeIntervalReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -146,6 +147,7 @@ abstract class TimeIntervalReportBuilderImpl< selectedItems = convertWorkingDaysToDays(selectedItems, this.columnHeaders); } return this.monitorMapper.getTaskIdsForSelectedItems( + Instant.now(), this.workbasketIds, this.states, this.classificationCategory, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimestampReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimestampReportBuilderImpl.java index 07a5bbf88..443dc71fa 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimestampReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/TimestampReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -99,6 +100,7 @@ public class TimestampReportBuilderImpl private List getTasksCountForStatusGroupedByOrgLevel(TaskTimestamp s) { return monitorMapper.getTasksCountForStatusGroupedByOrgLevel( + Instant.now(), s, classificationCategory, classificationIds, diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketReportBuilderImpl.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketReportBuilderImpl.java index 453ec59d6..ac932ec31 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketReportBuilderImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/internal/reports/WorkbasketReportBuilderImpl.java @@ -1,5 +1,6 @@ package pro.taskana.monitor.internal.reports; +import java.time.Instant; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -51,6 +52,7 @@ public class WorkbasketReportBuilderImpl WorkbasketReport report = new WorkbasketReport(this.columnHeaders); List monitorQueryItems = this.monitorMapper.getTaskCountOfWorkbaskets( + Instant.now(), this.workbasketIds, this.states, this.classificationCategory, diff --git a/lib/taskana-core/src/test/java/pro/taskana/ArchitectureTest.java b/lib/taskana-core/src/test/java/pro/taskana/ArchitectureTest.java index b465b7cf5..68bc54497 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/ArchitectureTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/ArchitectureTest.java @@ -7,17 +7,26 @@ import static com.tngtech.archunit.library.GeneralCodingRules.NO_CLASSES_SHOULD_ import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices; import static org.assertj.core.api.Assertions.assertThat; +import com.tngtech.archunit.base.Optional; import com.tngtech.archunit.core.domain.JavaClass; import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.domain.JavaMethod; import com.tngtech.archunit.core.importer.ClassFileImporter; import com.tngtech.archunit.lang.ArchCondition; import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.ConditionEvents; import com.tngtech.archunit.lang.SimpleConditionEvent; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Insert; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; @@ -109,22 +118,7 @@ class ArchitectureTest { ) .map(Pattern::compile) .collect(Collectors.toList()); - ArchCondition condition = - new ArchCondition("all be defined in TASKANA_SUB_PACKAGES") { - @Override - public void check(JavaClass item, ConditionEvents events) { - if (TASKANA_SUB_PACKAGES.stream().noneMatch(p -> item.getPackageName().startsWith(p)) - && excludePackages.stream() - .noneMatch(p -> p.matcher(item.getPackageName()).matches())) { - String message = - String.format( - "Package '%s' was not declared in TASKANA_SUB_PACKAGES", - item.getPackageName()); - events.add(SimpleConditionEvent.violated(item, message)); - } - } - }; - ArchRule myRule = classes().should(condition); + ArchRule myRule = classes().should(beDefinedInTaskanaSubPackages(excludePackages)); myRule.check(importedClasses); } @@ -220,4 +214,83 @@ class ArchitectureTest { .because("we consistently want to use assertj in our tests"); rule.check(importedClasses); } + + @Test + void mapperClassesShouldNotUseCurrentTimestampSqlFunction() { + ArchRule rule = + classes() + .that() + .haveSimpleNameEndingWith("Mapper") + .should(notUseCurrentTimestampSqlFunction()); + + rule.check(importedClasses); + } + + private static ArchCondition beDefinedInTaskanaSubPackages( + List excludePackages) { + return new ArchCondition<>("all be defined in TASKANA_SUB_PACKAGES") { + @Override + public void check(JavaClass javaClass, ConditionEvents events) { + if (TASKANA_SUB_PACKAGES.stream().noneMatch(p -> javaClass.getPackageName().startsWith(p)) + && excludePackages.stream() + .noneMatch(p -> p.matcher(javaClass.getPackageName()).matches())) { + String message = + String.format( + "Package '%s' was not declared in TASKANA_SUB_PACKAGES", + javaClass.getPackageName()); + events.add(SimpleConditionEvent.violated(javaClass, message)); + } + } + }; + } + + private static ArchCondition notUseCurrentTimestampSqlFunction() { + Function> getSqlStringsFromMethod = + (method) -> { + List values = new ArrayList<>(); + final Optional