Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
|
44e11c37b8 | |
|
3812e9e883 | |
|
9d329c5a83 | |
|
4793aab361 | |
|
92c374e9e4 | |
|
fb92a4df80 | |
|
d7bc392c97 | |
|
e9164c6334 | |
|
4812ee1801 |
|
@ -7,8 +7,7 @@ on:
|
|||
tags:
|
||||
- v[0-9]+\.[0-9]+\.[0-9]+
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
JAVA_VERSION: 11
|
||||
NODE_VERSION: 14.16.0
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>taskana-common-logging</artifactId>
|
||||
|
||||
|
@ -9,9 +9,9 @@
|
|||
<description>The global trace logging implementation</description>
|
||||
|
||||
<parent>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@ -42,6 +42,11 @@
|
|||
<artifactId>assertj-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -14,59 +14,73 @@ import org.aspectj.lang.reflect.MethodSignature;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@NoLogging
|
||||
@Aspect
|
||||
public class LoggingAspect {
|
||||
|
||||
public static final String ENABLE_LOGGING_ASPECT_PROPERTY_KEY = "enableLoggingAspect";
|
||||
private static final Map<String, Logger> CLASS_TO_LOGGER = new ConcurrentHashMap<>();
|
||||
|
||||
@Pointcut(
|
||||
"!@annotation(pro.taskana.common.internal.logging.NoLogging)"
|
||||
+ " && execution(* *(..))"
|
||||
+ " && !within(@pro.taskana.common.internal.logging.NoLogging *)"
|
||||
+ " && execution(* pro.taskana..*(..))"
|
||||
+ " && !execution(* lambda*(..))"
|
||||
+ " && !execution(* access*(..))"
|
||||
+ " && !execution(String *.toString())"
|
||||
+ " && !execution(int *.hashCode())"
|
||||
+ " && !execution(boolean *.canEqual(Object))"
|
||||
+ " && !execution(boolean *.equals(Object))")
|
||||
public void traceLogging() {}
|
||||
|
||||
// This method exists, so that we can mock the system property during testing.
|
||||
public static String getLoggingAspectEnabledPropertyValue() {
|
||||
return LazyHolder.ENABLE_LOGGING_ASPECT_PROPERTY_VALUE;
|
||||
}
|
||||
|
||||
@Before("traceLogging()")
|
||||
public void beforeMethodExecuted(JoinPoint joinPoint) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
String declaringTypeName = methodSignature.getDeclaringTypeName();
|
||||
Logger currentLogger =
|
||||
CLASS_TO_LOGGER.computeIfAbsent(declaringTypeName, LoggerFactory::getLogger);
|
||||
if ("true".equals(getLoggingAspectEnabledPropertyValue())) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
String declaringTypeName = methodSignature.getDeclaringTypeName();
|
||||
Logger currentLogger =
|
||||
CLASS_TO_LOGGER.computeIfAbsent(declaringTypeName, LoggerFactory::getLogger);
|
||||
|
||||
if (currentLogger.isTraceEnabled()) {
|
||||
String methodName = methodSignature.getName();
|
||||
Object[] values = joinPoint.getArgs();
|
||||
String[] parameterNames = methodSignature.getParameterNames();
|
||||
String parametersValues = mapParametersNameValue(parameterNames, values);
|
||||
if (currentLogger.isTraceEnabled()) {
|
||||
String methodName = methodSignature.getName();
|
||||
Object[] values = joinPoint.getArgs();
|
||||
String[] parameterNames = methodSignature.getParameterNames();
|
||||
String parametersValues = mapParametersNameValue(parameterNames, values);
|
||||
|
||||
currentLogger.trace("entry to {}({})", methodName, parametersValues);
|
||||
currentLogger.trace("entry to {}({})", methodName, parametersValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AfterReturning(pointcut = "traceLogging()", returning = "returnedObject")
|
||||
public void afterMethodExecuted(JoinPoint joinPoint, Object returnedObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
String declaringTypeName = methodSignature.getDeclaringTypeName();
|
||||
Logger currentLogger =
|
||||
CLASS_TO_LOGGER.computeIfAbsent(declaringTypeName, LoggerFactory::getLogger);
|
||||
if ("true".equals(getLoggingAspectEnabledPropertyValue())) {
|
||||
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
||||
String declaringTypeName = methodSignature.getDeclaringTypeName();
|
||||
Logger currentLogger =
|
||||
CLASS_TO_LOGGER.computeIfAbsent(declaringTypeName, LoggerFactory::getLogger);
|
||||
|
||||
if (currentLogger.isTraceEnabled()) {
|
||||
String methodName = methodSignature.getName();
|
||||
// unfortunately necessary, because this method returns a raw type
|
||||
Class<?> returnType = methodSignature.getReturnType();
|
||||
if (returnType.isAssignableFrom(void.class)) {
|
||||
currentLogger.trace("exit from {}.", methodName);
|
||||
} else {
|
||||
currentLogger.trace(
|
||||
"exit from {}. Returning: '{}'", methodName, Objects.toString(returnedObject, "null"));
|
||||
if (currentLogger.isTraceEnabled()) {
|
||||
String methodName = methodSignature.getName();
|
||||
// unfortunately necessary, because this method returns a raw type
|
||||
Class<?> returnType = methodSignature.getReturnType();
|
||||
if (returnType.isAssignableFrom(void.class)) {
|
||||
currentLogger.trace("exit from {}.", methodName);
|
||||
} else {
|
||||
currentLogger.trace(
|
||||
"exit from {}. Returning: '{}'",
|
||||
methodName,
|
||||
Objects.toString(returnedObject, "null"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NoLogging
|
||||
private static String mapParametersNameValue(String[] parameterNames, Object[] values) {
|
||||
Map<String, Object> parametersNameToValue = new HashMap<>();
|
||||
|
||||
|
@ -82,4 +96,13 @@ public class LoggingAspect {
|
|||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
// This Initialization-on-demand holder idiom is necessary so that the retrieval of the system
|
||||
// property will be executed during the execution of the first JointPoint.
|
||||
// This allows us to set the system property during test execution BEFORE retrieving the system
|
||||
// property.
|
||||
private static class LazyHolder {
|
||||
private static final String ENABLE_LOGGING_ASPECT_PROPERTY_VALUE =
|
||||
System.getProperty(ENABLE_LOGGING_ASPECT_PROPERTY_KEY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package outside.of.pro.staskana;
|
||||
|
||||
public class OutsideOfProTaskanaPackageLoggingTestClass {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void doStuff() {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package pro.taskana;
|
||||
|
||||
public class AtProTaskanaRootPackageLoggingTestClass {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void doStuff() {}
|
||||
}
|
|
@ -3,80 +3,136 @@ package pro.taskana.common.internal.logging;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.assertj.core.api.Condition;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.internal.stubbing.answers.CallsRealMethods;
|
||||
import outside.of.pro.staskana.OutsideOfProTaskanaPackageLoggingTestClass;
|
||||
import uk.org.lidalia.slf4jext.Level;
|
||||
import uk.org.lidalia.slf4jtest.LoggingEvent;
|
||||
import uk.org.lidalia.slf4jtest.TestLogger;
|
||||
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
|
||||
|
||||
class LoggingAspectTest {
|
||||
import pro.taskana.AtProTaskanaRootPackageLoggingTestClass;
|
||||
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(LoggingTestClass.class);
|
||||
@NoLogging
|
||||
class LoggingAspectTest {
|
||||
|
||||
@BeforeEach
|
||||
public void clearLoggers() {
|
||||
TestLoggerFactory.clear();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
System.setProperty(LoggingAspect.ENABLE_LOGGING_ASPECT_PROPERTY_KEY, "true");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_Log_For_InternalMethod() {
|
||||
void should_NotLogMethodCalls_When_ClassDoesNotResideWithinTaskanaPackage() {
|
||||
OutsideOfProTaskanaPackageLoggingTestClass loggingTestClass =
|
||||
new OutsideOfProTaskanaPackageLoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.doStuff();
|
||||
|
||||
assertThat(logger.getLoggingEvents()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_LogMethod_When_ClassResidesAtTaskanaRootPackage() {
|
||||
AtProTaskanaRootPackageLoggingTestClass loggingTestClass =
|
||||
new AtProTaskanaRootPackageLoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.doStuff();
|
||||
|
||||
verifyLoggingStatement(logger, "doStuff", "", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_LogInternalMethod_When_ClassResidesAtTaskanaSubPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethod();
|
||||
|
||||
verifyLoggingStatement("logInternalMethod", "", null);
|
||||
verifyLoggingStatement(logger, "logInternalMethod", "", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_Log_For_InternalMethodWithReturnValue() {
|
||||
void should_NotLogInternalMethod_When_SystemPropertyIsNotSet() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
try (MockedStatic<LoggingAspect> loggingAspectMockedStatic =
|
||||
Mockito.mockStatic(LoggingAspect.class, new CallsRealMethods())) {
|
||||
loggingAspectMockedStatic
|
||||
.when(LoggingAspect::getLoggingAspectEnabledPropertyValue)
|
||||
.thenReturn("");
|
||||
|
||||
loggingTestClass.logInternalMethod();
|
||||
}
|
||||
assertThat(logger.getLoggingEvents()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_LogInternalMethodWithReturnValue_When_ClassResidesAtTaskanaSubPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethodWithReturnValue();
|
||||
|
||||
verifyLoggingStatement("logInternalMethodWithReturnValue", "", "test string");
|
||||
verifyLoggingStatement(logger, "logInternalMethodWithReturnValue", "", "test string");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_Log_For_InternalMethodWithReturnValueNull() {
|
||||
void should_LogInternalMethodWithReturnValueNull_When_ClassResidesAtTaskanaSubPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethodWithReturnValueNull();
|
||||
|
||||
verifyLoggingStatement("logInternalMethodWithReturnValueNull", "", "null");
|
||||
verifyLoggingStatement(logger, "logInternalMethodWithReturnValueNull", "", "null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_Log_For_InternalMethodWithArguments() {
|
||||
void should_LogInternalMethodWithArguments_When_ClassResidesAtTaskanaSubPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethodWithArguments("message");
|
||||
|
||||
verifyLoggingStatement("logInternalMethodWithArguments", "param = message", null);
|
||||
verifyLoggingStatement(logger, "logInternalMethodWithArguments", "param = message", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_Log_For_InternalMethodWithReturnValueAndArguments() {
|
||||
void should_LogInternalMethodWithReturnValueAndArguments_When_ClassResidesAtTaskanaSubPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethodWithReturnValueAndArguments("message");
|
||||
|
||||
verifyLoggingStatement(
|
||||
"logInternalMethodWithReturnValueAndArguments", "param = message", "return value");
|
||||
logger, "logInternalMethodWithReturnValueAndArguments", "param = message", "return value");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_NotLog_For_ExternalMethod() {
|
||||
void should_NotLogExternalMethod_When_AMethodCallsAMethodOutsideOfTaskanaPackage() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.callsExternalMethod();
|
||||
|
||||
verifyLoggingStatement("callsExternalMethod", "", null);
|
||||
verifyLoggingStatement(logger, "callsExternalMethod", "", null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_LogMultipleMethods_When_SubMethodIsCalled() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.logInternalMethodWrapper();
|
||||
assertThat(logger.getLoggingEvents())
|
||||
|
@ -88,6 +144,7 @@ class LoggingAspectTest {
|
|||
@Test
|
||||
void should_NotLogInternalMethod_When_MethodIsAnnotatedWithNoLogging() {
|
||||
LoggingTestClass loggingTestClass = new LoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(loggingTestClass.getClass());
|
||||
|
||||
loggingTestClass.doNotLogInternalMethod();
|
||||
|
||||
|
@ -97,6 +154,7 @@ class LoggingAspectTest {
|
|||
@Test
|
||||
void should_NotLogInternalMethod_When_ClassIsAnnotatedWithNoLogging() {
|
||||
NoLoggingTestClass noLoggingTestClass = new NoLoggingTestClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(noLoggingTestClass.getClass());
|
||||
|
||||
noLoggingTestClass.doNotLogInternalMethod();
|
||||
|
||||
|
@ -106,13 +164,15 @@ class LoggingAspectTest {
|
|||
@Test
|
||||
void should_NotLogInternalMethod_When_SuperClassIsAnnotatedWithNoLogging() {
|
||||
NoLoggingTestSubClass noLoggingTestSubClass = new NoLoggingTestSubClass();
|
||||
TestLogger logger = TestLoggerFactory.getTestLogger(noLoggingTestSubClass.getClass());
|
||||
|
||||
noLoggingTestSubClass.doNotLogInternalMethod();
|
||||
|
||||
assertThat(logger.getLoggingEvents()).isEmpty();
|
||||
}
|
||||
|
||||
private void verifyLoggingStatement(String methodName, String arguments, Object returnValue) {
|
||||
private void verifyLoggingStatement(
|
||||
TestLogger logger, String methodName, String arguments, Object returnValue) {
|
||||
assertThat(logger.getLoggingEvents()).hasSize(2);
|
||||
LoggingEvent entryLoggingEvent = logger.getLoggingEvents().get(0);
|
||||
assertThat(entryLoggingEvent.getLevel()).isEqualTo(Level.TRACE);
|
||||
|
@ -131,47 +191,4 @@ class LoggingAspectTest {
|
|||
assertThat(exitLoggingEvent.getArguments()).containsExactly(methodName, returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
static class LoggingTestClass {
|
||||
public void logInternalMethod() {}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
String logInternalMethodWithReturnValue() {
|
||||
return "test string";
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public String logInternalMethodWithReturnValueNull() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void logInternalMethodWithArguments(String param) {}
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public String logInternalMethodWithReturnValueAndArguments(String param) {
|
||||
return "return value";
|
||||
}
|
||||
|
||||
public void logInternalMethodWrapper() {
|
||||
logInternalMethodPrivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void callsExternalMethod() {
|
||||
String sum = String.valueOf(5);
|
||||
}
|
||||
|
||||
@NoLogging
|
||||
public void doNotLogInternalMethod() {}
|
||||
|
||||
private void logInternalMethodPrivate() {}
|
||||
}
|
||||
|
||||
@NoLogging
|
||||
static class NoLoggingTestClass {
|
||||
public void doNotLogInternalMethod() {}
|
||||
}
|
||||
|
||||
static class NoLoggingTestSubClass extends NoLoggingTestClass {}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package pro.taskana.common.internal.logging;
|
||||
|
||||
class LoggingTestClass {
|
||||
|
||||
public void logInternalMethod() {}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public String logInternalMethodWithReturnValue() {
|
||||
return "test string";
|
||||
}
|
||||
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
public String logInternalMethodWithReturnValueNull() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void logInternalMethodWithArguments(String param) {}
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public String logInternalMethodWithReturnValueAndArguments(String param) {
|
||||
return "return value";
|
||||
}
|
||||
|
||||
public void logInternalMethodWrapper() {
|
||||
logInternalMethodPrivate();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void callsExternalMethod() {
|
||||
String sum = String.valueOf(5);
|
||||
}
|
||||
|
||||
@NoLogging
|
||||
public void doNotLogInternalMethod() {}
|
||||
|
||||
private void logInternalMethodPrivate() {}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package pro.taskana.common.internal.logging;
|
||||
|
||||
@NoLogging
|
||||
class NoLoggingTestClass {
|
||||
|
||||
public void doNotLogInternalMethod() {}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package pro.taskana.common.internal.logging;
|
||||
|
||||
class NoLoggingTestSubClass extends NoLoggingTestClass {}
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-common-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -12,15 +12,16 @@ import pro.taskana.common.api.exceptions.SystemException;
|
|||
|
||||
public class SecurityVerifier {
|
||||
|
||||
public static final String SECURITY_FLAG_COLUMN_NAME = "ENFORCE_SECURITY";
|
||||
public static final String INSERT_SECURITY_FLAG_SQL =
|
||||
"INSERT INTO %s.CONFIGURATION (" + SECURITY_FLAG_COLUMN_NAME + ") VALUES (%b)";
|
||||
public static final String SELECT_SECURITY_FLAG_SQL = "SELECT %s FROM %s.CONFIGURATION";
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityVerifier.class);
|
||||
private static final String SECURITY_FLAG_COLUMN_NAME = "ENFORCE_SECURITY";
|
||||
private static final String INSERT_SECURITY_FLAG = "INSERT INTO %s.CONFIGURATION VALUES (%b)";
|
||||
private static final String SELECT_SECURITY_FLAG = "SELECT %s FROM %s.CONFIGURATION";
|
||||
private final String schemaName;
|
||||
private final DataSource dataSource;
|
||||
|
||||
public SecurityVerifier(DataSource dataSource, String schema) {
|
||||
super();
|
||||
this.dataSource = dataSource;
|
||||
this.schemaName = schema;
|
||||
}
|
||||
|
@ -35,7 +36,7 @@ public class SecurityVerifier {
|
|||
SqlRunner sqlRunner = new SqlRunner(connection);
|
||||
|
||||
String querySecurity =
|
||||
String.format(SELECT_SECURITY_FLAG, SECURITY_FLAG_COLUMN_NAME, schemaName);
|
||||
String.format(SELECT_SECURITY_FLAG_SQL, SECURITY_FLAG_COLUMN_NAME, schemaName);
|
||||
|
||||
if ((boolean) sqlRunner.selectOne(querySecurity).get(SECURITY_FLAG_COLUMN_NAME)
|
||||
&& !securityEnabled) {
|
||||
|
@ -65,7 +66,8 @@ public class SecurityVerifier {
|
|||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
|
||||
String setSecurityFlagSql = String.format(INSERT_SECURITY_FLAG, schemaName, securityEnabled);
|
||||
String setSecurityFlagSql =
|
||||
String.format(INSERT_SECURITY_FLAG_SQL, schemaName, securityEnabled);
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(setSecurityFlagSql)) {
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana.history</groupId>
|
||||
<artifactId>taskana-history-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana.history</groupId>
|
||||
<artifactId>taskana-history-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana.history</groupId>
|
||||
<artifactId>taskana-history-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package pro.taskana.task.internal;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
|
@ -81,7 +82,7 @@ public interface AttachmentMapper {
|
|||
@Result(property = "channel", column = "CHANNEL")
|
||||
@Result(property = "received", column = "RECEIVED")
|
||||
List<AttachmentSummaryImpl> findAttachmentSummariesByTaskIds(
|
||||
@Param("taskIds") List<String> taskIds);
|
||||
@Param("taskIds") Collection<String> taskIds);
|
||||
|
||||
@Delete("DELETE FROM ATTACHMENT WHERE ID=#{attachmentId}")
|
||||
void delete(@Param("attachmentId") String attachmentId);
|
||||
|
|
|
@ -6,13 +6,13 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -59,6 +59,7 @@ import pro.taskana.task.api.exceptions.TaskCommentNotFoundException;
|
|||
import pro.taskana.task.api.exceptions.TaskNotFoundException;
|
||||
import pro.taskana.task.api.exceptions.UpdateFailedException;
|
||||
import pro.taskana.task.api.models.Attachment;
|
||||
import pro.taskana.task.api.models.AttachmentSummary;
|
||||
import pro.taskana.task.api.models.ObjectReference;
|
||||
import pro.taskana.task.api.models.Task;
|
||||
import pro.taskana.task.api.models.TaskComment;
|
||||
|
@ -274,7 +275,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
@Override
|
||||
public Task getTask(String id) throws NotAuthorizedException, TaskNotFoundException {
|
||||
TaskImpl resultTask = null;
|
||||
TaskImpl resultTask;
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
|
||||
|
@ -302,18 +303,13 @@ public class TaskServiceImpl implements TaskService {
|
|||
attachmentImpls = new ArrayList<>();
|
||||
}
|
||||
|
||||
List<ClassificationSummary> classifications;
|
||||
classifications = findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls);
|
||||
List<Attachment> attachments =
|
||||
addClassificationSummariesToAttachments(attachmentImpls, classifications);
|
||||
resultTask.setAttachments(attachments);
|
||||
Map<String, ClassificationSummary> classificationSummariesById =
|
||||
findClassificationForTaskImplAndAttachments(resultTask, attachmentImpls);
|
||||
addClassificationSummariesToAttachments(attachmentImpls, classificationSummariesById);
|
||||
resultTask.setAttachments(new ArrayList<>(attachmentImpls));
|
||||
|
||||
String classificationId = resultTask.getClassificationSummary().getId();
|
||||
ClassificationSummary classification =
|
||||
classifications.stream()
|
||||
.filter(c -> c.getId().equals(classificationId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
ClassificationSummary classification = classificationSummariesById.get(classificationId);
|
||||
if (classification == null) {
|
||||
throw new SystemException(
|
||||
"Could not find a Classification for task " + resultTask.getId());
|
||||
|
@ -346,7 +342,7 @@ public class TaskServiceImpl implements TaskService {
|
|||
@Override
|
||||
public Task setTaskRead(String taskId, boolean isRead)
|
||||
throws TaskNotFoundException, NotAuthorizedException {
|
||||
TaskImpl task = null;
|
||||
TaskImpl task;
|
||||
try {
|
||||
taskanaEngine.openConnection();
|
||||
task = (TaskImpl) getTask(taskId);
|
||||
|
@ -942,8 +938,8 @@ public class TaskServiceImpl implements TaskService {
|
|||
|
||||
private List<TaskSummaryImpl> augmentTaskSummariesByContainedSummariesWithoutPartitioning(
|
||||
List<TaskSummaryImpl> taskSummaries) {
|
||||
List<String> taskIds =
|
||||
taskSummaries.stream().map(TaskSummaryImpl::getId).distinct().collect(Collectors.toList());
|
||||
Set<String> taskIds =
|
||||
taskSummaries.stream().map(TaskSummaryImpl::getId).collect(Collectors.toSet());
|
||||
|
||||
if (taskIds.isEmpty()) {
|
||||
taskIds = null;
|
||||
|
@ -955,15 +951,17 @@ public class TaskServiceImpl implements TaskService {
|
|||
+ "about to query for attachmentSummaries ",
|
||||
taskSummaries);
|
||||
}
|
||||
|
||||
List<AttachmentSummaryImpl> attachmentSummaries =
|
||||
attachmentMapper.findAttachmentSummariesByTaskIds(taskIds);
|
||||
|
||||
List<ClassificationSummary> classifications =
|
||||
Map<String, ClassificationSummary> classificationSummariesById =
|
||||
findClassificationsForTasksAndAttachments(taskSummaries, attachmentSummaries);
|
||||
Map<String, WorkbasketSummary> workbasketSummariesById = findWorkbasketsForTasks(taskSummaries);
|
||||
|
||||
addClassificationSummariesToTaskSummaries(taskSummaries, classifications);
|
||||
addWorkbasketSummariesToTaskSummaries(taskSummaries);
|
||||
addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries, classifications);
|
||||
addClassificationSummariesToAttachments(attachmentSummaries, classificationSummariesById);
|
||||
addClassificationSummariesToTaskSummaries(taskSummaries, classificationSummariesById);
|
||||
addWorkbasketSummariesToTaskSummaries(taskSummaries, workbasketSummariesById);
|
||||
addAttachmentSummariesToTaskSummaries(taskSummaries, attachmentSummaries);
|
||||
|
||||
return taskSummaries;
|
||||
}
|
||||
|
@ -1522,192 +1520,159 @@ public class TaskServiceImpl implements TaskService {
|
|||
}
|
||||
}
|
||||
|
||||
private Map<String, WorkbasketSummary> findWorkbasketsForTasks(
|
||||
List<? extends TaskSummary> taskSummaries) {
|
||||
if (taskSummaries == null || taskSummaries.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> workbasketIds =
|
||||
taskSummaries.stream()
|
||||
.map(TaskSummary::getWorkbasketSummary)
|
||||
.map(WorkbasketSummary::getId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return queryWorkbasketsForTasks(workbasketIds).stream()
|
||||
.collect(Collectors.toMap(WorkbasketSummary::getId, Function.identity()));
|
||||
}
|
||||
|
||||
private Map<String, ClassificationSummary> findClassificationsForTasksAndAttachments(
|
||||
List<? extends TaskSummary> taskSummaries,
|
||||
List<? extends AttachmentSummaryImpl> attachmentSummaries) {
|
||||
if (taskSummaries == null || taskSummaries.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> classificationIds =
|
||||
Stream.concat(
|
||||
taskSummaries.stream().map(TaskSummary::getClassificationSummary),
|
||||
attachmentSummaries.stream().map(AttachmentSummary::getClassificationSummary))
|
||||
.map(ClassificationSummary::getId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return queryClassificationsForTasksAndAttachments(classificationIds).stream()
|
||||
.collect(Collectors.toMap(ClassificationSummary::getId, Function.identity()));
|
||||
}
|
||||
|
||||
private Map<String, ClassificationSummary> findClassificationForTaskImplAndAttachments(
|
||||
TaskImpl task, List<AttachmentImpl> attachmentImpls) {
|
||||
return findClassificationsForTasksAndAttachments(
|
||||
Collections.singletonList(task), attachmentImpls);
|
||||
}
|
||||
|
||||
private List<ClassificationSummary> queryClassificationsForTasksAndAttachments(
|
||||
Set<String> classificationIds) {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"queryClassificationsForTasksAndAttachments() about to query classifications and exit");
|
||||
}
|
||||
return this.classificationService
|
||||
.createClassificationQuery()
|
||||
.idIn(classificationIds.toArray(new String[0]))
|
||||
.list();
|
||||
}
|
||||
|
||||
private List<WorkbasketSummary> queryWorkbasketsForTasks(Set<String> workbasketIds) {
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("queryWorkbasketsForTasks() about to query workbaskets and exit");
|
||||
}
|
||||
// perform classification query
|
||||
return this.workbasketService
|
||||
.createWorkbasketQuery()
|
||||
.idIn(workbasketIds.toArray(new String[0]))
|
||||
.list();
|
||||
}
|
||||
|
||||
private void addClassificationSummariesToTaskSummaries(
|
||||
List<TaskSummaryImpl> tasks, List<ClassificationSummary> classifications) {
|
||||
List<TaskSummaryImpl> tasks, Map<String, ClassificationSummary> classificationSummaryById) {
|
||||
|
||||
if (tasks == null || tasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// assign query results to appropriate tasks.
|
||||
|
||||
for (TaskSummaryImpl task : tasks) {
|
||||
String classificationId = task.getClassificationSummary().getId();
|
||||
ClassificationSummary classificationSummary =
|
||||
classifications.stream()
|
||||
.filter(c -> c.getId().equals(classificationId))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
ClassificationSummary classificationSummary = classificationSummaryById.get(classificationId);
|
||||
if (classificationSummary == null) {
|
||||
throw new SystemException(
|
||||
"Did not find a Classification for task (Id="
|
||||
+ task.getId()
|
||||
+ ",classification="
|
||||
+ ",Classification="
|
||||
+ task.getClassificationSummary().getId()
|
||||
+ ")");
|
||||
}
|
||||
// set the classification on the task object
|
||||
task.setClassificationSummary(classificationSummary);
|
||||
}
|
||||
}
|
||||
|
||||
private List<ClassificationSummary> findClassificationsForTasksAndAttachments(
|
||||
List<TaskSummaryImpl> taskSummaries, List<AttachmentSummaryImpl> attachmentSummaries) {
|
||||
if (taskSummaries == null || taskSummaries.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
Set<String> classificationIdSet =
|
||||
taskSummaries.stream()
|
||||
.map(t -> t.getClassificationSummary().getId())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (attachmentSummaries != null && !attachmentSummaries.isEmpty()) {
|
||||
for (AttachmentSummaryImpl att : attachmentSummaries) {
|
||||
classificationIdSet.add(att.getClassificationSummary().getId());
|
||||
}
|
||||
}
|
||||
return queryClassificationsForTasksAndAttachments(classificationIdSet);
|
||||
}
|
||||
|
||||
private List<ClassificationSummary> findClassificationForTaskImplAndAttachments(
|
||||
TaskImpl task, List<AttachmentImpl> attachmentImpls) {
|
||||
Set<String> classificationIdSet =
|
||||
new HashSet<>(Collections.singletonList(task.getClassificationSummary().getId()));
|
||||
if (attachmentImpls != null && !attachmentImpls.isEmpty()) {
|
||||
for (AttachmentImpl att : attachmentImpls) {
|
||||
classificationIdSet.add(att.getClassificationSummary().getId());
|
||||
}
|
||||
}
|
||||
return queryClassificationsForTasksAndAttachments(classificationIdSet);
|
||||
}
|
||||
|
||||
private List<ClassificationSummary> queryClassificationsForTasksAndAttachments(
|
||||
Set<String> classificationIdSet) {
|
||||
|
||||
String[] classificationIdArray = classificationIdSet.toArray(new String[0]);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"getClassificationsForTasksAndAttachments() about to query classifications and exit");
|
||||
}
|
||||
// perform classification query
|
||||
return this.classificationService
|
||||
.createClassificationQuery()
|
||||
.idIn(classificationIdArray)
|
||||
.list();
|
||||
}
|
||||
|
||||
private void addWorkbasketSummariesToTaskSummaries(List<TaskSummaryImpl> taskSummaries) {
|
||||
if (taskSummaries == null || taskSummaries.isEmpty()) {
|
||||
private void addWorkbasketSummariesToTaskSummaries(
|
||||
List<TaskSummaryImpl> tasks, Map<String, WorkbasketSummary> workbasketSummaryById) {
|
||||
if (tasks == null || tasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// calculate parameters for workbasket query: workbasket keys
|
||||
String[] workbasketIdArray =
|
||||
taskSummaries.stream()
|
||||
.map(t -> t.getWorkbasketSummary().getId())
|
||||
.distinct()
|
||||
.toArray(String[]::new);
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("addWorkbasketSummariesToTaskSummaries() about to query workbaskets");
|
||||
}
|
||||
WorkbasketQueryImpl query = (WorkbasketQueryImpl) workbasketService.createWorkbasketQuery();
|
||||
query.setUsedToAugmentTasks(true);
|
||||
|
||||
List<WorkbasketSummary> workbaskets = query.idIn(workbasketIdArray).list();
|
||||
Iterator<TaskSummaryImpl> taskIterator = taskSummaries.iterator();
|
||||
while (taskIterator.hasNext()) {
|
||||
TaskSummaryImpl task = taskIterator.next();
|
||||
String workbasketId = task.getWorkbasketSummaryImpl().getId();
|
||||
|
||||
WorkbasketSummary workbasketSummary =
|
||||
workbaskets.stream()
|
||||
.filter(x -> workbasketId != null && workbasketId.equals(x.getId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
for (TaskSummaryImpl task : tasks) {
|
||||
String workbasketId = task.getWorkbasketSummary().getId();
|
||||
WorkbasketSummary workbasketSummary = workbasketSummaryById.get(workbasketId);
|
||||
if (workbasketSummary == null) {
|
||||
LOGGER.warn("Could not find a Workbasket for task {}.", task.getId());
|
||||
taskIterator.remove();
|
||||
continue;
|
||||
throw new SystemException(
|
||||
"Did not find a Workbasket for task (Id="
|
||||
+ task.getId()
|
||||
+ ",Workbasket="
|
||||
+ task.getWorkbasketSummary().getId()
|
||||
+ ")");
|
||||
}
|
||||
|
||||
task.setWorkbasketSummary(workbasketSummary);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAttachmentSummariesToTaskSummaries(
|
||||
List<TaskSummaryImpl> taskSummaries,
|
||||
List<AttachmentSummaryImpl> attachmentSummaries,
|
||||
List<ClassificationSummary> classifications) {
|
||||
List<TaskSummaryImpl> taskSummaries, List<AttachmentSummaryImpl> attachmentSummaries) {
|
||||
|
||||
if (taskSummaries == null || taskSummaries.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// augment attachment summaries by classification summaries
|
||||
// Note:
|
||||
// the mapper sets for each Attachment summary the property classificationSummary.key from the
|
||||
// CLASSIFICATION_KEY property in the DB
|
||||
addClassificationSummariesToAttachmentSummaries(
|
||||
attachmentSummaries, taskSummaries, classifications);
|
||||
// assign attachment summaries to task summaries
|
||||
for (TaskSummaryImpl task : taskSummaries) {
|
||||
for (AttachmentSummaryImpl attachment : attachmentSummaries) {
|
||||
if (attachment.getTaskId() != null && attachment.getTaskId().equals(task.getId())) {
|
||||
task.addAttachmentSummary(attachment);
|
||||
}
|
||||
Map<String, TaskSummaryImpl> taskSummariesById =
|
||||
taskSummaries.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
TaskSummary::getId,
|
||||
Function.identity(),
|
||||
// Currently, we still have a bug (TSK-1204), where the TaskQuery#list function
|
||||
// returns the same task multiple times when that task has more than one
|
||||
// attachment...Therefore, this MergeFunction is necessary.
|
||||
(a, b) -> b));
|
||||
|
||||
for (AttachmentSummaryImpl attachmentSummary : attachmentSummaries) {
|
||||
String taskId = attachmentSummary.getTaskId();
|
||||
TaskSummaryImpl taskSummary = taskSummariesById.get(taskId);
|
||||
if (taskSummary != null) {
|
||||
taskSummary.addAttachmentSummary(attachmentSummary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addClassificationSummariesToAttachmentSummaries(
|
||||
List<AttachmentSummaryImpl> attachmentSummaries,
|
||||
List<TaskSummaryImpl> taskSummaries,
|
||||
List<ClassificationSummary> classifications) {
|
||||
// prereq: in each attachmentSummary, the classificationSummary.key property is set.
|
||||
if (attachmentSummaries == null
|
||||
|| attachmentSummaries.isEmpty()
|
||||
|| taskSummaries == null
|
||||
|| taskSummaries.isEmpty()) {
|
||||
private void addClassificationSummariesToAttachments(
|
||||
List<? extends AttachmentSummaryImpl> attachments,
|
||||
Map<String, ClassificationSummary> classificationSummariesById) {
|
||||
|
||||
if (attachments == null || attachments.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// iterate over all attachment summaries an add the appropriate classification summary to each
|
||||
for (AttachmentSummaryImpl att : attachmentSummaries) {
|
||||
String classificationId = att.getClassificationSummary().getId();
|
||||
|
||||
for (AttachmentSummaryImpl attachment : attachments) {
|
||||
String classificationId = attachment.getClassificationSummary().getId();
|
||||
ClassificationSummary classificationSummary =
|
||||
classifications.stream()
|
||||
.filter(x -> classificationId != null && classificationId.equals(x.getId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (classificationSummary == null) {
|
||||
throw new SystemException("Could not find a Classification for attachment " + att);
|
||||
}
|
||||
att.setClassificationSummary(classificationSummary);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Attachment> addClassificationSummariesToAttachments(
|
||||
List<AttachmentImpl> attachmentImpls, List<ClassificationSummary> classifications) {
|
||||
|
||||
if (attachmentImpls == null || attachmentImpls.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<Attachment> result = new ArrayList<>();
|
||||
for (AttachmentImpl att : attachmentImpls) {
|
||||
// find the associated task to use the correct domain
|
||||
ClassificationSummary classificationSummary =
|
||||
classifications.stream()
|
||||
.filter(c -> c != null && c.getId().equals(att.getClassificationSummary().getId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
classificationSummariesById.get(classificationId);
|
||||
|
||||
if (classificationSummary == null) {
|
||||
throw new SystemException("Could not find a Classification for attachment " + att);
|
||||
throw new SystemException("Could not find a Classification for attachment " + attachment);
|
||||
}
|
||||
att.setClassificationSummary(classificationSummary);
|
||||
result.add(att);
|
||||
attachment.setClassificationSummary(classificationSummary);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private TaskImpl initUpdatedTask(
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.junit.jupiter.api.Test;
|
|||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
||||
import pro.taskana.common.internal.configuration.SecurityVerifier;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
|
||||
class TaskanaSecurityConfigAccTest {
|
||||
|
@ -88,7 +89,9 @@ class TaskanaSecurityConfigAccTest {
|
|||
|
||||
String selectSecurityFlagSql =
|
||||
String.format(
|
||||
"SELECT * FROM %s.CONFIGURATION", TaskanaEngineTestConfiguration.getSchemaName());
|
||||
SecurityVerifier.SELECT_SECURITY_FLAG_SQL,
|
||||
SecurityVerifier.SECURITY_FLAG_COLUMN_NAME,
|
||||
TaskanaEngineTestConfiguration.getSchemaName());
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(selectSecurityFlagSql);
|
||||
|
@ -107,8 +110,9 @@ class TaskanaSecurityConfigAccTest {
|
|||
|
||||
String sql =
|
||||
String.format(
|
||||
"INSERT INTO %s.CONFIGURATION VALUES (%b)",
|
||||
TaskanaEngineTestConfiguration.getSchemaName(), securityFlag);
|
||||
SecurityVerifier.INSERT_SECURITY_FLAG_SQL,
|
||||
TaskanaEngineTestConfiguration.getSchemaName(),
|
||||
securityFlag);
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
statement.execute(sql);
|
||||
|
|
|
@ -136,14 +136,15 @@ class QueryTasksAccTest extends AbstractAccTest {
|
|||
@WithAccessId(user = "admin")
|
||||
@Test
|
||||
void should_SplitTaskListIntoChunksOf32000_When_AugmentingTasksAfterTaskQuery() {
|
||||
MockedStatic<CollectionUtil> listUtilMock = Mockito.mockStatic(CollectionUtil.class);
|
||||
listUtilMock
|
||||
.when(() -> CollectionUtil.partitionBasedOnSize(any(), anyInt()))
|
||||
.thenCallRealMethod();
|
||||
try (MockedStatic<CollectionUtil> listUtilMock = Mockito.mockStatic(CollectionUtil.class)) {
|
||||
listUtilMock
|
||||
.when(() -> CollectionUtil.partitionBasedOnSize(any(), anyInt()))
|
||||
.thenCallRealMethod();
|
||||
|
||||
TASK_SERVICE.createTaskQuery().list();
|
||||
TASK_SERVICE.createTaskQuery().list();
|
||||
|
||||
listUtilMock.verify(() -> CollectionUtil.partitionBasedOnSize(any(), eq(32000)));
|
||||
listUtilMock.verify(() -> CollectionUtil.partitionBasedOnSize(any(), eq(32000)));
|
||||
}
|
||||
}
|
||||
|
||||
@WithAccessId(user = "admin")
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-lib-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -4,7 +4,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>${project.groupId}:${project.artifactId}</name>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-rest-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-rest-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-rest-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-rest-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-routing-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<parent>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-rest-parent</artifactId>
|
||||
<version>4.7.1-SNAPSHOT</version>
|
||||
<version>4.7.4-SNAPSHOT</version>
|
||||
<relativePath>../rest/pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
|
Loading…
Reference in New Issue