From e6f8883e4911704f16404846fe4208ee3abb2adc Mon Sep 17 00:00:00 2001 From: Holger Hagen <19706592+holgerhagen@users.noreply.github.com> Date: Wed, 5 Feb 2020 09:46:57 +0100 Subject: [PATCH] TSK-1031: removed unnecessary throws statements --- .../internal/jobs/WorkbasketCleanupJob.java | 295 +++++---- .../taskana/rest/ExampleRestApplication.java | 147 +++-- .../taskana/rest/ExampleRestApplication.java | 147 +++-- .../taskana/TaskanaWildFlyApplication.java | 243 ++++--- .../security/WildflyWebSecurityConfig.java | 406 ++++++------ .../taskana/rest/WorkbasketController.java | 6 +- .../rest/ClassificationControllerIntTest.java | 604 +++++++++--------- .../taskana/rest/ExampleDocumentationApp.java | 145 +++-- ...WorkbasketDefinitionControllerIntTest.java | 560 ++++++++-------- .../WorkbasketResourceAssemblerTest.java | 278 ++++---- 10 files changed, 1410 insertions(+), 1421 deletions(-) diff --git a/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/WorkbasketCleanupJob.java b/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/WorkbasketCleanupJob.java index 06c67fc23..54df71841 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/WorkbasketCleanupJob.java +++ b/lib/taskana-core/src/main/java/pro/taskana/common/internal/jobs/WorkbasketCleanupJob.java @@ -1,149 +1,146 @@ -package pro.taskana.common.internal.jobs; - -import java.time.Duration; -import java.time.Instant; -import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import pro.taskana.common.api.BaseQuery; -import pro.taskana.common.api.BulkOperationResults; -import pro.taskana.common.api.ScheduledJob; -import pro.taskana.common.api.TaskanaEngine; -import pro.taskana.common.api.exceptions.InvalidArgumentException; -import pro.taskana.common.api.exceptions.NotAuthorizedException; -import pro.taskana.common.api.exceptions.TaskanaException; -import pro.taskana.common.internal.transaction.TaskanaTransactionProvider; -import pro.taskana.workbasket.api.WorkbasketQueryColumnName; -import pro.taskana.workbasket.api.exceptions.WorkbasketInUseException; -import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException; - -/** - * Job to cleanup completed workbaskets after a period of time if there are no pending tasks - * associated to the workbasket. - */ -public class WorkbasketCleanupJob extends AbstractTaskanaJob { - - private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketCleanupJob.class); - - // Parameter - private Instant firstRun; - private Duration runEvery; - private int batchSize; - - public WorkbasketCleanupJob( - TaskanaEngine taskanaEngine, - TaskanaTransactionProvider txProvider, - ScheduledJob job) { - super(taskanaEngine, txProvider, job); - firstRun = taskanaEngine.getConfiguration().getCleanupJobFirstRun(); - runEvery = taskanaEngine.getConfiguration().getCleanupJobRunEvery(); - batchSize = taskanaEngine.getConfiguration().getMaxNumberOfUpdatesPerTransaction(); - } - - @Override - public void run() throws TaskanaException { - LOGGER.info("Running job to delete all workbaskets marked for deletion"); - try { - List workbasketsMarkedForDeletion = getWorkbasketsMarkedForDeletion(); - int totalNumberOfWorkbasketDeleted = 0; - while (workbasketsMarkedForDeletion.size() > 0) { - int upperLimit = batchSize; - if (upperLimit > workbasketsMarkedForDeletion.size()) { - upperLimit = workbasketsMarkedForDeletion.size(); - } - totalNumberOfWorkbasketDeleted += - deleteWorkbasketsTransactionally(workbasketsMarkedForDeletion.subList(0, upperLimit)); - workbasketsMarkedForDeletion.subList(0, upperLimit).clear(); - } - LOGGER.info( - "Job ended successfully. {} workbaskets deleted.", totalNumberOfWorkbasketDeleted); - } catch (Exception e) { - throw new TaskanaException("Error while processing WorkbasketCleanupJob.", e); - } finally { - scheduleNextCleanupJob(); - } - } - - /** - * Initializes the WorkbasketCleanupJob schedule.
- * All scheduled cleanup jobs are cancelled/deleted and a new one is scheduled. - * - * @param taskanaEngine the taskana engine - */ - public static void initializeSchedule(TaskanaEngine taskanaEngine) { - WorkbasketCleanupJob job = new WorkbasketCleanupJob(taskanaEngine, null, null); - job.scheduleNextCleanupJob(); - } - - private List getWorkbasketsMarkedForDeletion() { - List workbasketList = - taskanaEngineImpl - .getWorkbasketService() - .createWorkbasketQuery() - .markedForDeletion(true) - .listValues(WorkbasketQueryColumnName.ID, BaseQuery.SortDirection.ASCENDING); - - return workbasketList; - } - - private int deleteWorkbasketsTransactionally(List workbasketsToBeDeleted) { - int deletedWorkbasketsCount = 0; - if (txProvider != null) { - int count = - (Integer) - txProvider.executeInTransaction( - () -> { - try { - return deleteWorkbaskets(workbasketsToBeDeleted); - } catch (Exception e) { - LOGGER.warn("Could not delete workbaskets.", e); - return 0; - } - }); - return count; - } else { - try { - deletedWorkbasketsCount = deleteWorkbaskets(workbasketsToBeDeleted); - } catch (Exception e) { - LOGGER.warn("Could not delete workbaskets.", e); - } - } - return deletedWorkbasketsCount; - } - - private int deleteWorkbaskets(List workbasketsToBeDeleted) - throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException, - WorkbasketInUseException { - - BulkOperationResults results = - taskanaEngineImpl.getWorkbasketService().deleteWorkbaskets(workbasketsToBeDeleted); - LOGGER.debug( - "{} workbasket deleted.", workbasketsToBeDeleted.size() - results.getFailedIds().size()); - for (String failedId : results.getFailedIds()) { - LOGGER.warn( - "Workbasket with id {} could not be deleted. Reason: {}", - failedId, - results.getErrorForId(failedId)); - } - return workbasketsToBeDeleted.size() - results.getFailedIds().size(); - } - - private void scheduleNextCleanupJob() { - LOGGER.debug("Entry to scheduleNextCleanupJob."); - ScheduledJob job = new ScheduledJob(); - job.setType(ScheduledJob.Type.WORKBASKETCLEANUPJOB); - job.setDue(getNextDueForWorkbasketCleanupJob()); - taskanaEngineImpl.getJobService().createJob(job); - LOGGER.debug("Exit from scheduleNextCleanupJob."); - } - - private Instant getNextDueForWorkbasketCleanupJob() { - Instant nextRunAt = firstRun; - while (nextRunAt.isBefore(Instant.now())) { - nextRunAt = nextRunAt.plus(runEvery); - } - LOGGER.info("Scheduling next run of the WorkbasketCleanupJob for {}", nextRunAt); - return nextRunAt; - } -} +package pro.taskana.common.internal.jobs; + +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import pro.taskana.common.api.BaseQuery; +import pro.taskana.common.api.BulkOperationResults; +import pro.taskana.common.api.ScheduledJob; +import pro.taskana.common.api.TaskanaEngine; +import pro.taskana.common.api.exceptions.InvalidArgumentException; +import pro.taskana.common.api.exceptions.NotAuthorizedException; +import pro.taskana.common.api.exceptions.TaskanaException; +import pro.taskana.common.internal.transaction.TaskanaTransactionProvider; +import pro.taskana.workbasket.api.WorkbasketQueryColumnName; + +/** + * Job to cleanup completed workbaskets after a period of time if there are no pending tasks + * associated to the workbasket. + */ +public class WorkbasketCleanupJob extends AbstractTaskanaJob { + + private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketCleanupJob.class); + + // Parameter + private Instant firstRun; + private Duration runEvery; + private int batchSize; + + public WorkbasketCleanupJob( + TaskanaEngine taskanaEngine, + TaskanaTransactionProvider txProvider, + ScheduledJob job) { + super(taskanaEngine, txProvider, job); + firstRun = taskanaEngine.getConfiguration().getCleanupJobFirstRun(); + runEvery = taskanaEngine.getConfiguration().getCleanupJobRunEvery(); + batchSize = taskanaEngine.getConfiguration().getMaxNumberOfUpdatesPerTransaction(); + } + + @Override + public void run() throws TaskanaException { + LOGGER.info("Running job to delete all workbaskets marked for deletion"); + try { + List workbasketsMarkedForDeletion = getWorkbasketsMarkedForDeletion(); + int totalNumberOfWorkbasketDeleted = 0; + while (workbasketsMarkedForDeletion.size() > 0) { + int upperLimit = batchSize; + if (upperLimit > workbasketsMarkedForDeletion.size()) { + upperLimit = workbasketsMarkedForDeletion.size(); + } + totalNumberOfWorkbasketDeleted += + deleteWorkbasketsTransactionally(workbasketsMarkedForDeletion.subList(0, upperLimit)); + workbasketsMarkedForDeletion.subList(0, upperLimit).clear(); + } + LOGGER.info( + "Job ended successfully. {} workbaskets deleted.", totalNumberOfWorkbasketDeleted); + } catch (Exception e) { + throw new TaskanaException("Error while processing WorkbasketCleanupJob.", e); + } finally { + scheduleNextCleanupJob(); + } + } + + /** + * Initializes the WorkbasketCleanupJob schedule.
+ * All scheduled cleanup jobs are cancelled/deleted and a new one is scheduled. + * + * @param taskanaEngine the taskana engine + */ + public static void initializeSchedule(TaskanaEngine taskanaEngine) { + WorkbasketCleanupJob job = new WorkbasketCleanupJob(taskanaEngine, null, null); + job.scheduleNextCleanupJob(); + } + + private List getWorkbasketsMarkedForDeletion() { + List workbasketList = + taskanaEngineImpl + .getWorkbasketService() + .createWorkbasketQuery() + .markedForDeletion(true) + .listValues(WorkbasketQueryColumnName.ID, BaseQuery.SortDirection.ASCENDING); + + return workbasketList; + } + + private int deleteWorkbasketsTransactionally(List workbasketsToBeDeleted) { + int deletedWorkbasketsCount = 0; + if (txProvider != null) { + int count = + (Integer) + txProvider.executeInTransaction( + () -> { + try { + return deleteWorkbaskets(workbasketsToBeDeleted); + } catch (Exception e) { + LOGGER.warn("Could not delete workbaskets.", e); + return 0; + } + }); + return count; + } else { + try { + deletedWorkbasketsCount = deleteWorkbaskets(workbasketsToBeDeleted); + } catch (Exception e) { + LOGGER.warn("Could not delete workbaskets.", e); + } + } + return deletedWorkbasketsCount; + } + + private int deleteWorkbaskets(List workbasketsToBeDeleted) + throws InvalidArgumentException, NotAuthorizedException { + + BulkOperationResults results = + taskanaEngineImpl.getWorkbasketService().deleteWorkbaskets(workbasketsToBeDeleted); + LOGGER.debug( + "{} workbasket deleted.", workbasketsToBeDeleted.size() - results.getFailedIds().size()); + for (String failedId : results.getFailedIds()) { + LOGGER.warn( + "Workbasket with id {} could not be deleted. Reason: {}", + failedId, + results.getErrorForId(failedId)); + } + return workbasketsToBeDeleted.size() - results.getFailedIds().size(); + } + + private void scheduleNextCleanupJob() { + LOGGER.debug("Entry to scheduleNextCleanupJob."); + ScheduledJob job = new ScheduledJob(); + job.setType(ScheduledJob.Type.WORKBASKETCLEANUPJOB); + job.setDue(getNextDueForWorkbasketCleanupJob()); + taskanaEngineImpl.getJobService().createJob(job); + LOGGER.debug("Exit from scheduleNextCleanupJob."); + } + + private Instant getNextDueForWorkbasketCleanupJob() { + Instant nextRunAt = firstRun; + while (nextRunAt.isBefore(Instant.now())) { + nextRunAt = nextRunAt.plus(runEvery); + } + LOGGER.info("Scheduling next run of the WorkbasketCleanupJob for {}", nextRunAt); + return nextRunAt; + } +} diff --git a/rest/taskana-rest-spring-example-boot/src/main/java/pro/taskana/rest/ExampleRestApplication.java b/rest/taskana-rest-spring-example-boot/src/main/java/pro/taskana/rest/ExampleRestApplication.java index afc11f972..4846b27cd 100644 --- a/rest/taskana-rest-spring-example-boot/src/main/java/pro/taskana/rest/ExampleRestApplication.java +++ b/rest/taskana-rest-spring-example-boot/src/main/java/pro/taskana/rest/ExampleRestApplication.java @@ -1,74 +1,73 @@ -package pro.taskana.rest; - -import java.sql.SQLException; -import javax.annotation.PostConstruct; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.Import; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.transaction.PlatformTransactionManager; - -import pro.taskana.jobs.TransactionalJobsConfiguration; -import pro.taskana.ldap.LdapCacheTestImpl; -import pro.taskana.ldap.LdapClient; -import pro.taskana.ldap.LdapConfiguration; -import pro.taskana.sampledata.SampleDataGenerator; - -/** Example Application showing the implementation of taskana-rest-spring. */ -@SpringBootApplication -@EnableScheduling -@ComponentScan(basePackages = "pro.taskana") -@SuppressWarnings("checkstyle:Indentation") -@Import({ - TransactionalJobsConfiguration.class, - LdapConfiguration.class, - RestConfiguration.class, - WebMvcConfig.class -}) -public class ExampleRestApplication { - - @Value("${taskana.schemaName:TASKANA}") - public String schemaName; - - @Value("${generateSampleData:true}") - public boolean generateSampleData; - - @Autowired private SampleDataGenerator sampleDataGenerator; - - @Autowired private LdapClient ldapClient; - - @Autowired private LdapCacheTestImpl ldapCacheTest; - - public static void main(String[] args) { - SpringApplication.run(ExampleRestApplication.class, args); - } - - @Bean - public PlatformTransactionManager txManager(DataSource dataSource) { - return new DataSourceTransactionManager(dataSource); - } - - @Bean - @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted - public SampleDataGenerator generateSampleData(DataSource dataSource) { - sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - return sampleDataGenerator; - } - - @PostConstruct - private void init() throws SQLException { - if (!ldapClient.useLdap()) { - AccessIdController.setLdapCache(ldapCacheTest); - } - if (generateSampleData) { - sampleDataGenerator.generateSampleData(); - } - } -} +package pro.taskana.rest; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Import; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.PlatformTransactionManager; + +import pro.taskana.jobs.TransactionalJobsConfiguration; +import pro.taskana.ldap.LdapCacheTestImpl; +import pro.taskana.ldap.LdapClient; +import pro.taskana.ldap.LdapConfiguration; +import pro.taskana.sampledata.SampleDataGenerator; + +/** Example Application showing the implementation of taskana-rest-spring. */ +@SpringBootApplication +@EnableScheduling +@ComponentScan(basePackages = "pro.taskana") +@SuppressWarnings("checkstyle:Indentation") +@Import({ + TransactionalJobsConfiguration.class, + LdapConfiguration.class, + RestConfiguration.class, + WebMvcConfig.class +}) +public class ExampleRestApplication { + + @Value("${taskana.schemaName:TASKANA}") + public String schemaName; + + @Value("${generateSampleData:true}") + public boolean generateSampleData; + + @Autowired private SampleDataGenerator sampleDataGenerator; + + @Autowired private LdapClient ldapClient; + + @Autowired private LdapCacheTestImpl ldapCacheTest; + + public static void main(String[] args) { + SpringApplication.run(ExampleRestApplication.class, args); + } + + @Bean + public PlatformTransactionManager txManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean + @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted + public SampleDataGenerator generateSampleData(DataSource dataSource) { + sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + return sampleDataGenerator; + } + + @PostConstruct + private void init() { + if (!ldapClient.useLdap()) { + AccessIdController.setLdapCache(ldapCacheTest); + } + if (generateSampleData) { + sampleDataGenerator.generateSampleData(); + } + } +} diff --git a/rest/taskana-rest-spring-example-common/src/test/java/pro/taskana/rest/ExampleRestApplication.java b/rest/taskana-rest-spring-example-common/src/test/java/pro/taskana/rest/ExampleRestApplication.java index afc11f972..4846b27cd 100644 --- a/rest/taskana-rest-spring-example-common/src/test/java/pro/taskana/rest/ExampleRestApplication.java +++ b/rest/taskana-rest-spring-example-common/src/test/java/pro/taskana/rest/ExampleRestApplication.java @@ -1,74 +1,73 @@ -package pro.taskana.rest; - -import java.sql.SQLException; -import javax.annotation.PostConstruct; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.Import; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.transaction.PlatformTransactionManager; - -import pro.taskana.jobs.TransactionalJobsConfiguration; -import pro.taskana.ldap.LdapCacheTestImpl; -import pro.taskana.ldap.LdapClient; -import pro.taskana.ldap.LdapConfiguration; -import pro.taskana.sampledata.SampleDataGenerator; - -/** Example Application showing the implementation of taskana-rest-spring. */ -@SpringBootApplication -@EnableScheduling -@ComponentScan(basePackages = "pro.taskana") -@SuppressWarnings("checkstyle:Indentation") -@Import({ - TransactionalJobsConfiguration.class, - LdapConfiguration.class, - RestConfiguration.class, - WebMvcConfig.class -}) -public class ExampleRestApplication { - - @Value("${taskana.schemaName:TASKANA}") - public String schemaName; - - @Value("${generateSampleData:true}") - public boolean generateSampleData; - - @Autowired private SampleDataGenerator sampleDataGenerator; - - @Autowired private LdapClient ldapClient; - - @Autowired private LdapCacheTestImpl ldapCacheTest; - - public static void main(String[] args) { - SpringApplication.run(ExampleRestApplication.class, args); - } - - @Bean - public PlatformTransactionManager txManager(DataSource dataSource) { - return new DataSourceTransactionManager(dataSource); - } - - @Bean - @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted - public SampleDataGenerator generateSampleData(DataSource dataSource) { - sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - return sampleDataGenerator; - } - - @PostConstruct - private void init() throws SQLException { - if (!ldapClient.useLdap()) { - AccessIdController.setLdapCache(ldapCacheTest); - } - if (generateSampleData) { - sampleDataGenerator.generateSampleData(); - } - } -} +package pro.taskana.rest; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Import; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.PlatformTransactionManager; + +import pro.taskana.jobs.TransactionalJobsConfiguration; +import pro.taskana.ldap.LdapCacheTestImpl; +import pro.taskana.ldap.LdapClient; +import pro.taskana.ldap.LdapConfiguration; +import pro.taskana.sampledata.SampleDataGenerator; + +/** Example Application showing the implementation of taskana-rest-spring. */ +@SpringBootApplication +@EnableScheduling +@ComponentScan(basePackages = "pro.taskana") +@SuppressWarnings("checkstyle:Indentation") +@Import({ + TransactionalJobsConfiguration.class, + LdapConfiguration.class, + RestConfiguration.class, + WebMvcConfig.class +}) +public class ExampleRestApplication { + + @Value("${taskana.schemaName:TASKANA}") + public String schemaName; + + @Value("${generateSampleData:true}") + public boolean generateSampleData; + + @Autowired private SampleDataGenerator sampleDataGenerator; + + @Autowired private LdapClient ldapClient; + + @Autowired private LdapCacheTestImpl ldapCacheTest; + + public static void main(String[] args) { + SpringApplication.run(ExampleRestApplication.class, args); + } + + @Bean + public PlatformTransactionManager txManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean + @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted + public SampleDataGenerator generateSampleData(DataSource dataSource) { + sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + return sampleDataGenerator; + } + + @PostConstruct + private void init() { + if (!ldapClient.useLdap()) { + AccessIdController.setLdapCache(ldapCacheTest); + } + if (generateSampleData) { + sampleDataGenerator.generateSampleData(); + } + } +} diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/TaskanaWildFlyApplication.java b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/TaskanaWildFlyApplication.java index 1e653ebc4..63a2cf7d9 100644 --- a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/TaskanaWildFlyApplication.java +++ b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/TaskanaWildFlyApplication.java @@ -1,122 +1,121 @@ -package pro.taskana; - -import java.io.InputStream; -import java.sql.SQLException; -import java.util.Properties; -import javax.annotation.PostConstruct; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.transaction.PlatformTransactionManager; - -import pro.taskana.jobs.TransactionalJobsConfiguration; -import pro.taskana.ldap.LdapCacheTestImpl; -import pro.taskana.ldap.LdapClient; -import pro.taskana.ldap.LdapConfiguration; -import pro.taskana.rest.AccessIdController; -import pro.taskana.rest.RestConfiguration; -import pro.taskana.rest.WebMvcConfig; -import pro.taskana.sampledata.SampleDataGenerator; - -/** - * Example Application showing the implementation of taskana-rest-spring for jboss application - * server. - */ -@SpringBootApplication -@EnableScheduling -@SuppressWarnings("checkstyle:Indentation") -@Import({ - TransactionalJobsConfiguration.class, - LdapConfiguration.class, - RestConfiguration.class, - WebMvcConfig.class -}) -public class TaskanaWildFlyApplication extends SpringBootServletInitializer { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaWildFlyApplication.class); - - @Value("${taskana.schemaName:TASKANA}") - public String schemaName; - - @Value("${generateSampleData:true}") - public boolean generateSampleData; - - @Autowired private SampleDataGenerator sampleDataGenerator; - - @Autowired private LdapClient ldapClient; - - @Autowired private LdapCacheTestImpl ldapCacheTest; - - public static void main(String[] args) { - SpringApplication.run(TaskanaWildFlyApplication.class, args); - } - - @Bean - @Primary - @ConfigurationProperties(prefix = "datasource") - public DataSourceProperties dataSourceProperties() { - DataSourceProperties props = new DataSourceProperties(); - props.setUrl( - "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS " - + schemaName); - return props; - } - - @Bean - public DataSource dataSource(DataSourceProperties dsProperties) { - // First try to load Properties and get Datasource via jndi lookup - Context ctx; - DataSource dataSource; - ClassLoader classloader = Thread.currentThread().getContextClassLoader(); - try (InputStream propertyStream = classloader.getResourceAsStream("application.properties")) { - Properties properties = new Properties(); - ctx = new InitialContext(); - properties.load(propertyStream); - dataSource = (DataSource) ctx.lookup(properties.getProperty("datasource.jndi")); - return dataSource; - } catch (Exception e) { - LOGGER.error( - "Caught exception {} when attempting to start Taskana with Datasource " - + "from Jndi. Using default H2 datasource. ", - e); - return dsProperties.initializeDataSourceBuilder().build(); - } - } - - @Bean - public PlatformTransactionManager txManager(DataSource dataSource) { - return new DataSourceTransactionManager(dataSource); - } - - @Bean - @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted - public SampleDataGenerator generateSampleData(DataSource dataSource) { - sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - return sampleDataGenerator; - } - - @PostConstruct - private void init() throws SQLException { - if (!ldapClient.useLdap()) { - AccessIdController.setLdapCache(ldapCacheTest); - } - if (generateSampleData) { - sampleDataGenerator.generateSampleData(); - } - } -} +package pro.taskana; + +import java.io.InputStream; +import java.util.Properties; +import javax.annotation.PostConstruct; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.PlatformTransactionManager; + +import pro.taskana.jobs.TransactionalJobsConfiguration; +import pro.taskana.ldap.LdapCacheTestImpl; +import pro.taskana.ldap.LdapClient; +import pro.taskana.ldap.LdapConfiguration; +import pro.taskana.rest.AccessIdController; +import pro.taskana.rest.RestConfiguration; +import pro.taskana.rest.WebMvcConfig; +import pro.taskana.sampledata.SampleDataGenerator; + +/** + * Example Application showing the implementation of taskana-rest-spring for jboss application + * server. + */ +@SpringBootApplication +@EnableScheduling +@SuppressWarnings("checkstyle:Indentation") +@Import({ + TransactionalJobsConfiguration.class, + LdapConfiguration.class, + RestConfiguration.class, + WebMvcConfig.class +}) +public class TaskanaWildFlyApplication extends SpringBootServletInitializer { + + private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaWildFlyApplication.class); + + @Value("${taskana.schemaName:TASKANA}") + public String schemaName; + + @Value("${generateSampleData:true}") + public boolean generateSampleData; + + @Autowired private SampleDataGenerator sampleDataGenerator; + + @Autowired private LdapClient ldapClient; + + @Autowired private LdapCacheTestImpl ldapCacheTest; + + public static void main(String[] args) { + SpringApplication.run(TaskanaWildFlyApplication.class, args); + } + + @Bean + @Primary + @ConfigurationProperties(prefix = "datasource") + public DataSourceProperties dataSourceProperties() { + DataSourceProperties props = new DataSourceProperties(); + props.setUrl( + "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS " + + schemaName); + return props; + } + + @Bean + public DataSource dataSource(DataSourceProperties dsProperties) { + // First try to load Properties and get Datasource via jndi lookup + Context ctx; + DataSource dataSource; + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + try (InputStream propertyStream = classloader.getResourceAsStream("application.properties")) { + Properties properties = new Properties(); + ctx = new InitialContext(); + properties.load(propertyStream); + dataSource = (DataSource) ctx.lookup(properties.getProperty("datasource.jndi")); + return dataSource; + } catch (Exception e) { + LOGGER.error( + "Caught exception {} when attempting to start Taskana with Datasource " + + "from Jndi. Using default H2 datasource. ", + e); + return dsProperties.initializeDataSourceBuilder().build(); + } + } + + @Bean + public PlatformTransactionManager txManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean + @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted + public SampleDataGenerator generateSampleData(DataSource dataSource) { + sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + return sampleDataGenerator; + } + + @PostConstruct + private void init() { + if (!ldapClient.useLdap()) { + AccessIdController.setLdapCache(ldapCacheTest); + } + if (generateSampleData) { + sampleDataGenerator.generateSampleData(); + } + } +} diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java index 0656f5aeb..5036070fb 100644 --- a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java +++ b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java @@ -1,203 +1,203 @@ -package pro.taskana.wildfly.security; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.Order; -import org.springframework.http.HttpMethod; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; -import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; -import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter; -import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; -import org.wildfly.security.auth.server.SecurityDomain; -import org.wildfly.security.auth.server.SecurityIdentity; -import org.wildfly.security.authz.Roles; - -import pro.taskana.rest.security.WebSecurityConfig; - -/** - * Default basic configuration for taskana web example running on Wildfly / JBoss with Elytron or - * JAAS Security. - */ -@Configuration -@EnableWebSecurity -@Order(1) -public class WildflyWebSecurityConfig extends WebSecurityConfig { - - @Value("${devMode:false}") - private boolean devMode; - - @Bean - public J2eePreAuthenticatedProcessingFilter preAuthFilter() throws Exception { - J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter(); - filter.setAuthenticationManager(preAuthManager()); - return filter; - } - - @Bean - public AuthenticationManager preAuthManager() { - return new AuthenticationManager() { - - @Override - public Authentication authenticate(Authentication authentication) - throws AuthenticationException { - return preauthAuthProvider().authenticate(authentication); - } - }; - } - - @Bean - public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { - PreAuthenticatedAuthenticationProvider preauthAuthProvider = - new PreAuthenticatedAuthenticationProvider(); - preauthAuthProvider.setPreAuthenticatedUserDetailsService(authenticationUserDetailsService()); - return preauthAuthProvider; - } - - @Bean - public AuthenticationUserDetailsService - authenticationUserDetailsService() { - return new PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService(); - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - http.authorizeRequests() - .antMatchers("/css/**", "/img/**") - .permitAll() - .and() - .csrf() - .disable() - .httpBasic() - .and() - .authenticationProvider(preauthAuthProvider()) - .authorizeRequests() - .antMatchers(HttpMethod.GET, "/docs/**") - .permitAll() - .and() - .addFilter(preAuthFilter()) - .addFilterAfter(new ElytronToJaasFilter(), JaasApiIntegrationFilter.class) - .addFilter(jaasApiIntegrationFilter()); - - if (devMode) { - http.headers() - .frameOptions() - .sameOrigin() - .and() - .authorizeRequests() - .antMatchers("/h2-console/**") - .permitAll(); - } else { - addLoginPageConfiguration(http); - } - } - - private JaasApiIntegrationFilter jaasApiIntegrationFilter() { - JaasApiIntegrationFilter filter = new JaasApiIntegrationFilter(); - filter.setCreateEmptySubject(true); - return filter; - } - - private void addLoginPageConfiguration(HttpSecurity http) throws Exception { - http.authorizeRequests() - .anyRequest() - .fullyAuthenticated() - .and() - .formLogin() - .loginPage("/login") - .failureUrl("/login?error") - .defaultSuccessUrl("/") - .permitAll() - .and() - .logout() - .invalidateHttpSession(true) - .clearAuthentication(true) - .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) - .logoutSuccessUrl("/login?logout") - .deleteCookies("JSESSIONID") - .permitAll(); - } - - private static class PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService - implements AuthenticationUserDetailsService { - - @Override - public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) - throws UsernameNotFoundException { - return new MyUserDetails(token); - } - - private static class MyUserDetails implements UserDetails { - - private static final long serialVersionUID = 1L; - private final PreAuthenticatedAuthenticationToken token; - - public MyUserDetails(PreAuthenticatedAuthenticationToken token) { - this.token = token; - } - - @Override - public Collection getAuthorities() { - List authorities = new ArrayList<>(); - SecurityIdentity securityIdentity = getSecurityIdentity(); - if (securityIdentity != null) { - Roles roles = securityIdentity.getRoles(); - roles.forEach(role -> authorities.add(new SimpleGrantedAuthority(role))); - } - return authorities; - } - - @Override - public String getPassword() { - return (String) token.getCredentials(); - } - - @Override - public String getUsername() { - return token.getName(); - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } - - private SecurityIdentity getSecurityIdentity() { - SecurityDomain current = SecurityDomain.getCurrent(); - if (current != null) { - return current.getCurrentSecurityIdentity(); - } - return null; - } - } - } -} +package pro.taskana.wildfly.security; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpMethod; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.AuthenticationUserDetailsService; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; +import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter; +import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.wildfly.security.auth.server.SecurityDomain; +import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.authz.Roles; + +import pro.taskana.rest.security.WebSecurityConfig; + +/** + * Default basic configuration for taskana web example running on Wildfly / JBoss with Elytron or + * JAAS Security. + */ +@Configuration +@EnableWebSecurity +@Order(1) +public class WildflyWebSecurityConfig extends WebSecurityConfig { + + @Value("${devMode:false}") + private boolean devMode; + + @Bean + public J2eePreAuthenticatedProcessingFilter preAuthFilter() { + J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter(); + filter.setAuthenticationManager(preAuthManager()); + return filter; + } + + @Bean + public AuthenticationManager preAuthManager() { + return new AuthenticationManager() { + + @Override + public Authentication authenticate(Authentication authentication) + throws AuthenticationException { + return preauthAuthProvider().authenticate(authentication); + } + }; + } + + @Bean + public PreAuthenticatedAuthenticationProvider preauthAuthProvider() { + PreAuthenticatedAuthenticationProvider preauthAuthProvider = + new PreAuthenticatedAuthenticationProvider(); + preauthAuthProvider.setPreAuthenticatedUserDetailsService(authenticationUserDetailsService()); + return preauthAuthProvider; + } + + @Bean + public AuthenticationUserDetailsService + authenticationUserDetailsService() { + return new PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService(); + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/css/**", "/img/**") + .permitAll() + .and() + .csrf() + .disable() + .httpBasic() + .and() + .authenticationProvider(preauthAuthProvider()) + .authorizeRequests() + .antMatchers(HttpMethod.GET, "/docs/**") + .permitAll() + .and() + .addFilter(preAuthFilter()) + .addFilterAfter(new ElytronToJaasFilter(), JaasApiIntegrationFilter.class) + .addFilter(jaasApiIntegrationFilter()); + + if (devMode) { + http.headers() + .frameOptions() + .sameOrigin() + .and() + .authorizeRequests() + .antMatchers("/h2-console/**") + .permitAll(); + } else { + addLoginPageConfiguration(http); + } + } + + private JaasApiIntegrationFilter jaasApiIntegrationFilter() { + JaasApiIntegrationFilter filter = new JaasApiIntegrationFilter(); + filter.setCreateEmptySubject(true); + return filter; + } + + private void addLoginPageConfiguration(HttpSecurity http) throws Exception { + http.authorizeRequests() + .anyRequest() + .fullyAuthenticated() + .and() + .formLogin() + .loginPage("/login") + .failureUrl("/login?error") + .defaultSuccessUrl("/") + .permitAll() + .and() + .logout() + .invalidateHttpSession(true) + .clearAuthentication(true) + .logoutRequestMatcher(new AntPathRequestMatcher("/logout")) + .logoutSuccessUrl("/login?logout") + .deleteCookies("JSESSIONID") + .permitAll(); + } + + private static class PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService + implements AuthenticationUserDetailsService { + + @Override + public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) + throws UsernameNotFoundException { + return new MyUserDetails(token); + } + + private static class MyUserDetails implements UserDetails { + + private static final long serialVersionUID = 1L; + private final PreAuthenticatedAuthenticationToken token; + + public MyUserDetails(PreAuthenticatedAuthenticationToken token) { + this.token = token; + } + + @Override + public Collection getAuthorities() { + List authorities = new ArrayList<>(); + SecurityIdentity securityIdentity = getSecurityIdentity(); + if (securityIdentity != null) { + Roles roles = securityIdentity.getRoles(); + roles.forEach(role -> authorities.add(new SimpleGrantedAuthority(role))); + } + return authorities; + } + + @Override + public String getPassword() { + return (String) token.getCredentials(); + } + + @Override + public String getUsername() { + return token.getName(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + + private SecurityIdentity getSecurityIdentity() { + SecurityDomain current = SecurityDomain.getCurrent(); + if (current != null) { + return current.getCurrentSecurityIdentity(); + } + return null; + } + } + } +} diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java index a25f01f4e..ab9376e05 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/WorkbasketController.java @@ -156,7 +156,7 @@ public class WorkbasketController extends AbstractPagingController { public ResponseEntity createWorkbasket( @RequestBody WorkbasketResource workbasketResource) throws InvalidWorkbasketException, NotAuthorizedException, WorkbasketAlreadyExistException, - WorkbasketNotFoundException, DomainNotFoundException { + DomainNotFoundException { if (LOGGER.isDebugEnabled()) { LOGGER.debug("Entry to createWorkbasket(workbasketResource= {})", workbasketResource); } @@ -178,8 +178,8 @@ public class WorkbasketController extends AbstractPagingController { public ResponseEntity updateWorkbasket( @PathVariable(value = "workbasketId") String workbasketId, @RequestBody WorkbasketResource workbasketResource) - throws InvalidWorkbasketException, WorkbasketNotFoundException, - NotAuthorizedException, ConcurrencyException { + throws InvalidWorkbasketException, WorkbasketNotFoundException, NotAuthorizedException, + ConcurrencyException { LOGGER.debug("Entry to updateWorkbasket(workbasketId= {})", workbasketId); ResponseEntity result; if (workbasketId.equals(workbasketResource.workbasketId)) { diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java index ab22fd80e..1118e2ec5 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ClassificationControllerIntTest.java @@ -1,303 +1,301 @@ -package pro.taskana.rest; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import java.io.IOException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.hateoas.Link; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import pro.taskana.RestHelper; -import pro.taskana.TaskanaSpringBootTest; -import pro.taskana.rest.resource.ClassificationResource; -import pro.taskana.rest.resource.ClassificationSummaryListResource; -import pro.taskana.rest.resource.ClassificationSummaryResource; - -/** - * Test ClassificationController. - * - * @author bbr - */ -@TaskanaSpringBootTest -class ClassificationControllerIntTest { - - static RestTemplate template = RestHelper.getRestTemplate(); - @Autowired RestHelper restHelper; - - @Test - void testGetAllClassifications() { - ResponseEntity response = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.GET, - restHelper.defaultRequest(), - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); - assertNotNull(response.getBody().getLink(Link.REL_SELF)); - } - - @Test - void testGetAllClassificationsFilterByCustomAttribute() { - ResponseEntity response = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_A&custom-1-like=RVNR", - HttpMethod.GET, - restHelper.defaultRequest(), - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); - assertNotNull(response.getBody().getLink(Link.REL_SELF)); - assertEquals(13, response.getBody().getContent().size()); - } - - @Test - void testGetAllClassificationsKeepingFilters() { - ResponseEntity response = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) - + "?domain=DOMAIN_A&sort-by=key&order=asc", - HttpMethod.GET, - restHelper.defaultRequest(), - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); - assertNotNull(response.getBody().getLink(Link.REL_SELF)); - assertTrue( - response - .getBody() - .getLink(Link.REL_SELF) - .getHref() - .endsWith("/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc")); - assertEquals(17, response.getBody().getContent().size()); - assertEquals("A12", response.getBody().getContent().iterator().next().key); - } - - @Test - void testGetSecondPageSortedByKey() { - ResponseEntity response = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) - + "?domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5", - HttpMethod.GET, - restHelper.defaultRequest(), - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); - assertEquals(5, response.getBody().getContent().size()); - assertEquals("L1050", response.getBody().getContent().iterator().next().key); - assertNotNull(response.getBody().getLink(Link.REL_SELF)); - assertTrue( - response - .getBody() - .getLink(Link.REL_SELF) - .getHref() - .endsWith( - "/api/v1/classifications?" - + "domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5")); - assertNotNull(response.getBody().getLink(Link.REL_FIRST)); - assertNotNull(response.getBody().getLink(Link.REL_LAST)); - assertNotNull(response.getBody().getLink(Link.REL_NEXT)); - assertNotNull(response.getBody().getLink(Link.REL_PREVIOUS)); - } - - @Test - @DirtiesContext - void testCreateClassification() { - String newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\"," - + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\"," - + "\"name\":\"new classification\",\"type\":\"TASK\"}"; - - ResponseEntity responseEntity = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class)); - - assertNotNull(responseEntity); - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - - newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\"," - + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS_2\"," - + "\"name\":\"new classification\",\"type\":\"TASK\"}"; - - responseEntity = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class)); - - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - } - - @Test - @DirtiesContext - void testCreateClassificationWithParentId() { - String newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\"," - + "\"domain\":\"DOMAIN_B\",\"key\":\"NEW_CLASS_P1\"," - + "\"name\":\"new classification\",\"type\":\"TASK\"," - + "\"parentId\":\"CLI:200000000000000000000000000000000015\"}"; - - ResponseEntity responseEntity = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class)); - - assertNotNull(responseEntity); - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - } - - @Test - @DirtiesContext - @SuppressWarnings("checkstyle:LineLength") - void testCreateClassificationWithParentKey() { - String newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\"," - + "\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\"," - + "\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; - - ResponseEntity responseEntity = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class)); - - assertNotNull(responseEntity); - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - } - - @Test - @DirtiesContext - void testCreateClassificationWithParentKeyInDomain_aShouldCreateAClassificationInRootDomain() - throws IOException { - String newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\"," - + "\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\"," - + "\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; - - ResponseEntity responseEntity = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class)); - - assertNotNull(responseEntity); - assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); - - ResponseEntity response = - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.GET, - restHelper.defaultRequest(), - ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); - assertNotNull(response.getBody().getLink(Link.REL_SELF)); - boolean foundClassificationCreated = false; - for (ClassificationSummaryResource classification : response.getBody().getContent()) { - if ("NEW_CLASS_P2".equals(classification.getKey()) - && "".equals(classification.getDomain()) - && "T2100".equals(classification.getParentKey())) { - foundClassificationCreated = true; - } - } - - assertEquals(true, foundClassificationCreated); - } - - @Test - @DirtiesContext - void testReturn400IfCreateClassificationWithIncompatibleParentIdAndKey() throws IOException { - String newClassification = - "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\"," - + "\"key\":\"NEW_CLASS_P3\",\"name\":\"new classification\"," - + "\"type\":\"TASK\",\"parentId\":\"CLI:200000000000000000000000000000000015\"," - + "\"parentKey\":\"T2000\"}"; - - HttpClientErrorException e = - Assertions.assertThrows( - HttpClientErrorException.class, - () -> - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class))); - - assertNotNull(e); - assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); - } - - @Test - @DirtiesContext - void testCreateClassificationWithClassificationIdReturnsError400() throws IOException { - String newClassification = - "{\"classificationId\":\"someId\",\"category\":\"MANUAL\"," - + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\"," - + "\"name\":\"new classification\",\"type\":\"TASK\"}"; - - HttpClientErrorException e = - Assertions.assertThrows( - HttpClientErrorException.class, - () -> - template.exchange( - restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), - HttpMethod.POST, - new HttpEntity<>(newClassification, restHelper.getHeaders()), - ParameterizedTypeReference.forType(ClassificationResource.class))); - - assertNotNull(e); - assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); - } - - @Test - void testGetClassificationWithSpecialCharacter() { - - HttpEntity request = new HttpEntity(restHelper.getHeadersAdmin()); - ResponseEntity response = - template.exchange( - restHelper.toUrl( - Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"), - HttpMethod.GET, - request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); - assertEquals("Zustimmungserklärung", response.getBody().name); - } - - @Test - @DirtiesContext - void testDeleteClassification() { - HttpEntity request = new HttpEntity(restHelper.getHeaders()); - - ResponseEntity response = - template.exchange( - restHelper.toUrl( - Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), - HttpMethod.DELETE, - request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); - assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); - - assertThrows( - HttpClientErrorException.class, - () -> { - template.exchange( - restHelper.toUrl( - Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), - HttpMethod.GET, - request, - ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); - }); - } -} +package pro.taskana.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.hateoas.Link; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +import pro.taskana.RestHelper; +import pro.taskana.TaskanaSpringBootTest; +import pro.taskana.rest.resource.ClassificationResource; +import pro.taskana.rest.resource.ClassificationSummaryListResource; +import pro.taskana.rest.resource.ClassificationSummaryResource; + +/** + * Test ClassificationController. + * + * @author bbr + */ +@TaskanaSpringBootTest +class ClassificationControllerIntTest { + + static RestTemplate template = RestHelper.getRestTemplate(); + @Autowired RestHelper restHelper; + + @Test + void testGetAllClassifications() { + ResponseEntity response = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + assertNotNull(response.getBody().getLink(Link.REL_SELF)); + } + + @Test + void testGetAllClassificationsFilterByCustomAttribute() { + ResponseEntity response = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_A&custom-1-like=RVNR", + HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + assertNotNull(response.getBody().getLink(Link.REL_SELF)); + assertEquals(13, response.getBody().getContent().size()); + } + + @Test + void testGetAllClassificationsKeepingFilters() { + ResponseEntity response = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + + "?domain=DOMAIN_A&sort-by=key&order=asc", + HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + assertNotNull(response.getBody().getLink(Link.REL_SELF)); + assertTrue( + response + .getBody() + .getLink(Link.REL_SELF) + .getHref() + .endsWith("/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc")); + assertEquals(17, response.getBody().getContent().size()); + assertEquals("A12", response.getBody().getContent().iterator().next().key); + } + + @Test + void testGetSecondPageSortedByKey() { + ResponseEntity response = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + + "?domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5", + HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + assertEquals(5, response.getBody().getContent().size()); + assertEquals("L1050", response.getBody().getContent().iterator().next().key); + assertNotNull(response.getBody().getLink(Link.REL_SELF)); + assertTrue( + response + .getBody() + .getLink(Link.REL_SELF) + .getHref() + .endsWith( + "/api/v1/classifications?" + + "domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5")); + assertNotNull(response.getBody().getLink(Link.REL_FIRST)); + assertNotNull(response.getBody().getLink(Link.REL_LAST)); + assertNotNull(response.getBody().getLink(Link.REL_NEXT)); + assertNotNull(response.getBody().getLink(Link.REL_PREVIOUS)); + } + + @Test + @DirtiesContext + void testCreateClassification() { + String newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\"," + + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\"," + + "\"name\":\"new classification\",\"type\":\"TASK\"}"; + + ResponseEntity responseEntity = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class)); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + + newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\"," + + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS_2\"," + + "\"name\":\"new classification\",\"type\":\"TASK\"}"; + + responseEntity = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class)); + + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + } + + @Test + @DirtiesContext + void testCreateClassificationWithParentId() { + String newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\"," + + "\"domain\":\"DOMAIN_B\",\"key\":\"NEW_CLASS_P1\"," + + "\"name\":\"new classification\",\"type\":\"TASK\"," + + "\"parentId\":\"CLI:200000000000000000000000000000000015\"}"; + + ResponseEntity responseEntity = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class)); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + } + + @Test + @DirtiesContext + @SuppressWarnings("checkstyle:LineLength") + void testCreateClassificationWithParentKey() { + String newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\"," + + "\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\"," + + "\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; + + ResponseEntity responseEntity = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class)); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + } + + @Test + @DirtiesContext + void testCreateClassificationWithParentKeyInDomain_aShouldCreateAClassificationInRootDomain() { + String newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_A\"," + + "\"key\":\"NEW_CLASS_P2\",\"name\":\"new classification\"," + + "\"type\":\"TASK\",\"parentKey\":\"T2100\"}"; + + ResponseEntity responseEntity = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class)); + + assertNotNull(responseEntity); + assertEquals(HttpStatus.CREATED, responseEntity.getStatusCode()); + + ResponseEntity response = + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.GET, + restHelper.defaultRequest(), + ParameterizedTypeReference.forType(ClassificationSummaryListResource.class)); + assertNotNull(response.getBody().getLink(Link.REL_SELF)); + boolean foundClassificationCreated = false; + for (ClassificationSummaryResource classification : response.getBody().getContent()) { + if ("NEW_CLASS_P2".equals(classification.getKey()) + && "".equals(classification.getDomain()) + && "T2100".equals(classification.getParentKey())) { + foundClassificationCreated = true; + } + } + + assertEquals(true, foundClassificationCreated); + } + + @Test + @DirtiesContext + void testReturn400IfCreateClassificationWithIncompatibleParentIdAndKey() { + String newClassification = + "{\"classificationId\":\"\",\"category\":\"MANUAL\",\"domain\":\"DOMAIN_B\"," + + "\"key\":\"NEW_CLASS_P3\",\"name\":\"new classification\"," + + "\"type\":\"TASK\",\"parentId\":\"CLI:200000000000000000000000000000000015\"," + + "\"parentKey\":\"T2000\"}"; + + HttpClientErrorException e = + Assertions.assertThrows( + HttpClientErrorException.class, + () -> + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class))); + + assertNotNull(e); + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + + @Test + @DirtiesContext + void testCreateClassificationWithClassificationIdReturnsError400() { + String newClassification = + "{\"classificationId\":\"someId\",\"category\":\"MANUAL\"," + + "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\"," + + "\"name\":\"new classification\",\"type\":\"TASK\"}"; + + HttpClientErrorException e = + Assertions.assertThrows( + HttpClientErrorException.class, + () -> + template.exchange( + restHelper.toUrl(Mapping.URL_CLASSIFICATIONS), + HttpMethod.POST, + new HttpEntity<>(newClassification, restHelper.getHeaders()), + ParameterizedTypeReference.forType(ClassificationResource.class))); + + assertNotNull(e); + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + + @Test + void testGetClassificationWithSpecialCharacter() { + + HttpEntity request = new HttpEntity(restHelper.getHeadersAdmin()); + ResponseEntity response = + template.exchange( + restHelper.toUrl( + Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"), + HttpMethod.GET, + request, + ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + assertEquals("Zustimmungserklärung", response.getBody().name); + } + + @Test + @DirtiesContext + void testDeleteClassification() { + HttpEntity request = new HttpEntity(restHelper.getHeaders()); + + ResponseEntity response = + template.exchange( + restHelper.toUrl( + Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), + HttpMethod.DELETE, + request, + ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode()); + + assertThrows( + HttpClientErrorException.class, + () -> { + template.exchange( + restHelper.toUrl( + Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"), + HttpMethod.GET, + request, + ParameterizedTypeReference.forType(ClassificationSummaryResource.class)); + }); + } +} diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApp.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApp.java index ffc942b89..f2a39ae71 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApp.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/ExampleDocumentationApp.java @@ -1,73 +1,72 @@ -package pro.taskana.rest; - -import java.sql.SQLException; -import javax.annotation.PostConstruct; -import javax.sql.DataSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.jdbc.datasource.DataSourceTransactionManager; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.transaction.PlatformTransactionManager; - -import pro.taskana.ldap.LdapCacheTestImpl; -import pro.taskana.sampledata.SampleDataGenerator; - -/** Example Application to create the documentation. */ -@SpringBootApplication -@EnableScheduling -@ComponentScan(basePackages = "pro.taskana") -@Import({RestConfiguration.class}) -public class ExampleDocumentationApp { - - @Value("${taskana.schemaName:TASKANA}") - private String schemaName; - - @Autowired private SampleDataGenerator sampleDataGenerator; - - public static void main(String[] args) { - SpringApplication.run(ExampleDocumentationApp.class, args); - } - - @Bean - @Primary - @ConfigurationProperties(prefix = "datasource") - public DataSourceProperties dataSourceProperties() { - DataSourceProperties props = new DataSourceProperties(); - props.setUrl( - "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS " - + schemaName); - return props; - } - - @Bean - public DataSource dataSource(DataSourceProperties properties) { - return properties.initializeDataSourceBuilder().build(); - } - - @Bean - public PlatformTransactionManager txManager(DataSource dataSource) { - return new DataSourceTransactionManager(dataSource); - } - - @Bean - @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted - public SampleDataGenerator generateSampleData(DataSource dataSource) { - sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - return sampleDataGenerator; - } - - @PostConstruct - private void init() throws SQLException { - AccessIdController.setLdapCache(new LdapCacheTestImpl()); - sampleDataGenerator.generateSampleData(); - } -} +package pro.taskana.rest; + +import javax.annotation.PostConstruct; +import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.PlatformTransactionManager; + +import pro.taskana.ldap.LdapCacheTestImpl; +import pro.taskana.sampledata.SampleDataGenerator; + +/** Example Application to create the documentation. */ +@SpringBootApplication +@EnableScheduling +@ComponentScan(basePackages = "pro.taskana") +@Import({RestConfiguration.class}) +public class ExampleDocumentationApp { + + @Value("${taskana.schemaName:TASKANA}") + private String schemaName; + + @Autowired private SampleDataGenerator sampleDataGenerator; + + public static void main(String[] args) { + SpringApplication.run(ExampleDocumentationApp.class, args); + } + + @Bean + @Primary + @ConfigurationProperties(prefix = "datasource") + public DataSourceProperties dataSourceProperties() { + DataSourceProperties props = new DataSourceProperties(); + props.setUrl( + "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0;INIT=CREATE SCHEMA IF NOT EXISTS " + + schemaName); + return props; + } + + @Bean + public DataSource dataSource(DataSourceProperties properties) { + return properties.initializeDataSourceBuilder().build(); + } + + @Bean + public PlatformTransactionManager txManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean + @DependsOn("getTaskanaEngine") // generate sample data after schema was inserted + public SampleDataGenerator generateSampleData(DataSource dataSource) { + sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + return sampleDataGenerator; + } + + @PostConstruct + private void init() { + AccessIdController.setLdapCache(new LdapCacheTestImpl()); + sampleDataGenerator.generateSampleData(); + } +} diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java index 8fda76fff..6247786fd 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/WorkbasketDefinitionControllerIntTest.java @@ -1,280 +1,280 @@ -package pro.taskana.rest; - -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.stream.Collectors; -import javax.sql.DataSource; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.io.FileSystemResource; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import pro.taskana.RestHelper; -import pro.taskana.TaskanaSpringBootTest; -import pro.taskana.rest.resource.WorkbasketDefinitionResource; -import pro.taskana.sampledata.SampleDataGenerator; - -/** Integration tests for WorkbasketDefinitionController. */ -@TaskanaSpringBootTest -class WorkbasketDefinitionControllerIntTest { - - private static RestTemplate template; - - @Value("${taskana.schemaName:TASKANA}") - String schemaName; - - ObjectMapper objMapper = new ObjectMapper(); - - @Autowired RestHelper restHelper; - - @Autowired private DataSource dataSource; - - @BeforeAll - static void init() { - template = RestHelper.getRestTemplate(); - } - - @BeforeEach - void resetDb() { - SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); - sampleDataGenerator.generateSampleData(); - } - - @Test - void testExportWorkbasketFromDomain() { - ResponseEntity> response = - executeExportRequestForDomain("DOMAIN_A"); - - assertNotNull(response.getBody()); - assertEquals(HttpStatus.OK, response.getStatusCode()); - assertThat(response.getBody().get(0), instanceOf(WorkbasketDefinitionResource.class)); - - boolean allAuthorizationsAreEmpty = true; - boolean allDistributionTargetsAreEmpty = true; - for (WorkbasketDefinitionResource workbasketDefinition : response.getBody()) { - if (allAuthorizationsAreEmpty && !workbasketDefinition.getAuthorizations().isEmpty()) { - allAuthorizationsAreEmpty = false; - } - if (allDistributionTargetsAreEmpty - && !workbasketDefinition.getDistributionTargets().isEmpty()) { - allDistributionTargetsAreEmpty = false; - } - if (!allAuthorizationsAreEmpty && !allDistributionTargetsAreEmpty) { - break; - } - } - assertFalse(allDistributionTargetsAreEmpty); - assertFalse(allAuthorizationsAreEmpty); - } - - @Test - void testExportWorkbasketsFromWrongDomain() { - ResponseEntity> response = - executeExportRequestForDomain("wrongDomain"); - assertEquals(0, response.getBody().size()); - } - - @Test - void testImportEveryWorkbasketFromDomainA() throws IOException { - List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); - for (WorkbasketDefinitionResource w : wbList) { - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); - } - } - - @Test - void testImportWorkbasketWithoutDistributionTargets() throws IOException { - WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); - w.setDistributionTargets(new HashSet<>()); - - this.expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); - - w.getWorkbasket().setKey("newKey"); - w.getAuthorizations().forEach(authorization -> authorization.setWorkbasketKey("newKey")); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); - } - - @Test - void testImportWorkbasketWithDistributionTargetsInImportFile() throws IOException { - List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); - - WorkbasketDefinitionResource w = wbList.get(0); - w.setDistributionTargets(new HashSet<>()); - String letMeBeYourDistributionTarget = w.getWorkbasket().workbasketId; - WorkbasketDefinitionResource w2 = wbList.get(1); - w2.setDistributionTargets(Collections.singleton(letMeBeYourDistributionTarget)); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); - - this.changeWorkbasketIdOrKey(w, "fancyNewId", null); - w2.setDistributionTargets(Collections.singleton("fancyNewId")); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); - - this.changeWorkbasketIdOrKey(w, null, "nowImANewWB"); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); - - this.changeWorkbasketIdOrKey(w2, null, "nowImAlsoANewWB"); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); - } - - @Test - void testImportWorkbasketWithDistributionTargetsInSystem() throws IOException { - List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); - - wbList.removeIf(definition -> definition.getDistributionTargets().isEmpty()); - WorkbasketDefinitionResource w = wbList.get(0); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); - - changeWorkbasketIdOrKey(w, null, "new"); - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); - } - - @Test - void testImportWorkbasketWithDistributionTargetsNotInSystem() throws IOException { - List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); - - WorkbasketDefinitionResource w = wbList.get(0); - w.setDistributionTargets(Collections.singleton("invalidWorkbasketId")); - try { - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w); - fail("Expected http-Status 400"); - } catch (HttpClientErrorException e) { - assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); - } - - w.getWorkbasket().setKey("anotherNewKey"); - try { - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w); - fail("Expected http-Status 400"); - } catch (HttpClientErrorException e) { - assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); - } - } - - @Test - void testFailOnImportDuplicates() throws IOException { - WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); - try { - expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.CONFLICT, w, w); - fail("Expected http-Status 409"); - } catch (HttpClientErrorException e) { - assertEquals(HttpStatus.CONFLICT, e.getStatusCode()); - } - } - - @Test - void testNoErrorWhenImportWithSameIdButDifferentKeyAndDomain() throws IOException { - List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); - - WorkbasketDefinitionResource w = wbList.get(0); - WorkbasketDefinitionResource differentLogicalId = wbList.get(1); - this.changeWorkbasketIdOrKey(differentLogicalId, w.getWorkbasket().getWorkbasketId(), null); - - // breaks the logic but not the script- should we really allow this case? - WorkbasketDefinitionResource theDestroyer = wbList.get(2); - theDestroyer.setDistributionTargets( - Collections.singleton(differentLogicalId.getWorkbasket().workbasketId)); - - expectStatusWhenExecutingImportRequestOfWorkbaskets( - HttpStatus.NO_CONTENT, w, differentLogicalId, theDestroyer); - } - - @Test - void testErrorWhenImportWithSameAccessIdAndWorkbasket() throws IOException { - WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); - - String w1String = workbasketToString(w); - w.getWorkbasket().setKey("new Key for this WB"); - String w2String = workbasketToString(w); - Assertions.assertThrows( - HttpClientErrorException.class, - () -> - expectStatusWhenExecutingImportRequestOfWorkbaskets( - HttpStatus.CONFLICT, Arrays.asList(w1String, w2String))); - } - - private void changeWorkbasketIdOrKey( - WorkbasketDefinitionResource w, String newId, String newKey) { - if (newId != null && !newId.isEmpty()) { - w.getWorkbasket().setWorkbasketId(newId); - w.getAuthorizations().forEach(auth -> auth.setWorkbasketId(newId)); - } - if (newKey != null && !newKey.isEmpty()) { - w.getWorkbasket().setKey(newKey); - w.getAuthorizations().forEach(auth -> auth.setWorkbasketKey(newKey)); - } - } - - private ResponseEntity> executeExportRequestForDomain( - String domain) { - return template.exchange( - restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=" + domain, - HttpMethod.GET, - restHelper.defaultRequest(), - new ParameterizedTypeReference>() {}); - } - - private void expectStatusWhenExecutingImportRequestOfWorkbaskets( - HttpStatus expectedStatus, WorkbasketDefinitionResource... workbaskets) throws IOException { - List workbasketStrings = - Arrays.stream(workbaskets).map(wb -> workbasketToString(wb)).collect(Collectors.toList()); - expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, workbasketStrings); - } - - private void expectStatusWhenExecutingImportRequestOfWorkbaskets( - HttpStatus expectedStatus, List workbasketStrings) throws IOException { - File tmpFile = File.createTempFile("test", ".tmp"); - OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tmpFile), UTF_8); - writer.write(workbasketStrings.toString()); - writer.close(); - - MultiValueMap body = new LinkedMultiValueMap<>(); - HttpHeaders headers = restHelper.getHeaders(); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - body.add("file", new FileSystemResource(tmpFile)); - - HttpEntity> requestEntity = new HttpEntity<>(body, headers); - String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS); - - ResponseEntity responseImport = - template.postForEntity(serverUrl, requestEntity, Void.class); - assertEquals(expectedStatus, responseImport.getStatusCode()); - } - - private String workbasketToString(WorkbasketDefinitionResource workbasketDefinitionResource) { - try { - return objMapper.writeValueAsString(workbasketDefinitionResource); - } catch (JsonProcessingException e) { - return ""; - } - } -} +package pro.taskana.rest; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.Matchers.instanceOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Collectors; +import javax.sql.DataSource; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.RestTemplate; + +import pro.taskana.RestHelper; +import pro.taskana.TaskanaSpringBootTest; +import pro.taskana.rest.resource.WorkbasketDefinitionResource; +import pro.taskana.sampledata.SampleDataGenerator; + +/** Integration tests for WorkbasketDefinitionController. */ +@TaskanaSpringBootTest +class WorkbasketDefinitionControllerIntTest { + + private static RestTemplate template; + + @Value("${taskana.schemaName:TASKANA}") + String schemaName; + + ObjectMapper objMapper = new ObjectMapper(); + + @Autowired RestHelper restHelper; + + @Autowired private DataSource dataSource; + + @BeforeAll + static void init() { + template = RestHelper.getRestTemplate(); + } + + @BeforeEach + void resetDb() { + SampleDataGenerator sampleDataGenerator = new SampleDataGenerator(dataSource, schemaName); + sampleDataGenerator.generateSampleData(); + } + + @Test + void testExportWorkbasketFromDomain() { + ResponseEntity> response = + executeExportRequestForDomain("DOMAIN_A"); + + assertNotNull(response.getBody()); + assertEquals(HttpStatus.OK, response.getStatusCode()); + assertThat(response.getBody().get(0), instanceOf(WorkbasketDefinitionResource.class)); + + boolean allAuthorizationsAreEmpty = true; + boolean allDistributionTargetsAreEmpty = true; + for (WorkbasketDefinitionResource workbasketDefinition : response.getBody()) { + if (allAuthorizationsAreEmpty && !workbasketDefinition.getAuthorizations().isEmpty()) { + allAuthorizationsAreEmpty = false; + } + if (allDistributionTargetsAreEmpty + && !workbasketDefinition.getDistributionTargets().isEmpty()) { + allDistributionTargetsAreEmpty = false; + } + if (!allAuthorizationsAreEmpty && !allDistributionTargetsAreEmpty) { + break; + } + } + assertFalse(allDistributionTargetsAreEmpty); + assertFalse(allAuthorizationsAreEmpty); + } + + @Test + void testExportWorkbasketsFromWrongDomain() { + ResponseEntity> response = + executeExportRequestForDomain("wrongDomain"); + assertEquals(0, response.getBody().size()); + } + + @Test + void testImportEveryWorkbasketFromDomainA() throws IOException { + List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); + for (WorkbasketDefinitionResource w : wbList) { + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); + } + } + + @Test + void testImportWorkbasketWithoutDistributionTargets() throws IOException { + WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); + w.setDistributionTargets(new HashSet<>()); + + this.expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); + + w.getWorkbasket().setKey("newKey"); + w.getAuthorizations().forEach(authorization -> authorization.setWorkbasketKey("newKey")); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); + } + + @Test + void testImportWorkbasketWithDistributionTargetsInImportFile() throws IOException { + List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); + + WorkbasketDefinitionResource w = wbList.get(0); + w.setDistributionTargets(new HashSet<>()); + String letMeBeYourDistributionTarget = w.getWorkbasket().workbasketId; + WorkbasketDefinitionResource w2 = wbList.get(1); + w2.setDistributionTargets(Collections.singleton(letMeBeYourDistributionTarget)); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); + + this.changeWorkbasketIdOrKey(w, "fancyNewId", null); + w2.setDistributionTargets(Collections.singleton("fancyNewId")); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); + + this.changeWorkbasketIdOrKey(w, null, "nowImANewWB"); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); + + this.changeWorkbasketIdOrKey(w2, null, "nowImAlsoANewWB"); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w, w2); + } + + @Test + void testImportWorkbasketWithDistributionTargetsInSystem() throws IOException { + List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); + + wbList.removeIf(definition -> definition.getDistributionTargets().isEmpty()); + WorkbasketDefinitionResource w = wbList.get(0); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); + + changeWorkbasketIdOrKey(w, null, "new"); + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.NO_CONTENT, w); + } + + @Test + void testImportWorkbasketWithDistributionTargetsNotInSystem() throws IOException { + List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); + + WorkbasketDefinitionResource w = wbList.get(0); + w.setDistributionTargets(Collections.singleton("invalidWorkbasketId")); + try { + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w); + fail("Expected http-Status 400"); + } catch (HttpClientErrorException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + + w.getWorkbasket().setKey("anotherNewKey"); + try { + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.BAD_REQUEST, w); + fail("Expected http-Status 400"); + } catch (HttpClientErrorException e) { + assertEquals(HttpStatus.BAD_REQUEST, e.getStatusCode()); + } + } + + @Test + void testFailOnImportDuplicates() throws IOException { + WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); + try { + expectStatusWhenExecutingImportRequestOfWorkbaskets(HttpStatus.CONFLICT, w, w); + fail("Expected http-Status 409"); + } catch (HttpClientErrorException e) { + assertEquals(HttpStatus.CONFLICT, e.getStatusCode()); + } + } + + @Test + void testNoErrorWhenImportWithSameIdButDifferentKeyAndDomain() throws IOException { + List wbList = executeExportRequestForDomain("DOMAIN_A").getBody(); + + WorkbasketDefinitionResource w = wbList.get(0); + WorkbasketDefinitionResource differentLogicalId = wbList.get(1); + this.changeWorkbasketIdOrKey(differentLogicalId, w.getWorkbasket().getWorkbasketId(), null); + + // breaks the logic but not the script- should we really allow this case? + WorkbasketDefinitionResource theDestroyer = wbList.get(2); + theDestroyer.setDistributionTargets( + Collections.singleton(differentLogicalId.getWorkbasket().workbasketId)); + + expectStatusWhenExecutingImportRequestOfWorkbaskets( + HttpStatus.NO_CONTENT, w, differentLogicalId, theDestroyer); + } + + @Test + void testErrorWhenImportWithSameAccessIdAndWorkbasket() { + WorkbasketDefinitionResource w = executeExportRequestForDomain("DOMAIN_A").getBody().get(0); + + String w1String = workbasketToString(w); + w.getWorkbasket().setKey("new Key for this WB"); + String w2String = workbasketToString(w); + Assertions.assertThrows( + HttpClientErrorException.class, + () -> + expectStatusWhenExecutingImportRequestOfWorkbaskets( + HttpStatus.CONFLICT, Arrays.asList(w1String, w2String))); + } + + private void changeWorkbasketIdOrKey( + WorkbasketDefinitionResource w, String newId, String newKey) { + if (newId != null && !newId.isEmpty()) { + w.getWorkbasket().setWorkbasketId(newId); + w.getAuthorizations().forEach(auth -> auth.setWorkbasketId(newId)); + } + if (newKey != null && !newKey.isEmpty()) { + w.getWorkbasket().setKey(newKey); + w.getAuthorizations().forEach(auth -> auth.setWorkbasketKey(newKey)); + } + } + + private ResponseEntity> executeExportRequestForDomain( + String domain) { + return template.exchange( + restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=" + domain, + HttpMethod.GET, + restHelper.defaultRequest(), + new ParameterizedTypeReference>() {}); + } + + private void expectStatusWhenExecutingImportRequestOfWorkbaskets( + HttpStatus expectedStatus, WorkbasketDefinitionResource... workbaskets) throws IOException { + List workbasketStrings = + Arrays.stream(workbaskets).map(wb -> workbasketToString(wb)).collect(Collectors.toList()); + expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, workbasketStrings); + } + + private void expectStatusWhenExecutingImportRequestOfWorkbaskets( + HttpStatus expectedStatus, List workbasketStrings) throws IOException { + File tmpFile = File.createTempFile("test", ".tmp"); + OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(tmpFile), UTF_8); + writer.write(workbasketStrings.toString()); + writer.close(); + + MultiValueMap body = new LinkedMultiValueMap<>(); + HttpHeaders headers = restHelper.getHeaders(); + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + body.add("file", new FileSystemResource(tmpFile)); + + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS); + + ResponseEntity responseImport = + template.postForEntity(serverUrl, requestEntity, Void.class); + assertEquals(expectedStatus, responseImport.getStatusCode()); + } + + private String workbasketToString(WorkbasketDefinitionResource workbasketDefinitionResource) { + try { + return objMapper.writeValueAsString(workbasketDefinitionResource); + } catch (JsonProcessingException e) { + return ""; + } + } +} diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/resource/WorkbasketResourceAssemblerTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/resource/WorkbasketResourceAssemblerTest.java index c2710db66..68ad409aa 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/resource/WorkbasketResourceAssemblerTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/rest/resource/WorkbasketResourceAssemblerTest.java @@ -1,140 +1,138 @@ -package pro.taskana.rest.resource; - -import java.time.Instant; -import org.junit.Assert; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import pro.taskana.TaskanaSpringBootTest; -import pro.taskana.common.api.exceptions.NotAuthorizedException; -import pro.taskana.rest.Mapping; -import pro.taskana.workbasket.api.Workbasket; -import pro.taskana.workbasket.api.WorkbasketService; -import pro.taskana.workbasket.api.WorkbasketType; -import pro.taskana.workbasket.api.exceptions.WorkbasketNotFoundException; -import pro.taskana.workbasket.internal.WorkbasketImpl; - -/** Test for {@link WorkbasketResourceAssembler}. */ -@TaskanaSpringBootTest -class WorkbasketResourceAssemblerTest { - - @Autowired WorkbasketService workbasketService; - @Autowired WorkbasketResourceAssembler workbasketResourceAssembler; - - @Test - void workbasketToResource() throws NotAuthorizedException, WorkbasketNotFoundException { - // given - Workbasket workbasket = workbasketService.newWorkbasket("1", "DOMAIN_A"); - ((WorkbasketImpl) workbasket).setId("ID"); - workbasket.setType(WorkbasketType.PERSONAL); - workbasket.setName("Testbasket"); - workbasket.setOrgLevel1("Org1"); - workbasket.setOrgLevel2("Org2"); - workbasket.setOrgLevel3("Org3"); - workbasket.setOrgLevel4("Org4"); - workbasket.setDescription("A test workbasket"); - workbasket.setCustom1("1"); - workbasket.setCustom2("2"); - workbasket.setCustom3("3"); - workbasket.setCustom4("4"); - workbasket.setOwner("Lars"); - ((WorkbasketImpl) workbasket).setCreated(Instant.parse("2010-01-01T12:00:00Z")); - ((WorkbasketImpl) workbasket).setModified(Instant.parse("2010-01-01T12:00:00Z")); - // when - WorkbasketResource resource = workbasketResourceAssembler.toResource(workbasket); - // then - testEquality(workbasket, resource); - verifyLinks(resource); - } - - @Test - void resourceWithoutCreated() { - // given - WorkbasketResource resource = new WorkbasketResource(); - resource.setWorkbasketId("1"); - resource.setModified("2010-01-01T12:00:00Z"); - resource.setType(WorkbasketType.PERSONAL); - // when - Workbasket workbasket = workbasketResourceAssembler.toModel(resource); - // then - testEquality(workbasket, resource); - } - - @Test - void resourceWithoutModified() { - // given - WorkbasketResource resource = new WorkbasketResource(); - resource.setWorkbasketId("1"); - resource.setCreated("2010-01-01T12:00:00Z"); - resource.setType(WorkbasketType.PERSONAL); - // when - Workbasket workbasket = workbasketResourceAssembler.toModel(resource); - // then - testEquality(workbasket, resource); - } - - @Test - void resourceToWorkbasket() { - // given - WorkbasketResource workbasketResource = new WorkbasketResource(); - workbasketResource.setWorkbasketId("1"); - workbasketResource.setCreated("2010-01-01T12:00:00Z"); - workbasketResource.setModified("2010-01-01T12:00:00Z"); - workbasketResource.setCustom1("Custom1"); - workbasketResource.setCustom2("Custom2"); - workbasketResource.setCustom3("Custom3"); - workbasketResource.setCustom4("Custom4"); - workbasketResource.setDescription("Test Ressource"); - workbasketResource.setDomain("DOMAIN_A"); - workbasketResource.setKey("1"); - workbasketResource.setName("Ressource"); - workbasketResource.setOrgLevel1("Org1"); - workbasketResource.setOrgLevel2("Org2"); - workbasketResource.setOrgLevel3("Org3"); - workbasketResource.setOrgLevel4("Org4"); - workbasketResource.setOwner("Lars"); - workbasketResource.setType(WorkbasketType.PERSONAL); - // when - Workbasket workbasket = workbasketResourceAssembler.toModel(workbasketResource); - // then - testEquality(workbasket, workbasketResource); - } - - private void verifyLinks(WorkbasketResource workbasket) { - Assert.assertEquals(5, workbasket.getLinks().size()); - Assert.assertEquals( - Mapping.URL_WORKBASKET_ID.replaceAll("\\{.*}", workbasket.getWorkbasketId()), - workbasket.getLink("self").getHref()); - Assert.assertEquals( - Mapping.URL_WORKBASKET_ID_DISTRIBUTION.replaceAll("\\{.*}", workbasket.getWorkbasketId()), - workbasket.getLink("distributionTargets").getHref()); - Assert.assertEquals(Mapping.URL_WORKBASKET, workbasket.getLink("allWorkbaskets").getHref()); - Assert.assertEquals( - Mapping.URL_WORKBASKET_DISTRIBUTION_ID.replaceAll("\\{.*}", workbasket.getWorkbasketId()), - workbasket.getLink("removeDistributionTargets").getHref()); - } - - private void testEquality(Workbasket workbasket, WorkbasketResource workbasketResource) { - Assert.assertEquals(workbasket.getId(), workbasketResource.workbasketId); - Assert.assertEquals(workbasket.getKey(), workbasketResource.key); - Assert.assertEquals( - workbasket.getCreated() == null ? null : workbasket.getCreated().toString(), - workbasketResource.created); - Assert.assertEquals( - workbasket.getModified() == null ? null : workbasket.getModified().toString(), - workbasketResource.modified); - Assert.assertEquals(workbasket.getName(), workbasketResource.name); - Assert.assertEquals(workbasket.getDescription(), workbasketResource.description); - Assert.assertEquals(workbasket.getOwner(), workbasketResource.owner); - Assert.assertEquals(workbasket.getDomain(), workbasketResource.domain); - Assert.assertEquals(workbasket.getType(), workbasketResource.type); - Assert.assertEquals(workbasket.getCustom1(), workbasketResource.custom1); - Assert.assertEquals(workbasket.getCustom2(), workbasketResource.custom2); - Assert.assertEquals(workbasket.getCustom3(), workbasketResource.custom3); - Assert.assertEquals(workbasket.getCustom4(), workbasketResource.custom4); - Assert.assertEquals(workbasket.getOrgLevel1(), workbasketResource.orgLevel1); - Assert.assertEquals(workbasket.getOrgLevel2(), workbasketResource.orgLevel2); - Assert.assertEquals(workbasket.getOrgLevel3(), workbasketResource.orgLevel3); - Assert.assertEquals(workbasket.getOrgLevel4(), workbasketResource.orgLevel4); - } -} +package pro.taskana.rest.resource; + +import java.time.Instant; +import org.junit.Assert; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import pro.taskana.TaskanaSpringBootTest; +import pro.taskana.rest.Mapping; +import pro.taskana.workbasket.api.Workbasket; +import pro.taskana.workbasket.api.WorkbasketService; +import pro.taskana.workbasket.api.WorkbasketType; +import pro.taskana.workbasket.internal.WorkbasketImpl; + +/** Test for {@link WorkbasketResourceAssembler}. */ +@TaskanaSpringBootTest +class WorkbasketResourceAssemblerTest { + + @Autowired WorkbasketService workbasketService; + @Autowired WorkbasketResourceAssembler workbasketResourceAssembler; + + @Test + void workbasketToResource() { + // given + Workbasket workbasket = workbasketService.newWorkbasket("1", "DOMAIN_A"); + ((WorkbasketImpl) workbasket).setId("ID"); + workbasket.setType(WorkbasketType.PERSONAL); + workbasket.setName("Testbasket"); + workbasket.setOrgLevel1("Org1"); + workbasket.setOrgLevel2("Org2"); + workbasket.setOrgLevel3("Org3"); + workbasket.setOrgLevel4("Org4"); + workbasket.setDescription("A test workbasket"); + workbasket.setCustom1("1"); + workbasket.setCustom2("2"); + workbasket.setCustom3("3"); + workbasket.setCustom4("4"); + workbasket.setOwner("Lars"); + ((WorkbasketImpl) workbasket).setCreated(Instant.parse("2010-01-01T12:00:00Z")); + ((WorkbasketImpl) workbasket).setModified(Instant.parse("2010-01-01T12:00:00Z")); + // when + WorkbasketResource resource = workbasketResourceAssembler.toResource(workbasket); + // then + testEquality(workbasket, resource); + verifyLinks(resource); + } + + @Test + void resourceWithoutCreated() { + // given + WorkbasketResource resource = new WorkbasketResource(); + resource.setWorkbasketId("1"); + resource.setModified("2010-01-01T12:00:00Z"); + resource.setType(WorkbasketType.PERSONAL); + // when + Workbasket workbasket = workbasketResourceAssembler.toModel(resource); + // then + testEquality(workbasket, resource); + } + + @Test + void resourceWithoutModified() { + // given + WorkbasketResource resource = new WorkbasketResource(); + resource.setWorkbasketId("1"); + resource.setCreated("2010-01-01T12:00:00Z"); + resource.setType(WorkbasketType.PERSONAL); + // when + Workbasket workbasket = workbasketResourceAssembler.toModel(resource); + // then + testEquality(workbasket, resource); + } + + @Test + void resourceToWorkbasket() { + // given + WorkbasketResource workbasketResource = new WorkbasketResource(); + workbasketResource.setWorkbasketId("1"); + workbasketResource.setCreated("2010-01-01T12:00:00Z"); + workbasketResource.setModified("2010-01-01T12:00:00Z"); + workbasketResource.setCustom1("Custom1"); + workbasketResource.setCustom2("Custom2"); + workbasketResource.setCustom3("Custom3"); + workbasketResource.setCustom4("Custom4"); + workbasketResource.setDescription("Test Ressource"); + workbasketResource.setDomain("DOMAIN_A"); + workbasketResource.setKey("1"); + workbasketResource.setName("Ressource"); + workbasketResource.setOrgLevel1("Org1"); + workbasketResource.setOrgLevel2("Org2"); + workbasketResource.setOrgLevel3("Org3"); + workbasketResource.setOrgLevel4("Org4"); + workbasketResource.setOwner("Lars"); + workbasketResource.setType(WorkbasketType.PERSONAL); + // when + Workbasket workbasket = workbasketResourceAssembler.toModel(workbasketResource); + // then + testEquality(workbasket, workbasketResource); + } + + private void verifyLinks(WorkbasketResource workbasket) { + Assert.assertEquals(5, workbasket.getLinks().size()); + Assert.assertEquals( + Mapping.URL_WORKBASKET_ID.replaceAll("\\{.*}", workbasket.getWorkbasketId()), + workbasket.getLink("self").getHref()); + Assert.assertEquals( + Mapping.URL_WORKBASKET_ID_DISTRIBUTION.replaceAll("\\{.*}", workbasket.getWorkbasketId()), + workbasket.getLink("distributionTargets").getHref()); + Assert.assertEquals(Mapping.URL_WORKBASKET, workbasket.getLink("allWorkbaskets").getHref()); + Assert.assertEquals( + Mapping.URL_WORKBASKET_DISTRIBUTION_ID.replaceAll("\\{.*}", workbasket.getWorkbasketId()), + workbasket.getLink("removeDistributionTargets").getHref()); + } + + private void testEquality(Workbasket workbasket, WorkbasketResource workbasketResource) { + Assert.assertEquals(workbasket.getId(), workbasketResource.workbasketId); + Assert.assertEquals(workbasket.getKey(), workbasketResource.key); + Assert.assertEquals( + workbasket.getCreated() == null ? null : workbasket.getCreated().toString(), + workbasketResource.created); + Assert.assertEquals( + workbasket.getModified() == null ? null : workbasket.getModified().toString(), + workbasketResource.modified); + Assert.assertEquals(workbasket.getName(), workbasketResource.name); + Assert.assertEquals(workbasket.getDescription(), workbasketResource.description); + Assert.assertEquals(workbasket.getOwner(), workbasketResource.owner); + Assert.assertEquals(workbasket.getDomain(), workbasketResource.domain); + Assert.assertEquals(workbasket.getType(), workbasketResource.type); + Assert.assertEquals(workbasket.getCustom1(), workbasketResource.custom1); + Assert.assertEquals(workbasket.getCustom2(), workbasketResource.custom2); + Assert.assertEquals(workbasket.getCustom3(), workbasketResource.custom3); + Assert.assertEquals(workbasket.getCustom4(), workbasketResource.custom4); + Assert.assertEquals(workbasket.getOrgLevel1(), workbasketResource.orgLevel1); + Assert.assertEquals(workbasket.getOrgLevel2(), workbasketResource.orgLevel2); + Assert.assertEquals(workbasket.getOrgLevel3(), workbasketResource.orgLevel3); + Assert.assertEquals(workbasket.getOrgLevel4(), workbasketResource.orgLevel4); + } +}