TSK-1737: created ConfigurationService which manages custom attributes
This commit is contained in:
parent
4ae94ff108
commit
05fce27222
|
|
@ -44,7 +44,6 @@ public class DbSchemaCreator {
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
public DbSchemaCreator(DataSource dataSource, String schema) {
|
public DbSchemaCreator(DataSource dataSource, String schema) {
|
||||||
super();
|
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.schemaName = schema;
|
this.schemaName = schema;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
package pro.taskana.common.internal.configuration;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import org.apache.ibatis.jdbc.SqlRunner;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
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 final String schemaName;
|
|
||||||
private final DataSource dataSource;
|
|
||||||
|
|
||||||
public SecurityVerifier(DataSource dataSource, String schema) {
|
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.schemaName = schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkSecureAccess(boolean securityEnabled) {
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug(connection.getMetaData().toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
SqlRunner sqlRunner = new SqlRunner(connection);
|
|
||||||
|
|
||||||
String querySecurity =
|
|
||||||
String.format(SELECT_SECURITY_FLAG_SQL, SECURITY_FLAG_COLUMN_NAME, schemaName);
|
|
||||||
|
|
||||||
if ((boolean) sqlRunner.selectOne(querySecurity).get(SECURITY_FLAG_COLUMN_NAME)
|
|
||||||
&& !securityEnabled) {
|
|
||||||
|
|
||||||
LOGGER.error("Tried to start TASKANA in unsecured mode while secured mode is enforced!");
|
|
||||||
|
|
||||||
throw new SystemException(
|
|
||||||
"Secured TASKANA mode is enforced, can't start in unsecured mode");
|
|
||||||
}
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug(
|
|
||||||
String.format(
|
|
||||||
"Security-mode is not yet set. Setting security flag to %b", securityEnabled));
|
|
||||||
}
|
|
||||||
|
|
||||||
setInitialSecurityMode(securityEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug("Security-mode is enabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setInitialSecurityMode(boolean securityEnabled) {
|
|
||||||
|
|
||||||
try (Connection connection = dataSource.getConnection()) {
|
|
||||||
|
|
||||||
String setSecurityFlagSql =
|
|
||||||
String.format(INSERT_SECURITY_FLAG_SQL, schemaName, securityEnabled);
|
|
||||||
|
|
||||||
try (PreparedStatement preparedStatement = connection.prepareStatement(setSecurityFlagSql)) {
|
|
||||||
|
|
||||||
preparedStatement.execute();
|
|
||||||
|
|
||||||
if (!connection.getAutoCommit()) {
|
|
||||||
connection.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
|
||||||
LOGGER.debug(String.format("Successfully set security-mode to %b", securityEnabled));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.error(
|
|
||||||
"Caught exception while trying to set the initial TASKANA security mode. "
|
|
||||||
+ "Aborting start-up process!",
|
|
||||||
ex);
|
|
||||||
|
|
||||||
throw new SystemException(
|
|
||||||
"Couldn't set initial TASKANA security mode. Aborting start-up process!");
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.error("Caught exception while trying to retrieve connection from datasource ", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package pro.taskana.common.internal.util;
|
||||||
|
|
||||||
|
import pro.taskana.common.api.exceptions.SystemException;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CheckedRunnable {
|
||||||
|
|
||||||
|
static Runnable wrap(CheckedRunnable checkedRunnable) {
|
||||||
|
return () -> {
|
||||||
|
try {
|
||||||
|
checkedRunnable.run();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SystemException("Caught exception", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() throws Exception;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package pro.taskana.common.internal.util;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ResourceUtil {
|
||||||
|
|
||||||
|
private ResourceUtil() {
|
||||||
|
throw new IllegalStateException("utility class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readResourceAsString(Class<?> clazz, String resource) throws IOException {
|
||||||
|
try (InputStream fileStream = clazz.getResourceAsStream(resource)) {
|
||||||
|
if (fileStream == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try (Reader inputStreamReader = new InputStreamReader(fileStream, StandardCharsets.UTF_8);
|
||||||
|
BufferedReader reader = new BufferedReader(inputStreamReader)) {
|
||||||
|
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ CREATE SCHEMA IF NOT EXISTS %schemaName%;
|
||||||
|
|
||||||
SET SCHEMA %schemaName%;
|
SET SCHEMA %schemaName%;
|
||||||
|
|
||||||
-- MOved to h2 jdbc connect string, because of taskana-spring-example project is using two schemas.
|
-- Moved to h2 jdbc connect string, because of taskana-spring-example project is using two schemas.
|
||||||
-- There the order of the schema setup's (dbcustom, taskana) should be switched then we can set collation
|
-- There the order of the schema setup's (dbcustom, taskana) should be switched then we can set collation
|
||||||
-- here in this file!
|
-- here in this file!
|
||||||
-- SET COLLATION DEFAULT_de_DE;
|
-- SET COLLATION DEFAULT_de_DE;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package pro.taskana.common.internal.util;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class ResourceUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_loadResource() throws Exception {
|
||||||
|
String resourceAsString = ResourceUtil.readResourceAsString(getClass(), "fileInClasspath.txt");
|
||||||
|
|
||||||
|
assertThat(resourceAsString).isEqualTo("This file is in the classpath");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnNull_When_ResourceDoesNotExist() throws Exception {
|
||||||
|
String resourceAsString = ResourceUtil.readResourceAsString(getClass(), "doesNotExist");
|
||||||
|
|
||||||
|
assertThat(resourceAsString).isNull();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -115,11 +115,12 @@ public abstract class AbstractAccTest {
|
||||||
dataSource,
|
dataSource,
|
||||||
false,
|
false,
|
||||||
schemaName != null && !schemaName.isEmpty() ? schemaName : getSchemaName());
|
schemaName != null && !schemaName.isEmpty() ? schemaName : getSchemaName());
|
||||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
taskanaEngine =
|
||||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||||
taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
||||||
historyService = new SimpleHistoryServiceImpl();
|
historyService = new SimpleHistoryServiceImpl();
|
||||||
historyService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
|
historyService.initialize(
|
||||||
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT));
|
||||||
|
|
||||||
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, getSchemaName());
|
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, getSchemaName());
|
||||||
sampleDataGenerator.clearDb();
|
sampleDataGenerator.clearDb();
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import pro.taskana.common.api.CustomHoliday;
|
import pro.taskana.common.api.CustomHoliday;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
|
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||||
import pro.taskana.common.api.TaskanaRole;
|
import pro.taskana.common.api.TaskanaRole;
|
||||||
import pro.taskana.common.api.exceptions.SystemException;
|
import pro.taskana.common.api.exceptions.SystemException;
|
||||||
import pro.taskana.common.api.exceptions.WrongCustomHolidayFormatException;
|
import pro.taskana.common.api.exceptions.WrongCustomHolidayFormatException;
|
||||||
|
|
@ -211,6 +212,11 @@ public class TaskanaEngineConfiguration {
|
||||||
return TaskanaEngineImpl.createTaskanaEngine(this);
|
return TaskanaEngineImpl.createTaskanaEngine(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TaskanaEngine buildTaskanaEngine(ConnectionManagementMode connectionManagementMode)
|
||||||
|
throws SQLException {
|
||||||
|
return TaskanaEngineImpl.createTaskanaEngine(this, connectionManagementMode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method creates a PooledDataSource, if the needed properties are provided.
|
* This method creates a PooledDataSource, if the needed properties are provided.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package pro.taskana.common.api;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface ConfigurationService {
|
||||||
|
|
||||||
|
Map<String, Object> getAllCustomAttributes();
|
||||||
|
|
||||||
|
void setAllCustomAttributes(Map<String, ?> customAttributes);
|
||||||
|
|
||||||
|
Optional<Object> getValue(String attribute);
|
||||||
|
}
|
||||||
|
|
@ -52,6 +52,8 @@ public interface TaskanaEngine {
|
||||||
|
|
||||||
UserService getUserService();
|
UserService getUserService();
|
||||||
|
|
||||||
|
ConfigurationService getConfigurationService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Taskana configuration.
|
* The Taskana configuration.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package pro.taskana.common.internal;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.ibatis.annotations.Insert;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
|
||||||
|
public interface ConfigurationMapper {
|
||||||
|
|
||||||
|
@Select("SELECT ENFORCE_SECURITY FROM CONFIGURATION")
|
||||||
|
Boolean isSecurityEnabled();
|
||||||
|
|
||||||
|
@Insert("INSERT INTO CONFIGURATION(ENFORCE_SECURITY) VALUES (#{securityEnabled})")
|
||||||
|
void setSecurityEnabled(@Param("securityEnabled") boolean securityEnabled);
|
||||||
|
|
||||||
|
@Select("SELECT CUSTOM_ATTRIBUTES FROM TASKANA.CONFIGURATION")
|
||||||
|
Map<String, Object> getAllCustomAttributes();
|
||||||
|
|
||||||
|
@Update("UPDATE TASKANA.CONFIGURATION SET CUSTOM_ATTRIBUTES = #{customAttributes}")
|
||||||
|
void setAllCustomAttributes(@Param("customAttributes") Map<String, ?> customAttributes);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
package pro.taskana.common.internal;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
|
import pro.taskana.common.api.exceptions.SystemException;
|
||||||
|
import pro.taskana.common.internal.util.CheckedRunnable;
|
||||||
|
import pro.taskana.common.internal.util.ResourceUtil;
|
||||||
|
|
||||||
|
public class ConfigurationServiceImpl implements ConfigurationService {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationServiceImpl.class);
|
||||||
|
|
||||||
|
private final InternalTaskanaEngine internalTaskanaEngine;
|
||||||
|
private final ConfigurationMapper mapper;
|
||||||
|
|
||||||
|
public ConfigurationServiceImpl(
|
||||||
|
InternalTaskanaEngine internalTaskanaEngine, ConfigurationMapper mapper) {
|
||||||
|
this.internalTaskanaEngine = internalTaskanaEngine;
|
||||||
|
this.mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkSecureAccess(boolean securityEnabled) {
|
||||||
|
Boolean isSecurityEnabled =
|
||||||
|
internalTaskanaEngine.executeInDatabaseConnection(mapper::isSecurityEnabled);
|
||||||
|
|
||||||
|
if (isSecurityEnabled == null) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Security-mode is not yet set. Setting security flag to {}", securityEnabled);
|
||||||
|
}
|
||||||
|
mapper.setSecurityEnabled(securityEnabled);
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("Successfully set security mode to {}", securityEnabled);
|
||||||
|
}
|
||||||
|
} else if (isSecurityEnabled && !securityEnabled) {
|
||||||
|
LOGGER.error("Tried to start TASKANA in unsecured mode while secured mode is enforced!");
|
||||||
|
throw new SystemException("Secured TASKANA mode is enforced, can't start in unsecured mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setupDefaultCustomAttributes() {
|
||||||
|
internalTaskanaEngine.executeInDatabaseConnection(
|
||||||
|
CheckedRunnable.wrap(
|
||||||
|
() -> {
|
||||||
|
if (mapper.getAllCustomAttributes() == null) {
|
||||||
|
if (LOGGER.isDebugEnabled()) {
|
||||||
|
LOGGER.debug("custom attributes are not set. Setting default value");
|
||||||
|
}
|
||||||
|
setAllCustomAttributes(generateDefaultCustomAttributes());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getAllCustomAttributes() {
|
||||||
|
return internalTaskanaEngine.executeInDatabaseConnection(mapper::getAllCustomAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAllCustomAttributes(Map<String, ?> customAttributes) {
|
||||||
|
internalTaskanaEngine.executeInDatabaseConnection(
|
||||||
|
() -> mapper.setAllCustomAttributes(customAttributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Object> getValue(String attribute) {
|
||||||
|
return Optional.ofNullable(getAllCustomAttributes().get(attribute));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> generateDefaultCustomAttributes() throws IOException {
|
||||||
|
JSONObject jsonObject =
|
||||||
|
new JSONObject(
|
||||||
|
ResourceUtil.readResourceAsString(getClass(), "defaultCustomAttributes.json"));
|
||||||
|
return jsonObject.toMap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ import pro.taskana.spi.task.internal.CreateTaskPreprocessorManager;
|
||||||
public interface InternalTaskanaEngine {
|
public interface InternalTaskanaEngine {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the connection to the database. Has to be called at the begin of each Api call that
|
* Opens the connection to the database. Has to be called at the beginning of each Api call that
|
||||||
* accesses the database
|
* accesses the database
|
||||||
*/
|
*/
|
||||||
void openConnection();
|
void openConnection();
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import pro.taskana.classification.api.ClassificationService;
|
||||||
import pro.taskana.classification.internal.ClassificationMapper;
|
import pro.taskana.classification.internal.ClassificationMapper;
|
||||||
import pro.taskana.classification.internal.ClassificationQueryMapper;
|
import pro.taskana.classification.internal.ClassificationQueryMapper;
|
||||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
import pro.taskana.common.api.JobService;
|
import pro.taskana.common.api.JobService;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
import pro.taskana.common.api.TaskanaRole;
|
import pro.taskana.common.api.TaskanaRole;
|
||||||
|
|
@ -43,7 +44,6 @@ import pro.taskana.common.api.security.CurrentUserContext;
|
||||||
import pro.taskana.common.api.security.UserPrincipal;
|
import pro.taskana.common.api.security.UserPrincipal;
|
||||||
import pro.taskana.common.internal.configuration.DB;
|
import pro.taskana.common.internal.configuration.DB;
|
||||||
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
||||||
import pro.taskana.common.internal.configuration.SecurityVerifier;
|
|
||||||
import pro.taskana.common.internal.persistence.InstantTypeHandler;
|
import pro.taskana.common.internal.persistence.InstantTypeHandler;
|
||||||
import pro.taskana.common.internal.persistence.MapTypeHandler;
|
import pro.taskana.common.internal.persistence.MapTypeHandler;
|
||||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||||
|
|
@ -85,19 +85,20 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
||||||
private final WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
private final WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
||||||
private final HistoryEventManager historyEventManager;
|
private final HistoryEventManager historyEventManager;
|
||||||
private final CurrentUserContext currentUserContext;
|
private final CurrentUserContext currentUserContext;
|
||||||
|
private final ConfigurationServiceImpl configurationService;
|
||||||
protected TaskanaEngineConfiguration taskanaEngineConfiguration;
|
protected TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||||
protected TransactionFactory transactionFactory;
|
protected TransactionFactory transactionFactory;
|
||||||
protected SqlSessionManager sessionManager;
|
protected SqlSessionManager sessionManager;
|
||||||
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
|
protected ConnectionManagementMode mode;
|
||||||
protected Connection connection = null;
|
protected Connection connection;
|
||||||
|
|
||||||
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
protected TaskanaEngineImpl(
|
||||||
|
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||||
|
ConnectionManagementMode connectionManagementMode)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
||||||
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
|
this.mode = connectionManagementMode;
|
||||||
this.sessionManager = createSqlSessionManager();
|
internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
|
||||||
initializeDbSchema(taskanaEngineConfiguration);
|
|
||||||
this.internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
|
|
||||||
workingDaysToDaysConverter =
|
workingDaysToDaysConverter =
|
||||||
new WorkingDaysToDaysConverter(
|
new WorkingDaysToDaysConverter(
|
||||||
taskanaEngineConfiguration.isGermanPublicHolidaysEnabled(),
|
taskanaEngineConfiguration.isGermanPublicHolidaysEnabled(),
|
||||||
|
|
@ -105,18 +106,31 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
||||||
taskanaEngineConfiguration.getCustomHolidays());
|
taskanaEngineConfiguration.getCustomHolidays());
|
||||||
currentUserContext =
|
currentUserContext =
|
||||||
new CurrentUserContextImpl(TaskanaEngineConfiguration.shouldUseLowerCaseForAccessIds());
|
new CurrentUserContextImpl(TaskanaEngineConfiguration.shouldUseLowerCaseForAccessIds());
|
||||||
|
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
|
||||||
|
sessionManager = createSqlSessionManager();
|
||||||
|
configurationService =
|
||||||
|
new ConfigurationServiceImpl(
|
||||||
|
internalTaskanaEngineImpl, sessionManager.getMapper(ConfigurationMapper.class));
|
||||||
|
initializeDbSchema(taskanaEngineConfiguration);
|
||||||
|
|
||||||
// IMPORTANT: SPI has to be initialized last (and in this order) in order
|
// IMPORTANT: SPI has to be initialized last (and in this order) in order
|
||||||
// to provide a fully initialized TaskanaEngine instance during the SPI initialization!
|
// to provide a fully initialized TaskanaEngine instance during the SPI initialization!
|
||||||
historyEventManager = new HistoryEventManager(this);
|
|
||||||
taskRoutingManager = new TaskRoutingManager(this);
|
|
||||||
priorityServiceManager = new PriorityServiceManager();
|
priorityServiceManager = new PriorityServiceManager();
|
||||||
createTaskPreprocessorManager = new CreateTaskPreprocessorManager();
|
createTaskPreprocessorManager = new CreateTaskPreprocessorManager();
|
||||||
|
historyEventManager = new HistoryEventManager(this);
|
||||||
|
taskRoutingManager = new TaskRoutingManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TaskanaEngine createTaskanaEngine(
|
public static TaskanaEngine createTaskanaEngine(
|
||||||
TaskanaEngineConfiguration taskanaEngineConfiguration) throws SQLException {
|
TaskanaEngineConfiguration taskanaEngineConfiguration) throws SQLException {
|
||||||
return new TaskanaEngineImpl(taskanaEngineConfiguration);
|
return createTaskanaEngine(taskanaEngineConfiguration, ConnectionManagementMode.PARTICIPATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TaskanaEngine createTaskanaEngine(
|
||||||
|
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||||
|
ConnectionManagementMode connectionManagementMode)
|
||||||
|
throws SQLException {
|
||||||
|
return new TaskanaEngineImpl(taskanaEngineConfiguration, connectionManagementMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -171,6 +185,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
||||||
internalTaskanaEngineImpl, sessionManager.getMapper(UserMapper.class));
|
internalTaskanaEngineImpl, sessionManager.getMapper(UserMapper.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationService getConfigurationService() {
|
||||||
|
return configurationService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskanaEngineConfiguration getConfiguration() {
|
public TaskanaEngineConfiguration getConfiguration() {
|
||||||
return this.taskanaEngineConfiguration;
|
return this.taskanaEngineConfiguration;
|
||||||
|
|
@ -330,6 +349,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
||||||
configuration.addMapper(AttachmentMapper.class);
|
configuration.addMapper(AttachmentMapper.class);
|
||||||
configuration.addMapper(JobMapper.class);
|
configuration.addMapper(JobMapper.class);
|
||||||
configuration.addMapper(UserMapper.class);
|
configuration.addMapper(UserMapper.class);
|
||||||
|
configuration.addMapper(ConfigurationMapper.class);
|
||||||
SqlSessionFactory localSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
|
SqlSessionFactory localSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
|
||||||
return SqlSessionManager.newInstance(localSessionFactory);
|
return SqlSessionManager.newInstance(localSessionFactory);
|
||||||
}
|
}
|
||||||
|
|
@ -346,9 +366,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
||||||
"The Database Schema Version doesn't match the expected minimal version "
|
"The Database Schema Version doesn't match the expected minimal version "
|
||||||
+ MINIMAL_TASKANA_SCHEMA_VERSION);
|
+ MINIMAL_TASKANA_SCHEMA_VERSION);
|
||||||
}
|
}
|
||||||
new SecurityVerifier(
|
configurationService.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
|
||||||
taskanaEngineConfiguration.getDatasource(), taskanaEngineConfiguration.getSchemaName())
|
configurationService.setupDefaultCustomAttributes();
|
||||||
.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
{
|
||||||
|
"nameHighPrio": "High Prio",
|
||||||
|
"nameMediumPrio": "Medium P",
|
||||||
|
"nameLowPrio": "Low Prio",
|
||||||
|
"intervalHighPrio": [
|
||||||
|
100,
|
||||||
|
200
|
||||||
|
],
|
||||||
|
"intervalMediumPrio": [
|
||||||
|
21,
|
||||||
|
100
|
||||||
|
],
|
||||||
|
"intervalLowPrio": [
|
||||||
|
1,
|
||||||
|
20
|
||||||
|
],
|
||||||
|
"colorHighPrio": "#ff0000",
|
||||||
|
"colorLowPrio": "#5FAD00",
|
||||||
|
"colorMediumPrio": "#FFEE00",
|
||||||
|
"filter": {
|
||||||
|
"Filter": {
|
||||||
|
"custom-1": [
|
||||||
|
"true"
|
||||||
|
],
|
||||||
|
"custom-5": [
|
||||||
|
"3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Filter neu": {
|
||||||
|
"custom-5": [
|
||||||
|
"7",
|
||||||
|
"5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Filter Doppelt": {
|
||||||
|
"custom-5": [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"90"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema": {
|
||||||
|
"Priority-Report": {
|
||||||
|
"displayName": "Priority Report",
|
||||||
|
"members": {
|
||||||
|
"nameHighPrio": {
|
||||||
|
"displayName": "High Prio Name",
|
||||||
|
"type": "text",
|
||||||
|
"min": 1
|
||||||
|
},
|
||||||
|
"nameMediumPrio": {
|
||||||
|
"displayName": "Medium Prio Name",
|
||||||
|
"type": "text",
|
||||||
|
"min": 1,
|
||||||
|
"max": 8
|
||||||
|
},
|
||||||
|
"nameLowPrio": {
|
||||||
|
"displayName": "Low Prio Name",
|
||||||
|
"type": "text",
|
||||||
|
"min": 2,
|
||||||
|
"max": 64
|
||||||
|
},
|
||||||
|
"intervalHighPrio": {
|
||||||
|
"displayName": "High Prio Interval",
|
||||||
|
"type": "interval",
|
||||||
|
"min": 0,
|
||||||
|
"max": 300
|
||||||
|
},
|
||||||
|
"intervalMediumPrio": {
|
||||||
|
"displayName": "Medium Prio Interval",
|
||||||
|
"type": "interval",
|
||||||
|
"min": -5,
|
||||||
|
"max": 300
|
||||||
|
},
|
||||||
|
"intervalLowPrio": {
|
||||||
|
"displayName": "Low Prio Interval",
|
||||||
|
"type": "interval",
|
||||||
|
"min": 0
|
||||||
|
},
|
||||||
|
"colorHighPrio": {
|
||||||
|
"displayName": "High Prio Color",
|
||||||
|
"type": "color"
|
||||||
|
},
|
||||||
|
"colorMediumPrio": {
|
||||||
|
"displayName": "Medium Prio Color",
|
||||||
|
"type": "color"
|
||||||
|
},
|
||||||
|
"colorLowPrio": {
|
||||||
|
"displayName": "Low Prio Color",
|
||||||
|
"type": "color"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Filter": {
|
||||||
|
"displayName": "Filter for Task-Priority-Report",
|
||||||
|
"members": {
|
||||||
|
"filter": {
|
||||||
|
"displayName": "Filter values",
|
||||||
|
"type": "json",
|
||||||
|
"min": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,8 +56,8 @@ public abstract class AbstractAccTest {
|
||||||
if (dropTables) {
|
if (dropTables) {
|
||||||
sampleDataGenerator.dropDb();
|
sampleDataGenerator.dropDb();
|
||||||
}
|
}
|
||||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
taskanaEngine =
|
||||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||||
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
||||||
sampleDataGenerator.clearDb();
|
sampleDataGenerator.clearDb();
|
||||||
sampleDataGenerator.generateTestData();
|
sampleDataGenerator.generateTestData();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package acceptance.config;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestInstance;
|
||||||
|
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import testapi.TaskanaInject;
|
||||||
|
import testapi.TaskanaIntegrationTest;
|
||||||
|
|
||||||
|
import pro.taskana.common.internal.ConfigurationMapper;
|
||||||
|
import pro.taskana.common.internal.ConfigurationServiceImpl;
|
||||||
|
import pro.taskana.common.internal.util.ResourceUtil;
|
||||||
|
|
||||||
|
@TaskanaIntegrationTest
|
||||||
|
public class ConfigurationServiceImplAccTest {
|
||||||
|
|
||||||
|
@TaskanaInject ConfigurationServiceImpl configurationService;
|
||||||
|
@TaskanaInject ConfigurationMapper configurationMapper;
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
|
class CustomAttribute {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
void
|
||||||
|
should_SetDefaultCustomAttributesDuringTaskanaInitialization_When_NoCustomAttributesAreSet()
|
||||||
|
throws Exception {
|
||||||
|
Map<String, Object> expectedCustomAttributes =
|
||||||
|
new JSONObject(
|
||||||
|
ResourceUtil.readResourceAsString(
|
||||||
|
ConfigurationServiceImpl.class, "defaultCustomAttributes.json"))
|
||||||
|
.toMap();
|
||||||
|
|
||||||
|
Map<String, Object> allCustomAttributes = configurationMapper.getAllCustomAttributes();
|
||||||
|
|
||||||
|
assertThat(allCustomAttributes).isEqualTo(expectedCustomAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_NotSetDefaultCustomAttributes_When_CustomAttributesAreAlreadySet() {
|
||||||
|
Map<String, String> foo = Map.of("foo", "bar");
|
||||||
|
configurationService.setAllCustomAttributes(foo);
|
||||||
|
|
||||||
|
configurationService.setupDefaultCustomAttributes();
|
||||||
|
Map<String, Object> allCustomAttributes = configurationService.getAllCustomAttributes();
|
||||||
|
|
||||||
|
assertThat(allCustomAttributes).isEqualTo(foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_SetCustomAttributes() {
|
||||||
|
Map<String, String> foo = Map.of("foo1", "bar");
|
||||||
|
configurationService.setAllCustomAttributes(foo);
|
||||||
|
|
||||||
|
Map<String, Object> allCustomAttributes = configurationService.getAllCustomAttributes();
|
||||||
|
|
||||||
|
assertThat(allCustomAttributes).isEqualTo(foo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_RetrieveCustomAttributes() {
|
||||||
|
Map<String, String> foo = Map.of("foo2", "bar");
|
||||||
|
configurationService.setAllCustomAttributes(foo);
|
||||||
|
|
||||||
|
Optional<Object> customAttribute = configurationService.getValue("foo2");
|
||||||
|
|
||||||
|
assertThat(customAttribute).hasValue("bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnNull_When_CustomAttributeDoesNotExist() {
|
||||||
|
Map<String, String> foo = Map.of("foo3", "bar");
|
||||||
|
configurationService.setAllCustomAttributes(foo);
|
||||||
|
|
||||||
|
Optional<Object> customAttribute = configurationService.getValue("doesNotExist");
|
||||||
|
|
||||||
|
assertThat(customAttribute).isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,7 +15,6 @@ import org.junit.jupiter.api.Test;
|
||||||
import pro.taskana.TaskanaEngineConfiguration;
|
import pro.taskana.TaskanaEngineConfiguration;
|
||||||
import pro.taskana.common.api.exceptions.SystemException;
|
import pro.taskana.common.api.exceptions.SystemException;
|
||||||
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
||||||
import pro.taskana.common.internal.configuration.SecurityVerifier;
|
|
||||||
import pro.taskana.common.test.config.DataSourceGenerator;
|
import pro.taskana.common.test.config.DataSourceGenerator;
|
||||||
import pro.taskana.sampledata.SampleDataGenerator;
|
import pro.taskana.sampledata.SampleDataGenerator;
|
||||||
|
|
||||||
|
|
@ -89,9 +88,7 @@ class TaskanaSecurityConfigAccTest {
|
||||||
|
|
||||||
String selectSecurityFlagSql =
|
String selectSecurityFlagSql =
|
||||||
String.format(
|
String.format(
|
||||||
SecurityVerifier.SELECT_SECURITY_FLAG_SQL,
|
"SELECT ENFORCE_SECURITY FROM %s.CONFIGURATION", DataSourceGenerator.getSchemaName());
|
||||||
SecurityVerifier.SECURITY_FLAG_COLUMN_NAME,
|
|
||||||
DataSourceGenerator.getSchemaName());
|
|
||||||
|
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
ResultSet resultSet = statement.executeQuery(selectSecurityFlagSql);
|
ResultSet resultSet = statement.executeQuery(selectSecurityFlagSql);
|
||||||
|
|
@ -110,9 +107,8 @@ class TaskanaSecurityConfigAccTest {
|
||||||
|
|
||||||
String sql =
|
String sql =
|
||||||
String.format(
|
String.format(
|
||||||
SecurityVerifier.INSERT_SECURITY_FLAG_SQL,
|
"INSERT INTO %s.CONFIGURATION (ENFORCE_SECURITY) VALUES (%b)",
|
||||||
DataSourceGenerator.getSchemaName(),
|
DataSourceGenerator.getSchemaName(), securityFlag);
|
||||||
securityFlag);
|
|
||||||
|
|
||||||
Statement statement = connection.createStatement();
|
Statement statement = connection.createStatement();
|
||||||
statement.execute(sql);
|
statement.execute(sql);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import java.time.Instant;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.internal.stubbing.answers.CallsRealMethods;
|
import org.mockito.internal.stubbing.answers.CallsRealMethods;
|
||||||
|
|
@ -23,6 +24,7 @@ import pro.taskana.common.internal.jobs.PlainJavaTransactionProvider;
|
||||||
import pro.taskana.common.test.config.DataSourceGenerator;
|
import pro.taskana.common.test.config.DataSourceGenerator;
|
||||||
import pro.taskana.task.internal.jobs.TaskCleanupJob;
|
import pro.taskana.task.internal.jobs.TaskCleanupJob;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
class JobRunnerAccTest extends AbstractAccTest {
|
class JobRunnerAccTest extends AbstractAccTest {
|
||||||
|
|
||||||
private final JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService();
|
private final JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService();
|
||||||
|
|
@ -38,8 +40,8 @@ class JobRunnerAccTest extends AbstractAccTest {
|
||||||
runInThread(
|
runInThread(
|
||||||
() -> {
|
() -> {
|
||||||
try {
|
try {
|
||||||
TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
TaskanaEngine taskanaEngine =
|
||||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||||
DataSource dataSource = DataSourceGenerator.getDataSource();
|
DataSource dataSource = DataSourceGenerator.getDataSource();
|
||||||
// We have to slow down the transaction.
|
// We have to slow down the transaction.
|
||||||
// This is necessary to guarantee the execution of
|
// This is necessary to guarantee the execution of
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ import static org.junit.platform.commons.support.AnnotationSupport.isAnnotated;
|
||||||
import static testapi.util.ExtensionCommunicator.getClassLevelStore;
|
import static testapi.util.ExtensionCommunicator.getClassLevelStore;
|
||||||
import static testapi.util.ExtensionCommunicator.isTopLevelClass;
|
import static testapi.util.ExtensionCommunicator.isTopLevelClass;
|
||||||
|
|
||||||
|
import acceptance.TaskanaEngineProxy;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||||
|
|
@ -20,11 +22,15 @@ import testapi.util.ServiceProviderExtractor;
|
||||||
import pro.taskana.TaskanaEngineConfiguration;
|
import pro.taskana.TaskanaEngineConfiguration;
|
||||||
import pro.taskana.classification.api.ClassificationService;
|
import pro.taskana.classification.api.ClassificationService;
|
||||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
import pro.taskana.common.api.JobService;
|
import pro.taskana.common.api.JobService;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||||
import pro.taskana.common.api.security.CurrentUserContext;
|
import pro.taskana.common.api.security.CurrentUserContext;
|
||||||
|
import pro.taskana.common.internal.ConfigurationMapper;
|
||||||
|
import pro.taskana.common.internal.ConfigurationServiceImpl;
|
||||||
|
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||||
import pro.taskana.common.internal.JobServiceImpl;
|
import pro.taskana.common.internal.JobServiceImpl;
|
||||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||||
|
|
@ -64,9 +70,9 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
||||||
.forEach(
|
.forEach(
|
||||||
(spi, serviceProviders) ->
|
(spi, serviceProviders) ->
|
||||||
staticMock.when(() -> SpiLoader.load(spi)).thenReturn(serviceProviders));
|
staticMock.when(() -> SpiLoader.load(spi)).thenReturn(serviceProviders));
|
||||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
taskanaEngine =
|
||||||
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||||
}
|
}
|
||||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
|
||||||
|
|
||||||
store.put(STORE_TASKANA_ENTITY_MAP, generateTaskanaEntityMap(taskanaEngine));
|
store.put(STORE_TASKANA_ENTITY_MAP, generateTaskanaEntityMap(taskanaEngine));
|
||||||
}
|
}
|
||||||
|
|
@ -85,17 +91,21 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
||||||
return new TaskanaEngineConfiguration(dataSource, false, schemaName);
|
return new TaskanaEngineConfiguration(dataSource, false, schemaName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<Class<?>, Object> generateTaskanaEntityMap(TaskanaEngine taskanaEngine) {
|
private static Map<Class<?>, Object> generateTaskanaEntityMap(TaskanaEngine taskanaEngine)
|
||||||
|
throws Exception {
|
||||||
TaskService taskService = taskanaEngine.getTaskService();
|
TaskService taskService = taskanaEngine.getTaskService();
|
||||||
|
TaskanaEngineProxy taskanaEngineProxy = new TaskanaEngineProxy(taskanaEngine);
|
||||||
MonitorService monitorService = taskanaEngine.getMonitorService();
|
MonitorService monitorService = taskanaEngine.getMonitorService();
|
||||||
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
|
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
|
||||||
ClassificationService classificationService = taskanaEngine.getClassificationService();
|
ClassificationService classificationService = taskanaEngine.getClassificationService();
|
||||||
JobService jobService = taskanaEngine.getJobService();
|
JobService jobService = taskanaEngine.getJobService();
|
||||||
CurrentUserContext currentUserContext = taskanaEngine.getCurrentUserContext();
|
CurrentUserContext currentUserContext = taskanaEngine.getCurrentUserContext();
|
||||||
|
SqlSession sqlSession = taskanaEngineProxy.getSqlSession();
|
||||||
return Map.ofEntries(
|
return Map.ofEntries(
|
||||||
Map.entry(TaskanaEngineConfiguration.class, taskanaEngine.getConfiguration()),
|
Map.entry(TaskanaEngineConfiguration.class, taskanaEngine.getConfiguration()),
|
||||||
Map.entry(TaskanaEngineImpl.class, taskanaEngine),
|
Map.entry(TaskanaEngineImpl.class, taskanaEngine),
|
||||||
Map.entry(TaskanaEngine.class, taskanaEngine),
|
Map.entry(TaskanaEngine.class, taskanaEngine),
|
||||||
|
Map.entry(InternalTaskanaEngine.class, taskanaEngineProxy.getEngine()),
|
||||||
Map.entry(TaskService.class, taskService),
|
Map.entry(TaskService.class, taskService),
|
||||||
Map.entry(TaskServiceImpl.class, taskService),
|
Map.entry(TaskServiceImpl.class, taskService),
|
||||||
Map.entry(MonitorService.class, monitorService),
|
Map.entry(MonitorService.class, monitorService),
|
||||||
|
|
@ -104,10 +114,13 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
||||||
Map.entry(WorkbasketServiceImpl.class, workbasketService),
|
Map.entry(WorkbasketServiceImpl.class, workbasketService),
|
||||||
Map.entry(ClassificationService.class, classificationService),
|
Map.entry(ClassificationService.class, classificationService),
|
||||||
Map.entry(ClassificationServiceImpl.class, classificationService),
|
Map.entry(ClassificationServiceImpl.class, classificationService),
|
||||||
|
Map.entry(ConfigurationService.class, taskanaEngine.getConfigurationService()),
|
||||||
|
Map.entry(ConfigurationServiceImpl.class, taskanaEngine.getConfigurationService()),
|
||||||
Map.entry(JobService.class, jobService),
|
Map.entry(JobService.class, jobService),
|
||||||
Map.entry(JobServiceImpl.class, jobService),
|
Map.entry(JobServiceImpl.class, jobService),
|
||||||
Map.entry(CurrentUserContext.class, currentUserContext),
|
Map.entry(CurrentUserContext.class, currentUserContext),
|
||||||
Map.entry(CurrentUserContextImpl.class, currentUserContext),
|
Map.entry(CurrentUserContextImpl.class, currentUserContext),
|
||||||
Map.entry(WorkingDaysToDaysConverter.class, taskanaEngine.getWorkingDaysToDaysConverter()));
|
Map.entry(WorkingDaysToDaysConverter.class, taskanaEngine.getWorkingDaysToDaysConverter()),
|
||||||
|
Map.entry(ConfigurationMapper.class, sqlSession.getMapper(ConfigurationMapper.class)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,14 @@ import testapi.TaskanaIntegrationTest;
|
||||||
import pro.taskana.TaskanaEngineConfiguration;
|
import pro.taskana.TaskanaEngineConfiguration;
|
||||||
import pro.taskana.classification.api.ClassificationService;
|
import pro.taskana.classification.api.ClassificationService;
|
||||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
import pro.taskana.common.api.JobService;
|
import pro.taskana.common.api.JobService;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||||
import pro.taskana.common.api.security.CurrentUserContext;
|
import pro.taskana.common.api.security.CurrentUserContext;
|
||||||
|
import pro.taskana.common.internal.ConfigurationMapper;
|
||||||
|
import pro.taskana.common.internal.ConfigurationServiceImpl;
|
||||||
|
import pro.taskana.common.internal.InternalTaskanaEngine;
|
||||||
import pro.taskana.common.internal.JobServiceImpl;
|
import pro.taskana.common.internal.JobServiceImpl;
|
||||||
import pro.taskana.common.internal.TaskanaEngineImpl;
|
import pro.taskana.common.internal.TaskanaEngineImpl;
|
||||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||||
|
|
@ -31,6 +35,7 @@ class TaskanaDependencyInjectionExtensionTest {
|
||||||
@TaskanaInject TaskanaEngine taskanaEngine;
|
@TaskanaInject TaskanaEngine taskanaEngine;
|
||||||
@TaskanaInject TaskanaEngine taskanaEngine2;
|
@TaskanaInject TaskanaEngine taskanaEngine2;
|
||||||
@TaskanaInject TaskanaEngineImpl taskanaEngineImpl;
|
@TaskanaInject TaskanaEngineImpl taskanaEngineImpl;
|
||||||
|
@TaskanaInject InternalTaskanaEngine internalTaskanaEngine;
|
||||||
@TaskanaInject ClassificationService classificationService;
|
@TaskanaInject ClassificationService classificationService;
|
||||||
@TaskanaInject ClassificationServiceImpl classificationServiceImpl;
|
@TaskanaInject ClassificationServiceImpl classificationServiceImpl;
|
||||||
@TaskanaInject WorkbasketService workbasketService;
|
@TaskanaInject WorkbasketService workbasketService;
|
||||||
|
|
@ -41,9 +46,12 @@ class TaskanaDependencyInjectionExtensionTest {
|
||||||
@TaskanaInject MonitorServiceImpl monitorServiceImpl;
|
@TaskanaInject MonitorServiceImpl monitorServiceImpl;
|
||||||
@TaskanaInject JobService jobService;
|
@TaskanaInject JobService jobService;
|
||||||
@TaskanaInject JobServiceImpl jobServiceImpl;
|
@TaskanaInject JobServiceImpl jobServiceImpl;
|
||||||
|
@TaskanaInject ConfigurationService configurationService;
|
||||||
|
@TaskanaInject ConfigurationServiceImpl configurationServiceImpl;
|
||||||
@TaskanaInject WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
@TaskanaInject WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
||||||
@TaskanaInject CurrentUserContext currentUserContext;
|
@TaskanaInject CurrentUserContext currentUserContext;
|
||||||
@TaskanaInject CurrentUserContextImpl currentUserContextImpl;
|
@TaskanaInject CurrentUserContextImpl currentUserContextImpl;
|
||||||
|
@TaskanaInject ConfigurationMapper configurationMapper;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_NotInjectTaskanaEngineConfiguration_When_FieldIsNotAnnotated() {
|
void should_NotInjectTaskanaEngineConfiguration_When_FieldIsNotAnnotated() {
|
||||||
|
|
@ -73,6 +81,12 @@ class TaskanaDependencyInjectionExtensionTest {
|
||||||
assertThat(taskanaEngineImpl).isSameAs(this.taskanaEngineImpl).isNotNull();
|
assertThat(taskanaEngineImpl).isSameAs(this.taskanaEngineImpl).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_InjectInternalTaskanaEngine_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
|
InternalTaskanaEngine internalTaskanaEngine) {
|
||||||
|
assertThat(internalTaskanaEngine).isSameAs(this.internalTaskanaEngine).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_InjectClassificationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
void should_InjectClassificationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
ClassificationService classificationService) {
|
ClassificationService classificationService) {
|
||||||
|
|
@ -132,6 +146,18 @@ class TaskanaDependencyInjectionExtensionTest {
|
||||||
assertThat(jobServiceImpl).isSameAs(this.jobServiceImpl).isNotNull();
|
assertThat(jobServiceImpl).isSameAs(this.jobServiceImpl).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_InjectConfigurationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
|
ConfigurationService configurationService) {
|
||||||
|
assertThat(configurationService).isSameAs(this.configurationService).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_InjectConfigurationServiceImpl_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
|
ConfigurationServiceImpl configurationServiceImpl) {
|
||||||
|
assertThat(configurationServiceImpl).isSameAs(this.configurationServiceImpl).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_InjectWorkingDaysToDaysConverter_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
void should_InjectWorkingDaysToDaysConverter_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
WorkingDaysToDaysConverter workingDaysToDaysConverter) {
|
WorkingDaysToDaysConverter workingDaysToDaysConverter) {
|
||||||
|
|
@ -149,4 +175,10 @@ class TaskanaDependencyInjectionExtensionTest {
|
||||||
CurrentUserContextImpl currentUserContextImpl) {
|
CurrentUserContextImpl currentUserContextImpl) {
|
||||||
assertThat(currentUserContextImpl).isSameAs(this.currentUserContextImpl).isNotNull();
|
assertThat(currentUserContextImpl).isSameAs(this.currentUserContextImpl).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_InjectConfigurationMapper_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||||
|
ConfigurationMapper configurationMapper) {
|
||||||
|
assertThat(configurationMapper).isSameAs(this.configurationMapper).isNotNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,7 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pro.taskana</groupId>
|
<groupId>pro.taskana</groupId>
|
||||||
<artifactId>taskana-spring</artifactId>
|
<artifactId>taskana-spring</artifactId>
|
||||||
|
|
@ -44,6 +41,17 @@
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.vaadin.external.google</groupId>
|
||||||
|
<artifactId>android-json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.sql.SQLException;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
|
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||||
import pro.taskana.common.internal.SpringTaskanaEngineImpl;
|
import pro.taskana.common.internal.SpringTaskanaEngineImpl;
|
||||||
|
|
||||||
/** This class configures the TaskanaEngineConfiguration for spring. */
|
/** This class configures the TaskanaEngineConfiguration for spring. */
|
||||||
|
|
@ -41,7 +42,7 @@ public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration
|
||||||
@Override
|
@Override
|
||||||
public TaskanaEngine buildTaskanaEngine() throws SQLException {
|
public TaskanaEngine buildTaskanaEngine() throws SQLException {
|
||||||
this.useManagedTransactions = true;
|
this.useManagedTransactions = true;
|
||||||
return new SpringTaskanaEngineImpl(this);
|
return new SpringTaskanaEngineImpl(this, ConnectionManagementMode.PARTICIPATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,10 @@ import pro.taskana.SpringTaskanaEngineConfiguration;
|
||||||
/** This class configures the TaskanaEngine for spring. */
|
/** This class configures the TaskanaEngine for spring. */
|
||||||
public class SpringTaskanaEngineImpl extends TaskanaEngineImpl {
|
public class SpringTaskanaEngineImpl extends TaskanaEngineImpl {
|
||||||
|
|
||||||
public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration)
|
public SpringTaskanaEngineImpl(
|
||||||
|
SpringTaskanaEngineConfiguration taskanaEngineConfiguration, ConnectionManagementMode mode)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
super(taskanaEngineConfiguration);
|
super(taskanaEngineConfiguration, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
package pro.taskana.example.rest.controllers;
|
package pro.taskana.example.rest.controllers;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
import pro.taskana.common.internal.util.ResourceUtil;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class ResourcesController {
|
public class ResourcesController {
|
||||||
|
|
||||||
|
|
@ -32,14 +29,10 @@ public class ResourcesController {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private String readResourceAsString(String resource) throws IOException {
|
private String readResourceAsString(String resource) throws IOException {
|
||||||
try (InputStream fileStream = getClass().getResourceAsStream(resource)) {
|
String resourceAsString = ResourceUtil.readResourceAsString(getClass(), resource);
|
||||||
if (fileStream == null) {
|
if (resourceAsString == null) {
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
|
||||||
try (Reader inputStreamReader = new InputStreamReader(fileStream);
|
|
||||||
BufferedReader reader = new BufferedReader(inputStreamReader)) {
|
|
||||||
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return resourceAsString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,9 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import pro.taskana.SpringTaskanaEngineConfiguration;
|
import pro.taskana.SpringTaskanaEngineConfiguration;
|
||||||
import pro.taskana.TaskanaEngineConfiguration;
|
import pro.taskana.TaskanaEngineConfiguration;
|
||||||
import pro.taskana.classification.api.ClassificationService;
|
import pro.taskana.classification.api.ClassificationService;
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
|
import pro.taskana.common.api.security.CurrentUserContext;
|
||||||
import pro.taskana.monitor.api.MonitorService;
|
import pro.taskana.monitor.api.MonitorService;
|
||||||
import pro.taskana.task.api.TaskService;
|
import pro.taskana.task.api.TaskService;
|
||||||
import pro.taskana.user.api.UserService;
|
import pro.taskana.user.api.UserService;
|
||||||
|
|
@ -58,6 +60,16 @@ public class RestConfiguration {
|
||||||
return taskanaEngine.getUserService();
|
return taskanaEngine.getUserService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ConfigurationService configurationService(TaskanaEngine taskanaEngine) {
|
||||||
|
return taskanaEngine.getConfigurationService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CurrentUserContext currentUserContext(TaskanaEngine taskanaEngine) {
|
||||||
|
return taskanaEngine.getCurrentUserContext();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(TaskanaEngine.class)
|
@ConditionalOnMissingBean(TaskanaEngine.class)
|
||||||
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ public final class RestEndpoints {
|
||||||
public static final String URL_CLASSIFICATION_CATEGORIES_BY_TYPES =
|
public static final String URL_CLASSIFICATION_CATEGORIES_BY_TYPES =
|
||||||
API_V1 + "classifications-by-type";
|
API_V1 + "classifications-by-type";
|
||||||
public static final String URL_HISTORY_ENABLED = API_V1 + "history-provider-enabled";
|
public static final String URL_HISTORY_ENABLED = API_V1 + "history-provider-enabled";
|
||||||
|
public static final String URL_CUSTOM_ATTRIBUTES = API_V1 + "/config/custom-attributes";
|
||||||
|
|
||||||
// access id endpoints
|
// access id endpoints
|
||||||
public static final String URL_ACCESS_ID = API_V1 + "access-ids";
|
public static final String URL_ACCESS_ID = API_V1 + "access-ids";
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,21 @@ package pro.taskana.common.rest;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import pro.taskana.TaskanaEngineConfiguration;
|
import pro.taskana.TaskanaEngineConfiguration;
|
||||||
|
import pro.taskana.common.api.ConfigurationService;
|
||||||
import pro.taskana.common.api.TaskanaEngine;
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
import pro.taskana.common.api.TaskanaRole;
|
import pro.taskana.common.api.security.CurrentUserContext;
|
||||||
|
import pro.taskana.common.rest.models.CustomAttributesRepresentationModel;
|
||||||
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
|
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
|
||||||
import pro.taskana.common.rest.models.VersionRepresentationModel;
|
import pro.taskana.common.rest.models.VersionRepresentationModel;
|
||||||
|
|
||||||
|
|
@ -20,13 +26,20 @@ import pro.taskana.common.rest.models.VersionRepresentationModel;
|
||||||
public class TaskanaEngineController {
|
public class TaskanaEngineController {
|
||||||
|
|
||||||
private final TaskanaEngineConfiguration taskanaEngineConfiguration;
|
private final TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||||
|
|
||||||
private final TaskanaEngine taskanaEngine;
|
private final TaskanaEngine taskanaEngine;
|
||||||
|
private final CurrentUserContext currentUserContext;
|
||||||
|
private final ConfigurationService configurationService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
TaskanaEngineController(
|
TaskanaEngineController(
|
||||||
TaskanaEngineConfiguration taskanaEngineConfiguration, TaskanaEngine taskanaEngine) {
|
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||||
|
TaskanaEngine taskanaEngine,
|
||||||
|
CurrentUserContext currentUserContext,
|
||||||
|
ConfigurationService configurationService) {
|
||||||
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
||||||
this.taskanaEngine = taskanaEngine;
|
this.taskanaEngine = taskanaEngine;
|
||||||
|
this.currentUserContext = currentUserContext;
|
||||||
|
this.configurationService = configurationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -35,6 +48,7 @@ public class TaskanaEngineController {
|
||||||
* @return An array with the domain-names as strings
|
* @return An array with the domain-names as strings
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_DOMAIN)
|
@GetMapping(path = RestEndpoints.URL_DOMAIN)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<List<String>> getDomains() {
|
public ResponseEntity<List<String>> getDomains() {
|
||||||
return ResponseEntity.ok(taskanaEngineConfiguration.getDomains());
|
return ResponseEntity.ok(taskanaEngineConfiguration.getDomains());
|
||||||
}
|
}
|
||||||
|
|
@ -48,6 +62,7 @@ public class TaskanaEngineController {
|
||||||
* @return the classification categories for the requested type.
|
* @return the classification categories for the requested type.
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES)
|
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<List<String>> getClassificationCategories(
|
public ResponseEntity<List<String>> getClassificationCategories(
|
||||||
@RequestParam(required = false) String type) {
|
@RequestParam(required = false) String type) {
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
|
|
@ -62,6 +77,7 @@ public class TaskanaEngineController {
|
||||||
* @return the configured classification types.
|
* @return the configured classification types.
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_TYPES)
|
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_TYPES)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<List<String>> getClassificationTypes() {
|
public ResponseEntity<List<String>> getClassificationTypes() {
|
||||||
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationTypes());
|
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationTypes());
|
||||||
}
|
}
|
||||||
|
|
@ -73,6 +89,7 @@ public class TaskanaEngineController {
|
||||||
* @return the configured classification categories
|
* @return the configured classification categories
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES_BY_TYPES)
|
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES_BY_TYPES)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<Map<String, List<String>>> getClassificationCategoriesByTypeMap() {
|
public ResponseEntity<Map<String, List<String>>> getClassificationCategoriesByTypeMap() {
|
||||||
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationCategoriesByTypeMap());
|
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationCategoriesByTypeMap());
|
||||||
}
|
}
|
||||||
|
|
@ -83,15 +100,14 @@ public class TaskanaEngineController {
|
||||||
* @return the information of the current user.
|
* @return the information of the current user.
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_CURRENT_USER)
|
@GetMapping(path = RestEndpoints.URL_CURRENT_USER)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskanaUserInfoRepresentationModel> getCurrentUserInfo() {
|
public ResponseEntity<TaskanaUserInfoRepresentationModel> getCurrentUserInfo() {
|
||||||
TaskanaUserInfoRepresentationModel resource = new TaskanaUserInfoRepresentationModel();
|
TaskanaUserInfoRepresentationModel resource = new TaskanaUserInfoRepresentationModel();
|
||||||
resource.setUserId(taskanaEngine.getCurrentUserContext().getUserid());
|
resource.setUserId(currentUserContext.getUserid());
|
||||||
resource.setGroupIds(taskanaEngine.getCurrentUserContext().getGroupIds());
|
resource.setGroupIds(currentUserContext.getGroupIds());
|
||||||
for (TaskanaRole role : taskanaEngineConfiguration.getRoleMap().keySet()) {
|
taskanaEngineConfiguration.getRoleMap().keySet().stream()
|
||||||
if (taskanaEngine.isUserInRole(role)) {
|
.filter(taskanaEngine::isUserInRole)
|
||||||
resource.getRoles().add(role);
|
.forEach(resource.getRoles()::add);
|
||||||
}
|
|
||||||
}
|
|
||||||
return ResponseEntity.ok(resource);
|
return ResponseEntity.ok(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,16 +117,33 @@ public class TaskanaEngineController {
|
||||||
* @return true, when the history is enabled, otherwise false
|
* @return true, when the history is enabled, otherwise false
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_HISTORY_ENABLED)
|
@GetMapping(path = RestEndpoints.URL_HISTORY_ENABLED)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<Boolean> getIsHistoryProviderEnabled() {
|
public ResponseEntity<Boolean> getIsHistoryProviderEnabled() {
|
||||||
return ResponseEntity.ok(taskanaEngine.isHistoryEnabled());
|
return ResponseEntity.ok(taskanaEngine.isHistoryEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping(path = RestEndpoints.URL_CUSTOM_ATTRIBUTES)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
|
public ResponseEntity<CustomAttributesRepresentationModel> getCustomAttributes() {
|
||||||
|
Map<String, Object> allCustomAttributes = configurationService.getAllCustomAttributes();
|
||||||
|
return ResponseEntity.ok(new CustomAttributesRepresentationModel(allCustomAttributes));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping(path = RestEndpoints.URL_CUSTOM_ATTRIBUTES)
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ResponseEntity<CustomAttributesRepresentationModel> setCustomAttributes(
|
||||||
|
@RequestBody CustomAttributesRepresentationModel customAttributes) {
|
||||||
|
configurationService.setAllCustomAttributes(customAttributes.getCustomAttributes());
|
||||||
|
return ResponseEntity.ok(customAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current application version.
|
* Get the current application version.
|
||||||
*
|
*
|
||||||
* @return The current version.
|
* @return The current version.
|
||||||
*/
|
*/
|
||||||
@GetMapping(path = RestEndpoints.URL_VERSION)
|
@GetMapping(path = RestEndpoints.URL_VERSION)
|
||||||
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<VersionRepresentationModel> currentVersion() {
|
public ResponseEntity<VersionRepresentationModel> currentVersion() {
|
||||||
VersionRepresentationModel resource = new VersionRepresentationModel();
|
VersionRepresentationModel resource = new VersionRepresentationModel();
|
||||||
resource.setVersion(TaskanaEngineConfiguration.class.getPackage().getImplementationVersion());
|
resource.setVersion(TaskanaEngineConfiguration.class.getPackage().getImplementationVersion());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package pro.taskana.common.rest.models;
|
||||||
|
|
||||||
|
import java.beans.ConstructorProperties;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.springframework.hateoas.RepresentationModel;
|
||||||
|
|
||||||
|
public class CustomAttributesRepresentationModel
|
||||||
|
extends RepresentationModel<CustomAttributesRepresentationModel> {
|
||||||
|
|
||||||
|
private final Map<String, Object> customAttributes;
|
||||||
|
|
||||||
|
@ConstructorProperties({"customAttributes"})
|
||||||
|
public CustomAttributesRepresentationModel(Map<String, Object> customAttributes) {
|
||||||
|
this.customAttributes = customAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> getCustomAttributes() {
|
||||||
|
return customAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
import pro.taskana.common.api.TaskanaRole;
|
import pro.taskana.common.api.TaskanaRole;
|
||||||
|
import pro.taskana.common.rest.models.CustomAttributesRepresentationModel;
|
||||||
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
|
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
|
||||||
import pro.taskana.common.test.rest.RestHelper;
|
import pro.taskana.common.test.rest.RestHelper;
|
||||||
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
|
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
|
||||||
|
|
@ -32,7 +33,7 @@ class TaskanaEngineControllerIntTest {
|
||||||
@Test
|
@Test
|
||||||
void testDomains() {
|
void testDomains() {
|
||||||
String url = restHelper.toUrl(RestEndpoints.URL_DOMAIN);
|
String url = restHelper.toUrl(RestEndpoints.URL_DOMAIN);
|
||||||
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||||
|
|
||||||
ResponseEntity<List<String>> response =
|
ResponseEntity<List<String>> response =
|
||||||
TEMPLATE.exchange(
|
TEMPLATE.exchange(
|
||||||
|
|
@ -43,7 +44,7 @@ class TaskanaEngineControllerIntTest {
|
||||||
@Test
|
@Test
|
||||||
void testClassificationTypes() {
|
void testClassificationTypes() {
|
||||||
String url = restHelper.toUrl(RestEndpoints.URL_CLASSIFICATION_TYPES);
|
String url = restHelper.toUrl(RestEndpoints.URL_CLASSIFICATION_TYPES);
|
||||||
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||||
|
|
||||||
ResponseEntity<List<String>> response =
|
ResponseEntity<List<String>> response =
|
||||||
TEMPLATE.exchange(
|
TEMPLATE.exchange(
|
||||||
|
|
@ -54,7 +55,7 @@ class TaskanaEngineControllerIntTest {
|
||||||
@Test
|
@Test
|
||||||
void testClassificationCategories() {
|
void testClassificationCategories() {
|
||||||
String url = restHelper.toUrl(RestEndpoints.URL_CLASSIFICATION_CATEGORIES);
|
String url = restHelper.toUrl(RestEndpoints.URL_CLASSIFICATION_CATEGORIES);
|
||||||
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||||
|
|
||||||
ResponseEntity<List<String>> response =
|
ResponseEntity<List<String>> response =
|
||||||
TEMPLATE.exchange(
|
TEMPLATE.exchange(
|
||||||
|
|
@ -66,7 +67,7 @@ class TaskanaEngineControllerIntTest {
|
||||||
@Test
|
@Test
|
||||||
void testGetCurrentUserInfo() {
|
void testGetCurrentUserInfo() {
|
||||||
String url = restHelper.toUrl(RestEndpoints.URL_CURRENT_USER);
|
String url = restHelper.toUrl(RestEndpoints.URL_CURRENT_USER);
|
||||||
HttpEntity<Object> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||||
|
|
||||||
ResponseEntity<TaskanaUserInfoRepresentationModel> response =
|
ResponseEntity<TaskanaUserInfoRepresentationModel> response =
|
||||||
TEMPLATE.exchange(
|
TEMPLATE.exchange(
|
||||||
|
|
@ -81,4 +82,19 @@ class TaskanaEngineControllerIntTest {
|
||||||
assertThat(response.getBody().getRoles()).contains(TaskanaRole.BUSINESS_ADMIN);
|
assertThat(response.getBody().getRoles()).contains(TaskanaRole.BUSINESS_ADMIN);
|
||||||
assertThat(response.getBody().getRoles()).doesNotContain(TaskanaRole.ADMIN);
|
assertThat(response.getBody().getRoles()).doesNotContain(TaskanaRole.ADMIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_ReturnCustomAttributes() {
|
||||||
|
String url = restHelper.toUrl(RestEndpoints.URL_CUSTOM_ATTRIBUTES);
|
||||||
|
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||||
|
|
||||||
|
ResponseEntity<CustomAttributesRepresentationModel> response =
|
||||||
|
TEMPLATE.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.GET,
|
||||||
|
auth,
|
||||||
|
ParameterizedTypeReference.forType(CustomAttributesRepresentationModel.class));
|
||||||
|
|
||||||
|
assertThat(response.getBody()).isNotNull();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,8 @@ public abstract class AbstractAccTest {
|
||||||
dbSchemaCreator.run();
|
dbSchemaCreator.run();
|
||||||
sampleDataGenerator.clearDb();
|
sampleDataGenerator.clearDb();
|
||||||
sampleDataGenerator.generateTestData();
|
sampleDataGenerator.generateTestData();
|
||||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
taskanaEngine =
|
||||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||||
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue