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;
|
||||
|
||||
public DbSchemaCreator(DataSource dataSource, String schema) {
|
||||
super();
|
||||
this.dataSource = dataSource;
|
||||
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%;
|
||||
|
||||
-- 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
|
||||
-- here in this file!
|
||||
-- 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,
|
||||
false,
|
||||
schemaName != null && !schemaName.isEmpty() ? schemaName : getSchemaName());
|
||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
||||
taskanaEngine =
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||
taskanaHistoryEngine = TaskanaHistoryEngineImpl.createTaskanaEngine(taskanaEngine);
|
||||
historyService = new SimpleHistoryServiceImpl();
|
||||
historyService.initialize(taskanaEngineConfiguration.buildTaskanaEngine());
|
||||
historyService.initialize(
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT));
|
||||
|
||||
SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, getSchemaName());
|
||||
sampleDataGenerator.clearDb();
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import pro.taskana.common.api.CustomHoliday;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||
import pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.api.exceptions.WrongCustomHolidayFormatException;
|
||||
|
@ -211,6 +212,11 @@ public class TaskanaEngineConfiguration {
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -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();
|
||||
|
||||
ConfigurationService getConfigurationService();
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void openConnection();
|
||||
|
|
|
@ -30,6 +30,7 @@ import pro.taskana.classification.api.ClassificationService;
|
|||
import pro.taskana.classification.internal.ClassificationMapper;
|
||||
import pro.taskana.classification.internal.ClassificationQueryMapper;
|
||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.JobService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
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.internal.configuration.DB;
|
||||
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.MapTypeHandler;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
|
@ -85,19 +85,20 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
private final WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
||||
private final HistoryEventManager historyEventManager;
|
||||
private final CurrentUserContext currentUserContext;
|
||||
private final ConfigurationServiceImpl configurationService;
|
||||
protected TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
protected TransactionFactory transactionFactory;
|
||||
protected SqlSessionManager sessionManager;
|
||||
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
|
||||
protected Connection connection = null;
|
||||
protected ConnectionManagementMode mode;
|
||||
protected Connection connection;
|
||||
|
||||
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
||||
protected TaskanaEngineImpl(
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||
ConnectionManagementMode connectionManagementMode)
|
||||
throws SQLException {
|
||||
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
||||
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
|
||||
this.sessionManager = createSqlSessionManager();
|
||||
initializeDbSchema(taskanaEngineConfiguration);
|
||||
this.internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
|
||||
this.mode = connectionManagementMode;
|
||||
internalTaskanaEngineImpl = new InternalTaskanaEngineImpl();
|
||||
workingDaysToDaysConverter =
|
||||
new WorkingDaysToDaysConverter(
|
||||
taskanaEngineConfiguration.isGermanPublicHolidaysEnabled(),
|
||||
|
@ -105,18 +106,31 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
taskanaEngineConfiguration.getCustomHolidays());
|
||||
currentUserContext =
|
||||
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
|
||||
// to provide a fully initialized TaskanaEngine instance during the SPI initialization!
|
||||
historyEventManager = new HistoryEventManager(this);
|
||||
taskRoutingManager = new TaskRoutingManager(this);
|
||||
priorityServiceManager = new PriorityServiceManager();
|
||||
createTaskPreprocessorManager = new CreateTaskPreprocessorManager();
|
||||
historyEventManager = new HistoryEventManager(this);
|
||||
taskRoutingManager = new TaskRoutingManager(this);
|
||||
}
|
||||
|
||||
public static TaskanaEngine createTaskanaEngine(
|
||||
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
|
||||
|
@ -171,6 +185,11 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
internalTaskanaEngineImpl, sessionManager.getMapper(UserMapper.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationService getConfigurationService() {
|
||||
return configurationService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskanaEngineConfiguration getConfiguration() {
|
||||
return this.taskanaEngineConfiguration;
|
||||
|
@ -330,6 +349,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
configuration.addMapper(AttachmentMapper.class);
|
||||
configuration.addMapper(JobMapper.class);
|
||||
configuration.addMapper(UserMapper.class);
|
||||
configuration.addMapper(ConfigurationMapper.class);
|
||||
SqlSessionFactory localSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
|
||||
return SqlSessionManager.newInstance(localSessionFactory);
|
||||
}
|
||||
|
@ -346,9 +366,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
|
|||
"The Database Schema Version doesn't match the expected minimal version "
|
||||
+ MINIMAL_TASKANA_SCHEMA_VERSION);
|
||||
}
|
||||
new SecurityVerifier(
|
||||
taskanaEngineConfiguration.getDatasource(), taskanaEngineConfiguration.getSchemaName())
|
||||
.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
|
||||
configurationService.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
|
||||
configurationService.setupDefaultCustomAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) {
|
||||
sampleDataGenerator.dropDb();
|
||||
}
|
||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
||||
taskanaEngine =
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
||||
sampleDataGenerator.clearDb();
|
||||
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.common.api.exceptions.SystemException;
|
||||
import pro.taskana.common.internal.configuration.DbSchemaCreator;
|
||||
import pro.taskana.common.internal.configuration.SecurityVerifier;
|
||||
import pro.taskana.common.test.config.DataSourceGenerator;
|
||||
import pro.taskana.sampledata.SampleDataGenerator;
|
||||
|
||||
|
@ -89,9 +88,7 @@ class TaskanaSecurityConfigAccTest {
|
|||
|
||||
String selectSecurityFlagSql =
|
||||
String.format(
|
||||
SecurityVerifier.SELECT_SECURITY_FLAG_SQL,
|
||||
SecurityVerifier.SECURITY_FLAG_COLUMN_NAME,
|
||||
DataSourceGenerator.getSchemaName());
|
||||
"SELECT ENFORCE_SECURITY FROM %s.CONFIGURATION", DataSourceGenerator.getSchemaName());
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery(selectSecurityFlagSql);
|
||||
|
@ -110,9 +107,8 @@ class TaskanaSecurityConfigAccTest {
|
|||
|
||||
String sql =
|
||||
String.format(
|
||||
SecurityVerifier.INSERT_SECURITY_FLAG_SQL,
|
||||
DataSourceGenerator.getSchemaName(),
|
||||
securityFlag);
|
||||
"INSERT INTO %s.CONFIGURATION (ENFORCE_SECURITY) VALUES (%b)",
|
||||
DataSourceGenerator.getSchemaName(), securityFlag);
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
statement.execute(sql);
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.time.Instant;
|
|||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import javax.sql.DataSource;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
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.task.internal.jobs.TaskCleanupJob;
|
||||
|
||||
@Disabled
|
||||
class JobRunnerAccTest extends AbstractAccTest {
|
||||
|
||||
private final JobServiceImpl jobService = (JobServiceImpl) taskanaEngine.getJobService();
|
||||
|
@ -38,8 +40,8 @@ class JobRunnerAccTest extends AbstractAccTest {
|
|||
runInThread(
|
||||
() -> {
|
||||
try {
|
||||
TaskanaEngine taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
||||
TaskanaEngine taskanaEngine =
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||
DataSource dataSource = DataSourceGenerator.getDataSource();
|
||||
// We have to slow down the transaction.
|
||||
// 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.isTopLevelClass;
|
||||
|
||||
import acceptance.TaskanaEngineProxy;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||
import org.junit.jupiter.api.extension.ExtensionContext.Store;
|
||||
import org.junit.jupiter.api.extension.TestInstancePostProcessor;
|
||||
|
@ -20,11 +22,15 @@ import testapi.util.ServiceProviderExtractor;
|
|||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.JobService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||
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.TaskanaEngineImpl;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
|
@ -64,9 +70,9 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
|||
.forEach(
|
||||
(spi, 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));
|
||||
}
|
||||
|
@ -85,17 +91,21 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
|||
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();
|
||||
TaskanaEngineProxy taskanaEngineProxy = new TaskanaEngineProxy(taskanaEngine);
|
||||
MonitorService monitorService = taskanaEngine.getMonitorService();
|
||||
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
|
||||
ClassificationService classificationService = taskanaEngine.getClassificationService();
|
||||
JobService jobService = taskanaEngine.getJobService();
|
||||
CurrentUserContext currentUserContext = taskanaEngine.getCurrentUserContext();
|
||||
SqlSession sqlSession = taskanaEngineProxy.getSqlSession();
|
||||
return Map.ofEntries(
|
||||
Map.entry(TaskanaEngineConfiguration.class, taskanaEngine.getConfiguration()),
|
||||
Map.entry(TaskanaEngineImpl.class, taskanaEngine),
|
||||
Map.entry(TaskanaEngine.class, taskanaEngine),
|
||||
Map.entry(InternalTaskanaEngine.class, taskanaEngineProxy.getEngine()),
|
||||
Map.entry(TaskService.class, taskService),
|
||||
Map.entry(TaskServiceImpl.class, taskService),
|
||||
Map.entry(MonitorService.class, monitorService),
|
||||
|
@ -104,10 +114,13 @@ public class TaskanaInitializationExtension implements TestInstancePostProcessor
|
|||
Map.entry(WorkbasketServiceImpl.class, workbasketService),
|
||||
Map.entry(ClassificationService.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(JobServiceImpl.class, jobService),
|
||||
Map.entry(CurrentUserContext.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.classification.api.ClassificationService;
|
||||
import pro.taskana.classification.internal.ClassificationServiceImpl;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.JobService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.WorkingDaysToDaysConverter;
|
||||
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.TaskanaEngineImpl;
|
||||
import pro.taskana.common.internal.security.CurrentUserContextImpl;
|
||||
|
@ -31,6 +35,7 @@ class TaskanaDependencyInjectionExtensionTest {
|
|||
@TaskanaInject TaskanaEngine taskanaEngine;
|
||||
@TaskanaInject TaskanaEngine taskanaEngine2;
|
||||
@TaskanaInject TaskanaEngineImpl taskanaEngineImpl;
|
||||
@TaskanaInject InternalTaskanaEngine internalTaskanaEngine;
|
||||
@TaskanaInject ClassificationService classificationService;
|
||||
@TaskanaInject ClassificationServiceImpl classificationServiceImpl;
|
||||
@TaskanaInject WorkbasketService workbasketService;
|
||||
|
@ -41,9 +46,12 @@ class TaskanaDependencyInjectionExtensionTest {
|
|||
@TaskanaInject MonitorServiceImpl monitorServiceImpl;
|
||||
@TaskanaInject JobService jobService;
|
||||
@TaskanaInject JobServiceImpl jobServiceImpl;
|
||||
@TaskanaInject ConfigurationService configurationService;
|
||||
@TaskanaInject ConfigurationServiceImpl configurationServiceImpl;
|
||||
@TaskanaInject WorkingDaysToDaysConverter workingDaysToDaysConverter;
|
||||
@TaskanaInject CurrentUserContext currentUserContext;
|
||||
@TaskanaInject CurrentUserContextImpl currentUserContextImpl;
|
||||
@TaskanaInject ConfigurationMapper configurationMapper;
|
||||
|
||||
@Test
|
||||
void should_NotInjectTaskanaEngineConfiguration_When_FieldIsNotAnnotated() {
|
||||
|
@ -73,6 +81,12 @@ class TaskanaDependencyInjectionExtensionTest {
|
|||
assertThat(taskanaEngineImpl).isSameAs(this.taskanaEngineImpl).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectInternalTaskanaEngine_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
InternalTaskanaEngine internalTaskanaEngine) {
|
||||
assertThat(internalTaskanaEngine).isSameAs(this.internalTaskanaEngine).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_InjectClassificationService_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
ClassificationService classificationService) {
|
||||
|
@ -132,6 +146,18 @@ class TaskanaDependencyInjectionExtensionTest {
|
|||
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
|
||||
void should_InjectWorkingDaysToDaysConverter_When_FieldIsAnnotatedOrDeclaredAsParameter(
|
||||
WorkingDaysToDaysConverter workingDaysToDaysConverter) {
|
||||
|
@ -149,4 +175,10 @@ class TaskanaDependencyInjectionExtensionTest {
|
|||
CurrentUserContextImpl currentUserContextImpl) {
|
||||
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>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>pro.taskana</groupId>
|
||||
<artifactId>taskana-spring</artifactId>
|
||||
|
@ -44,6 +41,17 @@
|
|||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.sql.SQLException;
|
|||
import javax.sql.DataSource;
|
||||
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.TaskanaEngine.ConnectionManagementMode;
|
||||
import pro.taskana.common.internal.SpringTaskanaEngineImpl;
|
||||
|
||||
/** This class configures the TaskanaEngineConfiguration for spring. */
|
||||
|
@ -41,7 +42,7 @@ public class SpringTaskanaEngineConfiguration extends TaskanaEngineConfiguration
|
|||
@Override
|
||||
public TaskanaEngine buildTaskanaEngine() throws SQLException {
|
||||
this.useManagedTransactions = true;
|
||||
return new SpringTaskanaEngineImpl(this);
|
||||
return new SpringTaskanaEngineImpl(this, ConnectionManagementMode.PARTICIPATE);
|
||||
}
|
||||
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
|
|
|
@ -9,9 +9,10 @@ import pro.taskana.SpringTaskanaEngineConfiguration;
|
|||
/** This class configures the TaskanaEngine for spring. */
|
||||
public class SpringTaskanaEngineImpl extends TaskanaEngineImpl {
|
||||
|
||||
public SpringTaskanaEngineImpl(SpringTaskanaEngineConfiguration taskanaEngineConfiguration)
|
||||
public SpringTaskanaEngineImpl(
|
||||
SpringTaskanaEngineConfiguration taskanaEngineConfiguration, ConnectionManagementMode mode)
|
||||
throws SQLException {
|
||||
super(taskanaEngineConfiguration);
|
||||
super(taskanaEngineConfiguration, mode);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
package pro.taskana.example.rest.controllers;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
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.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import pro.taskana.common.internal.util.ResourceUtil;
|
||||
|
||||
@Controller
|
||||
public class ResourcesController {
|
||||
|
||||
|
@ -32,14 +29,10 @@ public class ResourcesController {
|
|||
// }
|
||||
|
||||
private String readResourceAsString(String resource) throws IOException {
|
||||
try (InputStream fileStream = getClass().getResourceAsStream(resource)) {
|
||||
if (fileStream == null) {
|
||||
return "{}";
|
||||
}
|
||||
try (Reader inputStreamReader = new InputStreamReader(fileStream);
|
||||
BufferedReader reader = new BufferedReader(inputStreamReader)) {
|
||||
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
|
||||
}
|
||||
String resourceAsString = ResourceUtil.readResourceAsString(getClass(), resource);
|
||||
if (resourceAsString == null) {
|
||||
return "{}";
|
||||
}
|
||||
return resourceAsString;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|||
import pro.taskana.SpringTaskanaEngineConfiguration;
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.classification.api.ClassificationService;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
import pro.taskana.common.api.TaskanaEngine;
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.monitor.api.MonitorService;
|
||||
import pro.taskana.task.api.TaskService;
|
||||
import pro.taskana.user.api.UserService;
|
||||
|
@ -58,6 +60,16 @@ public class RestConfiguration {
|
|||
return taskanaEngine.getUserService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConfigurationService configurationService(TaskanaEngine taskanaEngine) {
|
||||
return taskanaEngine.getConfigurationService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CurrentUserContext currentUserContext(TaskanaEngine taskanaEngine) {
|
||||
return taskanaEngine.getCurrentUserContext();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(TaskanaEngine.class)
|
||||
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration)
|
||||
|
|
|
@ -14,6 +14,7 @@ public final class RestEndpoints {
|
|||
public static final String URL_CLASSIFICATION_CATEGORIES_BY_TYPES =
|
||||
API_V1 + "classifications-by-type";
|
||||
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
|
||||
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.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
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.RestController;
|
||||
|
||||
import pro.taskana.TaskanaEngineConfiguration;
|
||||
import pro.taskana.common.api.ConfigurationService;
|
||||
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.VersionRepresentationModel;
|
||||
|
||||
|
@ -20,13 +26,20 @@ import pro.taskana.common.rest.models.VersionRepresentationModel;
|
|||
public class TaskanaEngineController {
|
||||
|
||||
private final TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
private final TaskanaEngine taskanaEngine;
|
||||
private final CurrentUserContext currentUserContext;
|
||||
private final ConfigurationService configurationService;
|
||||
|
||||
@Autowired
|
||||
TaskanaEngineController(
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration, TaskanaEngine taskanaEngine) {
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration,
|
||||
TaskanaEngine taskanaEngine,
|
||||
CurrentUserContext currentUserContext,
|
||||
ConfigurationService configurationService) {
|
||||
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
||||
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
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_DOMAIN)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<List<String>> getDomains() {
|
||||
return ResponseEntity.ok(taskanaEngineConfiguration.getDomains());
|
||||
}
|
||||
|
@ -48,6 +62,7 @@ public class TaskanaEngineController {
|
|||
* @return the classification categories for the requested type.
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<List<String>> getClassificationCategories(
|
||||
@RequestParam(required = false) String type) {
|
||||
if (type != null) {
|
||||
|
@ -62,6 +77,7 @@ public class TaskanaEngineController {
|
|||
* @return the configured classification types.
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_TYPES)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<List<String>> getClassificationTypes() {
|
||||
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationTypes());
|
||||
}
|
||||
|
@ -73,6 +89,7 @@ public class TaskanaEngineController {
|
|||
* @return the configured classification categories
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_CLASSIFICATION_CATEGORIES_BY_TYPES)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<Map<String, List<String>>> getClassificationCategoriesByTypeMap() {
|
||||
return ResponseEntity.ok(taskanaEngineConfiguration.getClassificationCategoriesByTypeMap());
|
||||
}
|
||||
|
@ -83,15 +100,14 @@ public class TaskanaEngineController {
|
|||
* @return the information of the current user.
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_CURRENT_USER)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<TaskanaUserInfoRepresentationModel> getCurrentUserInfo() {
|
||||
TaskanaUserInfoRepresentationModel resource = new TaskanaUserInfoRepresentationModel();
|
||||
resource.setUserId(taskanaEngine.getCurrentUserContext().getUserid());
|
||||
resource.setGroupIds(taskanaEngine.getCurrentUserContext().getGroupIds());
|
||||
for (TaskanaRole role : taskanaEngineConfiguration.getRoleMap().keySet()) {
|
||||
if (taskanaEngine.isUserInRole(role)) {
|
||||
resource.getRoles().add(role);
|
||||
}
|
||||
}
|
||||
resource.setUserId(currentUserContext.getUserid());
|
||||
resource.setGroupIds(currentUserContext.getGroupIds());
|
||||
taskanaEngineConfiguration.getRoleMap().keySet().stream()
|
||||
.filter(taskanaEngine::isUserInRole)
|
||||
.forEach(resource.getRoles()::add);
|
||||
return ResponseEntity.ok(resource);
|
||||
}
|
||||
|
||||
|
@ -101,16 +117,33 @@ public class TaskanaEngineController {
|
|||
* @return true, when the history is enabled, otherwise false
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_HISTORY_ENABLED)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<Boolean> getIsHistoryProviderEnabled() {
|
||||
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.
|
||||
*
|
||||
* @return The current version.
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_VERSION)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<VersionRepresentationModel> currentVersion() {
|
||||
VersionRepresentationModel resource = new VersionRepresentationModel();
|
||||
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 pro.taskana.common.api.TaskanaRole;
|
||||
import pro.taskana.common.rest.models.CustomAttributesRepresentationModel;
|
||||
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
|
||||
import pro.taskana.common.test.rest.RestHelper;
|
||||
import pro.taskana.common.test.rest.TaskanaSpringBootTest;
|
||||
|
@ -32,7 +33,7 @@ class TaskanaEngineControllerIntTest {
|
|||
@Test
|
||||
void testDomains() {
|
||||
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 =
|
||||
TEMPLATE.exchange(
|
||||
|
@ -43,7 +44,7 @@ class TaskanaEngineControllerIntTest {
|
|||
@Test
|
||||
void testClassificationTypes() {
|
||||
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 =
|
||||
TEMPLATE.exchange(
|
||||
|
@ -54,7 +55,7 @@ class TaskanaEngineControllerIntTest {
|
|||
@Test
|
||||
void testClassificationCategories() {
|
||||
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 =
|
||||
TEMPLATE.exchange(
|
||||
|
@ -66,7 +67,7 @@ class TaskanaEngineControllerIntTest {
|
|||
@Test
|
||||
void testGetCurrentUserInfo() {
|
||||
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 =
|
||||
TEMPLATE.exchange(
|
||||
|
@ -81,4 +82,19 @@ class TaskanaEngineControllerIntTest {
|
|||
assertThat(response.getBody().getRoles()).contains(TaskanaRole.BUSINESS_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();
|
||||
sampleDataGenerator.clearDb();
|
||||
sampleDataGenerator.generateTestData();
|
||||
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
|
||||
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
|
||||
taskanaEngine =
|
||||
taskanaEngineConfiguration.buildTaskanaEngine(ConnectionManagementMode.AUTOCOMMIT);
|
||||
converter = taskanaEngine.getWorkingDaysToDaysConverter();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue