TSK-1358: Audit-log for history events

This commit is contained in:
Joerg Heffner 2020-06-29 15:25:04 +02:00 committed by gitgoodjhe
parent 418f37917d
commit a37a859573
24 changed files with 475 additions and 54 deletions

View File

@ -19,6 +19,7 @@
<module>taskana-simplehistory-provider</module>
<module>taskana-simplehistory-rest-spring</module>
<module>taskana-simplehistory-rest-spring-example</module>
</modules>
<module>taskana-loghistory-provider</module>
</modules>
</project>

View File

@ -0,0 +1,70 @@
<?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">
<parent>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-parent</artifactId>
<version>3.2.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-loghistory-provider</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>The taskana history events logging plugin to include in your project.</description>
<dependencies>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${version.jackson-databind}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>uk.org.lidalia</groupId>
<artifactId>slf4j-test</artifactId>
<version>${version.slf4j-test}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,102 @@
package pro.taskana.loghistory.impl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.spi.history.api.TaskanaHistory;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
public class LogfileHistoryServiceProvider implements TaskanaHistory {
private static final Logger LOGGER = LoggerFactory.getLogger(LogfileHistoryServiceProvider.class);
private static final String TASKANA_PROPERTIES = "/taskana.properties";
private static final String TASKANA_HISTORYLOGGER_NAME = "taskana.historylogger.name";
private static Logger historyLogger;
ObjectMapper objectMapper = new ObjectMapper();
@Override
public void initialize(TaskanaEngine taskanaEngine) {
objectMapper.registerModule(new JavaTimeModule());
String historyLoggerName =
readPropertiesFromFile(TASKANA_PROPERTIES).getProperty(TASKANA_HISTORYLOGGER_NAME);
if (historyLoggerName != null) {
historyLogger = LoggerFactory.getLogger(historyLoggerName);
} else {
historyLogger = LOGGER;
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"LogfileHistoryServiceProvider initialized with name: {} ", historyLogger.getName());
}
}
@Override
public void create(TaskanaHistoryEvent event) {
try {
if (historyLogger.isInfoEnabled()) {
historyLogger.info(objectMapper.writeValueAsString(event));
}
} catch (JsonProcessingException e) {
throw new SystemException("Caught exception while serializing history event to JSON ", e);
}
}
@Override
public void deleteHistoryEventsByTaskIds(List<String> taskIds) {
throw new UnsupportedOperationException("HistoryLogger is not supposed to delete events");
}
private Properties readPropertiesFromFile(String propertiesFile) {
java.util.Properties props = new Properties();
boolean loadFromClasspath = loadFromClasspath(propertiesFile);
try {
if (loadFromClasspath) {
InputStream inputStream =
TaskanaEngineConfiguration.class.getResourceAsStream(propertiesFile);
if (inputStream == null) {
LOGGER.error("taskana properties file {} was not found on classpath.", propertiesFile);
} else {
props.load(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
LOGGER.debug("properties were loaded from file {} from classpath.", propertiesFile);
}
} else {
props.load(new FileInputStream(propertiesFile));
LOGGER.debug("properties were loaded from file {}.", propertiesFile);
}
} catch (IOException e) {
LOGGER.error("caught IOException when processing properties file {}.", propertiesFile);
throw new SystemException(
"internal System error when processing properties file " + propertiesFile, e.getCause());
}
return props;
}
private boolean loadFromClasspath(String propertiesFile) {
boolean loadFromClasspath = true;
File f = new File(propertiesFile);
if (f.exists() && !f.isDirectory()) {
loadFromClasspath = false;
}
return loadFromClasspath;
}
}

View File

@ -0,0 +1 @@
pro.taskana.loghistory.impl.LogfileHistoryServiceProvider

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<!--
- Abweichungen der Log4j Struktur muessen mit dem Anwendungsbetrieb abgesprochen werden
- SCHEMA_ID, BUSINESS_APPLICATION und GLOBAL_ID werden in ARA gesetzt
- LOG_FOLDER fuer jboss ${sys:jboss.server.log.dir} | fuer weblogic ${env:LOG_PATH}/${SCHEMA_ID} | fuer tomcat ${sys:catalina.base}/logs
-->
<Properties>
<Property name="LOG_FOLDER"></Property>
<Property name="SCHEMA_ID"></Property>
<Property name="BUSINESS_APPLICATION"></Property>
<Property name="GLOBAL_ID"></Property>
<Property name="DOMAIN_ID"></Property>
<Property name="SUBCATEGORIZATION"></Property>
<Property name="SERVICE_ID"></Property>
<Property name="VERSION"></Property>
<Property name="QUALIFIED_SERVICE_NAME"></Property>
</Properties>
<Appenders>
<RollingFile name="auditFileJson"
fileName="_audit.json"
filePattern="${LOG_FOLDER}/${QUALIFIED_SERVICE_NAME}_audit-%d{yyyy-MM-dd}-%i.json">
<JsonLayout compact="true" complete="false" properties="true" locationInfo="true"
propertiesAsList="false" eventEol="true" stacktraceAsString="true">
<KeyValuePair key="datetime" value="$${date:yyyy-MM-dd'T'HH:mm:ss.SSSXXX}" />
<KeyValuePair key="globalId" value="${GLOBAL_ID}" />
<KeyValuePair key="schemaId" value="${SCHEMA_ID}" />
<KeyValuePair key="serviceId" value="${SERVICE_ID}" />
<KeyValuePair key="domainId" value="${DOMAIN_ID}" />
<KeyValuePair key="businessApplication" value="${BUSINESS_APPLICATION}" />
<KeyValuePair key="subcategorization" value="${SUBCATEGORIZATION}" />
<KeyValuePair key="version" value="${VERSION}" />
<KeyValuePair key="logstream" value="audit" />
</JsonLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
<Logger name="AUDIT" level="INFO" additivity="false">
<AppenderRef ref="auditFileJson" />
</Logger>
</Loggers>
</Configuration>

View File

@ -0,0 +1,62 @@
package pro.taskana.loghistory.impl;
import static org.assertj.core.api.Assertions.assertThat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.Instant;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import uk.org.lidalia.slf4jtest.TestLogger;
import uk.org.lidalia.slf4jtest.TestLoggerFactory;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
class LogfileHistoryServiceProviderTest {
static ObjectMapper objectMapper = new ObjectMapper();
LogfileHistoryServiceProvider logfileHistoryServiceProvider = new LogfileHistoryServiceProvider();
TestLogger logger = TestLoggerFactory.getTestLogger("AUDIT");
@Mock TaskanaEngine taskanaEngine;
@AfterAll
public static void clearLoggers() {
TestLoggerFactory.clear();
}
@BeforeAll
public static void setupObjectMapper() {
objectMapper.registerModule(new JavaTimeModule());
}
@Test
void should_LogEventAsJson_When_CreateIsCalled() throws Exception {
logfileHistoryServiceProvider.initialize(taskanaEngine);
TaskanaHistoryEvent eventToBeLogged = new TaskanaHistoryEvent();
eventToBeLogged.setId("someId");
eventToBeLogged.setUserId("someUser");
eventToBeLogged.setEventType("TASK_CREATED");
eventToBeLogged.setDomain("DOMAIN_A");
eventToBeLogged.setCreated(Instant.now());
eventToBeLogged.setNewValue("someNewValue");
eventToBeLogged.setOldValue("someOldValue");
eventToBeLogged.setBusinessProcessId("someBusinessProcessId");
eventToBeLogged.setWorkbasketKey("someWorkbasketKey");
eventToBeLogged.setTaskClassificationKey("someTaskClassificationKey");
eventToBeLogged.setTaskClassificationCategory("someTaskClassificationCategory");
eventToBeLogged.setDetails("someDetails");
logfileHistoryServiceProvider.create(eventToBeLogged);
String logMessage = logger.getLoggingEvents().asList().get(0).getMessage();
TaskanaHistoryEvent deserializedEventFromLogMessage =
objectMapper.readValue(logMessage, TaskanaHistoryEvent.class);
assertThat(eventToBeLogged).isEqualTo(deserializedEventFromLogMessage);
}
}

View File

@ -0,0 +1,20 @@
taskana.roles.user=teamlead-1 | teamlead-2 | user-1-1 | user-1-2 | user-2-1 | user-2-2 | user-b-1 | user-b-2
taskana.roles.admin=admin | uid=admin,cn=users,OU=Test,O=TASKANA
taskana.roles.businessadmin=businessadmin | cn=business-admins,cn=groups,OU=Test,O=TASKANA
taskana.roles.monitor=monitor | cn=monitor-users,cn=groups,OU=Test,O=TASKANA
taskana.roles.taskadmin=taskadmin
taskana.domains=DOMAIN_A,DOMAIN_B,DOMAIN_C
taskana.classification.types=TASK,DOCUMENT
taskana.classification.categories.task= EXTERNAL, manual, autoMAtic, Process
taskana.classification.categories.document= EXTERNAL
taskana.jobs.maxRetries=3
taskana.jobs.batchSize=50
taskana.jobs.cleanup.runEvery=P1D
taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.german.holidays.enabled=true
taskana.german.holidays.corpus-christi.enabled=true
taskana.historylogger.name=AUDIT

View File

@ -68,5 +68,5 @@
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
</project>

View File

@ -7,6 +7,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.TaskanaRole;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
@ -25,14 +26,13 @@ public class SimpleHistoryServiceImpl implements TaskanaHistory {
private HistoryEventMapper historyEventMapper;
private HistoryQueryMapper historyQueryMapper;
@Override
public void initialize(TaskanaEngineConfiguration taskanaEngineConfiguration) {
public void initialize(TaskanaEngine taskanaEngine) {
this.taskanaHistoryEngine = getTaskanaEngine(taskanaEngineConfiguration);
this.taskanaHistoryEngine = getTaskanaEngine(taskanaEngine.getConfiguration());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Simple history service implementation initialized with schemaName: {} ",
taskanaEngineConfiguration.getSchemaName());
taskanaEngine.getConfiguration().getSchemaName());
}
this.historyEventMapper =

View File

@ -54,7 +54,7 @@ public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
public TaskanaHistory getTaskanaHistoryService() {
if (taskanaHistoryService == null) {
SimpleHistoryServiceImpl historyService = new SimpleHistoryServiceImpl();
historyService.initialize(taskanaEngineConfiguration);
historyService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
this.taskanaHistoryService = historyService;
}
return this.taskanaHistoryService;

View File

@ -1 +1 @@
pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl
pro.taskana.simplehistory.impl.SimpleHistoryServiceImpl

View File

@ -94,7 +94,7 @@ public abstract class AbstractAccTest {
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
historyService = new SimpleHistoryServiceImpl();
historyService.initialize(taskanaEngineConfiguration);
historyService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, getSchemaName());
sampleDataGenerator.clearDb();

View File

@ -19,6 +19,7 @@ import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.simplehistory.impl.mappings.HistoryEventMapper;
import pro.taskana.simplehistory.impl.mappings.HistoryQueryMapper;
@ -36,6 +37,8 @@ class SimpleHistoryServiceImplTest {
@Mock private TaskanaEngineConfiguration taskanaEngineConfiguration;
@Mock private TaskanaEngine taskanaEngine;
@Mock private SqlSessionManager sqlSessionManagerMock;
@Test
@ -46,7 +49,11 @@ class SimpleHistoryServiceImplTest {
.thenReturn(historyQueryMapperMock);
when(taskanaHistoryEngineMock.getSqlSession()).thenReturn(sqlSessionManagerMock);
doReturn(taskanaHistoryEngineMock).when(cutSpy).getTaskanaEngine(taskanaEngineConfiguration);
cutSpy.initialize(taskanaEngineConfiguration);
doReturn(taskanaEngine).when(taskanaEngineConfiguration).buildTaskanaEngine();
doReturn(taskanaEngineConfiguration).when(taskanaEngine).getConfiguration();
cutSpy.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
verify(sqlSessionManagerMock, times(2)).getMapper(any());
verify(taskanaHistoryEngineMock, times(2)).getSqlSession();

View File

@ -1,8 +1,8 @@
taskana.roles.user=group1 | group2|teamlead_1 | teamlead_2 |user_1_1| user_1_1| user_1_2| user_2_1| user_2_2| max|elena|simone
taskana.roles.user=teamlead-1 | teamlead-2 | user-1-1 | user-1-2 | user-2-1 | user-2-2 | user-b-1 | user-b-2
taskana.roles.admin=name=konrad,Organisation=novatec|admin
taskana.roles.businessadmin=max|Moritz|businessadmin
taskana.roles.monitor=john|teamlead_2 | monitor
taskana.roles.taskadmin=peter | taskadmin
taskana.roles.businessadmin=businessadmin | cn=business-admins,cn=groups,OU=Test,O=TASKANA
taskana.roles.monitor=monitor | cn=monitor-users,cn=groups,OU=Test,O=TASKANA
taskana.roles.taskadmin=taskadmin
taskana.domains=Domain_A , DOMAIN_B
taskana.classification.types=TASK , document
taskana.classification.categories.task=EXTERNAL, manual, autoMAtic, Process

View File

@ -18,9 +18,9 @@
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-provider</artifactId>
<version>${project.version}</version>
</dependency>
<artifactId>taskana-simplehistory-provider</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring</artifactId>

View File

@ -94,7 +94,7 @@ public class TaskHistoryEventController extends AbstractPagingController {
TaskHistoryEventRepresentationModelAssembler taskHistoryEventRepresentationModelAssembler) {
this.simpleHistoryService = simpleHistoryServiceImpl;
this.simpleHistoryService.initialize(taskanaEngineConfiguration);
this.simpleHistoryService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
this.taskHistoryEventRepresentationModelAssembler =
taskHistoryEventRepresentationModelAssembler;
}

View File

@ -85,7 +85,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
this.sessionManager = createSqlSessionManager();
historyEventManager = HistoryEventManager.getInstance(taskanaEngineConfiguration);
historyEventManager = HistoryEventManager.getInstance(this);
taskRoutingManager = TaskRoutingManager.getInstance(this);
this.internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
workingDaysToDaysConverter =

View File

@ -2,7 +2,7 @@ package pro.taskana.spi.history.api;
import java.util.List;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.spi.history.api.events.TaskanaHistoryEvent;
@ -13,10 +13,9 @@ public interface TaskanaHistory {
/**
* Initialize TaskanaHistory service.
*
* @param taskanaEngineConfiguration {@link TaskanaEngineConfiguration} The Taskana engine
* configuration for needed initialization.
* @param taskanaEngine {@link TaskanaEngine} The Taskana engine for needed initialization.
*/
void initialize(TaskanaEngineConfiguration taskanaEngineConfiguration);
void initialize(TaskanaEngine taskanaEngine);
/**
* Create a new history event.

View File

@ -1,6 +1,7 @@
package pro.taskana.spi.history.api.events;
import java.time.Instant;
import java.util.Objects;
import pro.taskana.common.api.exceptions.SystemException;
@ -234,6 +235,78 @@ public class TaskanaHistoryEvent {
this.details = details;
}
@Override
public int hashCode() {
return Objects.hash(
getId(),
getBusinessProcessId(),
getParentBusinessProcessId(),
getTaskId(),
getEventType(),
getCreated(),
getUserId(),
getDomain(),
getWorkbasketKey(),
getPorCompany(),
getPorSystem(),
getPorInstance(),
getPorType(),
getPorValue(),
getTaskClassificationKey(),
getTaskClassificationCategory(),
getAttachmentClassificationKey(),
getOldValue(),
getNewValue(),
getCustomAttribute(TaskHistoryCustomField.CUSTOM_1),
getCustomAttribute(TaskHistoryCustomField.CUSTOM_2),
getCustomAttribute(TaskHistoryCustomField.CUSTOM_3),
getCustomAttribute(TaskHistoryCustomField.CUSTOM_4),
getDetails());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof TaskanaHistoryEvent)) {
return false;
}
TaskanaHistoryEvent other = (TaskanaHistoryEvent) obj;
return Objects.equals(getId(), other.getId())
&& Objects.equals(getBusinessProcessId(), other.getBusinessProcessId())
&& Objects.equals(getParentBusinessProcessId(), other.getParentBusinessProcessId())
&& Objects.equals(getTaskId(), other.getTaskId())
&& Objects.equals(getEventType(), other.getEventType())
&& Objects.equals(getCreated(), other.getCreated())
&& Objects.equals(getUserId(), other.getUserId())
&& Objects.equals(getDomain(), other.getDomain())
&& Objects.equals(getWorkbasketKey(), other.getWorkbasketKey())
&& Objects.equals(getPorCompany(), other.getPorCompany())
&& Objects.equals(getPorSystem(), other.getPorSystem())
&& Objects.equals(getPorInstance(), other.getPorInstance())
&& Objects.equals(getPorType(), other.getPorType())
&& Objects.equals(getPorValue(), other.getPorValue())
&& Objects.equals(getTaskClassificationKey(), other.getTaskClassificationKey())
&& Objects.equals(getTaskClassificationCategory(), other.getTaskClassificationCategory())
&& Objects.equals(getAttachmentClassificationKey(), other.getAttachmentClassificationKey())
&& Objects.equals(getOldValue(), other.getOldValue())
&& Objects.equals(getNewValue(), other.getNewValue())
&& Objects.equals(
getCustomAttribute(TaskHistoryCustomField.CUSTOM_1),
other.getCustomAttribute(TaskHistoryCustomField.CUSTOM_1))
&& Objects.equals(
getCustomAttribute(TaskHistoryCustomField.CUSTOM_2),
other.getCustomAttribute(TaskHistoryCustomField.CUSTOM_2))
&& Objects.equals(
getCustomAttribute(TaskHistoryCustomField.CUSTOM_3),
other.getCustomAttribute(TaskHistoryCustomField.CUSTOM_3))
&& Objects.equals(
getCustomAttribute(TaskHistoryCustomField.CUSTOM_4),
other.getCustomAttribute(TaskHistoryCustomField.CUSTOM_4))
&& Objects.equals(getDetails(), other.getDetails());
}
@Override
public String toString() {
return "TaskanaHistoryEvent ["

View File

@ -6,7 +6,7 @@ import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.spi.history.api.TaskanaHistory;
@ -20,10 +20,10 @@ public final class HistoryEventManager {
private boolean enabled = false;
private ServiceLoader<TaskanaHistory> serviceLoader;
private HistoryEventManager(TaskanaEngineConfiguration taskanaEngineConfiguration) {
private HistoryEventManager(TaskanaEngine taskanaEngine) {
serviceLoader = ServiceLoader.load(TaskanaHistory.class);
for (TaskanaHistory history : serviceLoader) {
history.initialize(taskanaEngineConfiguration);
history.initialize(taskanaEngine);
LOGGER.info("Registered history provider: {}", history.getClass().getName());
enabled = true;
}
@ -32,10 +32,9 @@ public final class HistoryEventManager {
}
}
public static synchronized HistoryEventManager getInstance(
TaskanaEngineConfiguration taskanaEngineConfiguration) {
public static synchronized HistoryEventManager getInstance(TaskanaEngine taskanaEngine) {
if (singleton == null) {
singleton = new HistoryEventManager(taskanaEngineConfiguration);
singleton = new HistoryEventManager(taskanaEngine);
}
return singleton;
}

View File

@ -119,6 +119,7 @@ class PojoTest {
return new ClassFileImporter()
.importPackages("pro.taskana").stream()
.filter(javaClass -> javaClass.tryGetMethod("equals", Object.class).isPresent())
.filter(javaClass -> !javaClass.getSimpleName().equals("TaskanaHistoryEvent"))
.map(JavaClass::reflect)
.collect(Collectors.toList());
}

View File

@ -27,6 +27,7 @@
<version.mybatis>3.5.5</version.mybatis>
<version.json>20200518</version.json>
<version.jackson-databind>2.11.0</version.jackson-databind>
<!-- build dependencies -->
<version.checkstyle>8.35</version.checkstyle>
@ -65,6 +66,7 @@
<version.equalsverifier>3.4.1</version.equalsverifier>
<version.openpojo>0.8.13</version.openpojo>
<version.jacoco>0.8.5</version.jacoco>
<version.slf4j-test>1.2.0</version.slf4j-test>
<!-- database driver versions -->
<version.db2>11.1.1.1</version.db2>

View File

@ -16,27 +16,6 @@
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@ -52,10 +31,6 @@
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring-example-common</artifactId>
@ -76,6 +51,53 @@
</dependency>
</dependencies>
</profile>
<profile>
<id>historyLogging.plugin</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-loghistory-provider</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
<build>

View File

@ -16,3 +16,4 @@ taskana.jobs.cleanup.firstRunAt=2018-07-25T08:00:00Z
taskana.jobs.cleanup.minimumAge=P14D
taskana.german.holidays.enabled=true
taskana.german.holidays.corpus-christi.enabled=true
taskana.historylogger.name=AUDIT