TSK-1031: removed unnecessary throws statements

This commit is contained in:
Holger Hagen 2020-02-05 09:46:57 +01:00
parent 448d4fb8fc
commit e6f8883e49
10 changed files with 1410 additions and 1421 deletions

View File

@ -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<Object> 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<String> 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. <br>
* 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<String> getWorkbasketsMarkedForDeletion() {
List<String> workbasketList =
taskanaEngineImpl
.getWorkbasketService()
.createWorkbasketQuery()
.markedForDeletion(true)
.listValues(WorkbasketQueryColumnName.ID, BaseQuery.SortDirection.ASCENDING);
return workbasketList;
}
private int deleteWorkbasketsTransactionally(List<String> 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<String> workbasketsToBeDeleted)
throws InvalidArgumentException, NotAuthorizedException, WorkbasketNotFoundException,
WorkbasketInUseException {
BulkOperationResults<String, TaskanaException> 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<Object> 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<String> 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. <br>
* 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<String> getWorkbasketsMarkedForDeletion() {
List<String> workbasketList =
taskanaEngineImpl
.getWorkbasketService()
.createWorkbasketQuery()
.markedForDeletion(true)
.listValues(WorkbasketQueryColumnName.ID, BaseQuery.SortDirection.ASCENDING);
return workbasketList;
}
private int deleteWorkbasketsTransactionally(List<String> 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<String> workbasketsToBeDeleted)
throws InvalidArgumentException, NotAuthorizedException {
BulkOperationResults<String, TaskanaException> 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;
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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<PreAuthenticatedAuthenticationToken>
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<PreAuthenticatedAuthenticationToken> {
@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<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> 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<PreAuthenticatedAuthenticationToken>
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<PreAuthenticatedAuthenticationToken> {
@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<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> 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;
}
}
}
}

View File

@ -156,7 +156,7 @@ public class WorkbasketController extends AbstractPagingController {
public ResponseEntity<WorkbasketResource> 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<WorkbasketResource> 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<WorkbasketResource> result;
if (workbasketId.equals(workbasketResource.workbasketId)) {

View File

@ -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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationSummaryListResource> 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<String> request = new HttpEntity<String>(restHelper.getHeadersAdmin());
ResponseEntity<ClassificationSummaryResource> 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<String> request = new HttpEntity<String>(restHelper.getHeaders());
ResponseEntity<ClassificationSummaryResource> 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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationSummaryListResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationResource> 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<ClassificationSummaryListResource> 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<String> request = new HttpEntity<String>(restHelper.getHeadersAdmin());
ResponseEntity<ClassificationSummaryResource> 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<String> request = new HttpEntity<String>(restHelper.getHeaders());
ResponseEntity<ClassificationSummaryResource> 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));
});
}
}

View File

@ -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();
}
}

View File

@ -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<List<WorkbasketDefinitionResource>> 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<List<WorkbasketDefinitionResource>> response =
executeExportRequestForDomain("wrongDomain");
assertEquals(0, response.getBody().size());
}
@Test
void testImportEveryWorkbasketFromDomainA() throws IOException {
List<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<List<WorkbasketDefinitionResource>> executeExportRequestForDomain(
String domain) {
return template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=" + domain,
HttpMethod.GET,
restHelper.defaultRequest(),
new ParameterizedTypeReference<List<WorkbasketDefinitionResource>>() {});
}
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
HttpStatus expectedStatus, WorkbasketDefinitionResource... workbaskets) throws IOException {
List<String> workbasketStrings =
Arrays.stream(workbaskets).map(wb -> workbasketToString(wb)).collect(Collectors.toList());
expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, workbasketStrings);
}
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
HttpStatus expectedStatus, List<String> 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<String, Object> body = new LinkedMultiValueMap<>();
HttpHeaders headers = restHelper.getHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
body.add("file", new FileSystemResource(tmpFile));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS);
ResponseEntity<Void> 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<List<WorkbasketDefinitionResource>> 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<List<WorkbasketDefinitionResource>> response =
executeExportRequestForDomain("wrongDomain");
assertEquals(0, response.getBody().size());
}
@Test
void testImportEveryWorkbasketFromDomainA() throws IOException {
List<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<WorkbasketDefinitionResource> 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<List<WorkbasketDefinitionResource>> executeExportRequestForDomain(
String domain) {
return template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS) + "?domain=" + domain,
HttpMethod.GET,
restHelper.defaultRequest(),
new ParameterizedTypeReference<List<WorkbasketDefinitionResource>>() {});
}
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
HttpStatus expectedStatus, WorkbasketDefinitionResource... workbaskets) throws IOException {
List<String> workbasketStrings =
Arrays.stream(workbaskets).map(wb -> workbasketToString(wb)).collect(Collectors.toList());
expectStatusWhenExecutingImportRequestOfWorkbaskets(expectedStatus, workbasketStrings);
}
private void expectStatusWhenExecutingImportRequestOfWorkbaskets(
HttpStatus expectedStatus, List<String> 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<String, Object> body = new LinkedMultiValueMap<>();
HttpHeaders headers = restHelper.getHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
body.add("file", new FileSystemResource(tmpFile));
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String serverUrl = restHelper.toUrl(Mapping.URL_WORKBASKETDEFIITIONS);
ResponseEntity<Void> 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 "";
}
}
}

View File

@ -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);
}
}