TSK-1031: formatting issues fixed.

This commit is contained in:
Holger Hagen 2020-02-11 11:01:29 +01:00
parent e0dbbe2783
commit 60d4b29015
31 changed files with 3456 additions and 3453 deletions

View File

@ -1,111 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-simplehistory-rest-spring-example</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for taskana-simplehistory-rest-spring</description>
<parent>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-simplehistory-rest-spring-example</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for taskana-simplehistory-rest-spring</description>
<parent>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -58,4 +58,5 @@
<version>${version.jackson}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,187 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-simplehistory-spring-test</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Exclusive test module. Contains integration tests and build rest-doc.</description>
<parent>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${version.maven.asciidoctor}</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<snippets>target/generated-snippets</snippets>
<docinfo>shared</docinfo>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-rest-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
<resource>
<directory>${project.basedir}/src/js</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-documentation-to-taskana-simplehistory-rest-spring-example</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
../taskana-simplehistory-rest-spring-example/target/generated-docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.outputDirectory}/static/docs/rest
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-simplehistory-spring-test</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Exclusive test module. Contains integration tests and build rest-doc.</description>
<parent>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${version.junit.jupiter}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>${version.maven.asciidoctor}</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
<attributes>
<snippets>target/generated-snippets</snippets>
<docinfo>shared</docinfo>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-rest-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.directory}/generated-docs
</directory>
</resource>
<resource>
<directory>${project.basedir}/src/js</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-documentation-to-taskana-simplehistory-rest-spring-example</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
../taskana-simplehistory-rest-spring-example/target/generated-docs
</outputDirectory>
<resources>
<resource>
<directory>
${project.build.outputDirectory}/static/docs/rest
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,146 +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;
/**
* 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;
}
}
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

@ -48,8 +48,7 @@ import pro.taskana.workbasket.internal.WorkbasketImpl;
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = TaskanaConfigTestApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.allow-bean-definition-overriding=true")
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"inmemorydb", "dev"})
@Import({TransactionalJobsConfiguration.class})
class TaskanaTransactionIntTest {

View File

@ -0,0 +1,2 @@
logging.level.pro.taskana=INFO
spring.main.allow-bean-definition-overriding=true

704
pom.xml
View File

@ -1,352 +1,352 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pro.taskana</groupId>
<artifactId>taskana-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<description>This pom is parent to all taskana modules and serves the common build.</description>
<url>http://taskana.pro</url>
<modules>
<module>lib</module>
<module>rest</module>
<!-- History is an optional module. -->
<module>history</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<version.mybatis>3.5.4</version.mybatis>
<version.slf4j>1.7.30</version.slf4j>
<version.json>20190722</version.json>
<version.jackson>2.9.8</version.jackson>
<version.aspectjweaver>1.9.5</version.aspectjweaver>
<version.javax.validation>2.0.1.Final</version.javax.validation>
<version.javax.servlet>4.0.1</version.javax.servlet>
<!-- build dependencies -->
<version.checkstyle>8.29</version.checkstyle>
<version.maven.checkstyle>3.1.0</version.maven.checkstyle>
<version.maven.jar>3.2.0</version.maven.jar>
<version.maven.compiler>3.8.1</version.maven.compiler>
<version.maven.source>3.2.1</version.maven.source>
<version.maven.javadoc>3.1.1</version.maven.javadoc>
<version.maven.resources>3.1.0</version.maven.resources>
<version.maven.surefire>3.0.0-M4</version.maven.surefire>
<version.maven.asciidoctor>1.6.0</version.maven.asciidoctor>
<version.maven.wildfly>2.0.2.Final</version.maven.wildfly>
<!-- release dependencies -->
<version.maven.gpg>1.6</version.maven.gpg>
<version.sonatype>1.6.8</version.sonatype>
<!-- spring dependencies -->
<version.spring>5.2.3.RELEASE</version.spring>
<version.spring.security>5.2.1.RELEASE</version.spring.security>
<version.spring.core>2.0.0.RELEASE</version.spring.core>
<version.spring.boot>2.2.4.RELEASE</version.spring.boot>
<version.spring.restdocs>2.0.2.RELEASE</version.spring.restdocs>
<version.spring.mybatis>2.0.3</version.spring.mybatis>
<version.spring.hateos>0.24.0.RELEASE</version.spring.hateos>
<version.spring.ldap>2.3.2.RELEASE</version.spring.ldap>
<!-- wildfly dependencies -->
<version.wildfly>11.0.0.Final</version.wildfly>
<!-- java ee dependencies -->
<version.resteasy>4.4.2.Final</version.resteasy>
<version.thorntail>2.6.0.Final</version.thorntail>
<version.wildfly.security>1.11.2.Final</version.wildfly.security>
<version.javaee-api>8.0.1</version.javaee-api>
<version.arquillian>1.5.0.Final</version.arquillian>
<!-- test dependencies -->
<version.assertj>3.15.0</version.assertj>
<version.junit.jupiter>5.6.0</version.junit.jupiter>
<version.log4j>2.13.0</version.log4j>
<version.archunit>0.13.0</version.archunit>
<version.mockito>3.2.4</version.mockito>
<version.junit.mockito>3.2.4</version.junit.mockito>
<!-- byte buddy 1.9.7+ is needed to solve dependency errors with spring mock tests see LdapClientTest -->
<version.byte-buddy>1.10.7</version.byte-buddy>
<version.byte-buddy-agent>1.10.7</version.byte-buddy-agent>
<version.powermock>2.0.5</version.powermock>
<version.hamcrest>2.2</version.hamcrest>
<version.equalsverifier>3.1.12</version.equalsverifier>
<version.openpojo>0.8.13</version.openpojo>
<version.jacoco>0.8.5</version.jacoco>
<!-- database driver versions -->
<version.h2>1.4.200</version.h2>
<version.db2>11.1.1.1</version.db2>
<version.postgres>42.2.9</version.postgres>
<!-- used by jacoco to collect coverage -->
<argLine></argLine>
</properties>
<developers>
<developer>
<name>Holger Hagen</name>
<email>holger.hagen@novatec-gmbh.de</email>
<organization>Novatec Consulting GmbH</organization>
<organizationUrl>https://www.novatec-gmbh.de</organizationUrl>
</developer>
</developers>
<scm>
<url>http://github.com/taskana/taskana/tree/master</url>
<connection>scm:git:git://github.com/taskana/taskana.git</connection>
<developerConnection>scm:git:ssh://github.com:taskana/taskana.git</developerConnection>
</scm>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<profiles>
<profile>
<id>snapshot</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${version.maven.gpg}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${version.sonatype}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</profile>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${version.maven.gpg}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${version.sonatype}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</profile>
<profile>
<id>eclipse</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>check</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>coverage</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<!--
This plugin appends version information into the jar, so that it can be extracted from the jar.
See TSK-837 for more information
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${version.maven.jar}</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${version.maven.compiler}</version>
<configuration>
<showWarnings>true</showWarnings>
<failOnWarning>true</failOnWarning>
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-proc:none</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${version.maven.source}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${version.maven.javadoc}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.surefire}</version>
<configuration>
<argLine>${argLine}</argLine>
<!-- Required for generation of REST documentation -->
<includes>
<include>**/*Test.java</include>
<include>**/*Documentation.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${version.maven.checkstyle}</version>
<dependencies>
<dependency>
<artifactId>checkstyle</artifactId>
<groupId>com.puppycrawl.tools</groupId>
<version>${version.checkstyle}</version>
</dependency>
</dependencies>
<configuration>
<configLocation>qa/checkstyle/checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<failOnViolation>true</failOnViolation>
<violationSeverity>warning</violationSeverity>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pro.taskana</groupId>
<artifactId>taskana-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<description>This pom is parent to all taskana modules and serves the common build.</description>
<url>http://taskana.pro</url>
<modules>
<module>lib</module>
<module>rest</module>
<!-- History is an optional module. -->
<module>history</module>
</modules>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<version.mybatis>3.5.4</version.mybatis>
<version.slf4j>1.7.30</version.slf4j>
<version.json>20190722</version.json>
<version.jackson>2.9.8</version.jackson>
<version.aspectjweaver>1.9.5</version.aspectjweaver>
<version.javax.validation>2.0.1.Final</version.javax.validation>
<version.javax.servlet>4.0.1</version.javax.servlet>
<!-- build dependencies -->
<version.checkstyle>8.29</version.checkstyle>
<version.maven.checkstyle>3.1.0</version.maven.checkstyle>
<version.maven.jar>3.2.0</version.maven.jar>
<version.maven.compiler>3.8.1</version.maven.compiler>
<version.maven.source>3.2.1</version.maven.source>
<version.maven.javadoc>3.1.1</version.maven.javadoc>
<version.maven.resources>3.1.0</version.maven.resources>
<version.maven.surefire>3.0.0-M4</version.maven.surefire>
<version.maven.asciidoctor>1.6.0</version.maven.asciidoctor>
<version.maven.wildfly>2.0.2.Final</version.maven.wildfly>
<!-- release dependencies -->
<version.maven.gpg>1.6</version.maven.gpg>
<version.sonatype>1.6.8</version.sonatype>
<!-- spring dependencies -->
<version.spring>5.2.3.RELEASE</version.spring>
<version.spring.security>5.2.1.RELEASE</version.spring.security>
<version.spring.core>2.0.0.RELEASE</version.spring.core>
<version.spring.boot>2.2.4.RELEASE</version.spring.boot>
<version.spring.restdocs>2.0.2.RELEASE</version.spring.restdocs>
<version.spring.mybatis>2.0.3</version.spring.mybatis>
<version.spring.hateos>0.24.0.RELEASE</version.spring.hateos>
<version.spring.ldap>2.3.2.RELEASE</version.spring.ldap>
<!-- wildfly dependencies -->
<version.wildfly>11.0.0.Final</version.wildfly>
<!-- java ee dependencies -->
<version.resteasy>4.4.2.Final</version.resteasy>
<version.thorntail>2.6.0.Final</version.thorntail>
<version.wildfly.security>1.11.2.Final</version.wildfly.security>
<version.javaee-api>8.0.1</version.javaee-api>
<version.arquillian>1.5.0.Final</version.arquillian>
<!-- test dependencies -->
<version.assertj>3.15.0</version.assertj>
<version.junit.jupiter>5.6.0</version.junit.jupiter>
<version.log4j>2.13.0</version.log4j>
<version.archunit>0.13.0</version.archunit>
<version.mockito>3.2.4</version.mockito>
<version.junit.mockito>3.2.4</version.junit.mockito>
<!-- byte buddy 1.9.7+ is needed to solve dependency errors with
spring mock tests see LdapClientTest -->
<version.byte-buddy>1.10.7</version.byte-buddy>
<version.byte-buddy-agent>1.10.7</version.byte-buddy-agent>
<version.powermock>2.0.5</version.powermock>
<version.hamcrest>2.2</version.hamcrest>
<version.equalsverifier>3.1.12</version.equalsverifier>
<version.openpojo>0.8.13</version.openpojo>
<version.jacoco>0.8.5</version.jacoco>
<!-- database driver versions -->
<version.h2>1.4.200</version.h2>
<version.db2>11.1.1.1</version.db2>
<version.postgres>42.2.9</version.postgres>
<!-- used by jacoco to collect coverage -->
<argLine></argLine>
</properties>
<developers>
<developer>
<name>Holger Hagen</name>
<email>holger.hagen@novatec-gmbh.de</email>
<organization>Novatec Consulting GmbH</organization>
<organizationUrl>https://www.novatec-gmbh.de</organizationUrl>
</developer>
</developers>
<scm>
<url>http://github.com/taskana/taskana/tree/master</url>
<connection>scm:git:git://github.com/taskana/taskana.git</connection>
<developerConnection>scm:git:ssh://github.com:taskana/taskana.git</developerConnection>
</scm>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<profiles>
<profile>
<id>snapshot</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${version.maven.gpg}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${version.sonatype}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</profile>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>${version.maven.gpg}</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>${version.sonatype}</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</profile>
<profile>
<id>eclipse</id>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<versionRange>[1.0.0,)</versionRange>
<goals>
<goal>check</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>coverage</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${version.jacoco}</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<!-- This plugin appends version information into the jar, so
that it can be extracted from the jar. See TSK-837 for more information -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${version.maven.jar}</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${version.maven.compiler}</version>
<configuration>
<showWarnings>true</showWarnings>
<failOnWarning>true</failOnWarning>
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-proc:none</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${version.maven.source}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${version.maven.javadoc}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.surefire}</version>
<configuration>
<argLine>${argLine}</argLine>
<!-- Required for generation of REST documentation -->
<includes>
<include>**/*Test.java</include>
<include>**/*Documentation.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${version.maven.checkstyle}</version>
<dependencies>
<dependency>
<artifactId>checkstyle</artifactId>
<groupId>com.puppycrawl.tools</groupId>
<version>${version.checkstyle}</version>
</dependency>
</dependencies>
<configuration>
<configLocation>qa/checkstyle/checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<failOnViolation>true</failOnViolation>
<violationSeverity>warning</violationSeverity>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,213 +1,213 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-boot</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for taskana-rest-spring</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>
<version>${version.db2}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/postgresql/postgresql -->
<!-- Postgresql driver dependency -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${version.postgres}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring-example-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>history.plugin</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring.boot}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-rest-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
../taskana-rest-spring/target/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-core-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-core
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-core/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-cdi-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-cdi
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-cdi/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-spring-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-spring
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-spring/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<!-- this repository is needed to fetch com.ibm.db2.jcc -->
<repository>
<id>novatec public</id>
<name>novatec-repository</name>
<url>https://repository.novatec-gmbh.de/content/repositories/novatec/</url>
</repository>
</repositories>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-boot</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for taskana-rest-spring</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>
<version>${version.db2}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/postgresql/postgresql -->
<!-- Postgresql driver dependency -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>${version.postgres}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring-example-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>history.plugin</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>pro.taskana.simplehistory</groupId>
<artifactId>taskana-simplehistory-rest-spring</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring.boot}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-rest-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
../taskana-rest-spring/target/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-core-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-core
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-core/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-cdi-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-cdi
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-cdi/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-taskana-spring-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/java/taskana-spring
</outputDirectory>
<resources>
<resource>
<directory>
../../lib/taskana-spring/target/apidocs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<!-- this repository is needed to fetch com.ibm.db2.jcc -->
<repository>
<id>novatec public</id>
<name>novatec-repository</name>
<url>https://repository.novatec-gmbh.de/content/repositories/novatec/</url>
</repository>
</repositories>
</project>

View File

@ -1,73 +1,73 @@
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();
}
}
}
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,4 +1,4 @@
logging.level.pro.taskana=DEBUG
logging.level.pro.taskana=INFO
server.servlet.context-path=/taskana
### logging.level.org.springframework=DEBUG
######## Taskana DB #######

View File

@ -1,128 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-common</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>groups the minimum required configuration for a taskana REST APP</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-data</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>${version.spring.ldap}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<!-- Since taskana-web packs its content in /static, we do not have
to unpack it again. However, when any local change has to be done to that
folder you have to copy target/classes/static manually from taskana-web. -->
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-web</artifactId>
<version>${project.version}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${version.spring.boot}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${version.spring.security}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-test</artifactId>
<version>${version.spring.ldap}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-common</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<description>groups the minimum required configuration for a taskana REST APP</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-data</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>${version.spring.ldap}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${version.spring.boot}</version>
</dependency>
<!-- Since taskana-web packs its content in /static, we do not have
to unpack it again. However, when any local change has to be done to that
folder you have to copy target/classes/static manually from taskana-web. -->
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-web</artifactId>
<version>${project.version}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${version.spring.boot}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${version.spring.security}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${version.h2}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-test</artifactId>
<version>${version.spring.ldap}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -1,80 +1,80 @@
package pro.taskana;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/** Helps to simplify rest api testing. */
@Component
public class RestHelper {
public static final RestTemplate template = getRestTemplate();
@Autowired Environment environment;
public String toUrl(String relativeUrl, Object... uriVariables) {
return UriComponentsBuilder.fromPath(relativeUrl)
.scheme("http")
.host("127.0.0.1")
.port(environment.getProperty("local.server.port"))
.build(false)
.expand(uriVariables)
.toString();
}
public HttpEntity<String> defaultRequest() {
return new HttpEntity<>(getHeaders());
}
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
headers.add("Content-Type", "application/json");
return headers;
}
public HttpHeaders getHeadersAdmin() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
headers.add("Content-Type", "application/hal+json");
return headers;
}
public HttpHeaders getHeadersBusinessAdmin() {
HttpHeaders headers = new HttpHeaders();
// businessadmin:businessadmin
headers.add("Authorization", "Basic YnVzaW5lc3NhZG1pbjpidXNpbmVzc2FkbWlu");
headers.add("Content-Type", "application/hal+json");
return headers;
}
/**
* Return a REST template which is capable of dealing with responses in HAL format.
*
* @return RestTemplate
*/
public static RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate();
// important to add first to ensure priority
template.getMessageConverters().add(0, converter);
return template;
}
}
package pro.taskana;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/** Helps to simplify rest api testing. */
@Component
public class RestHelper {
public static final RestTemplate template = getRestTemplate();
@Autowired Environment environment;
public String toUrl(String relativeUrl, Object... uriVariables) {
return UriComponentsBuilder.fromPath(relativeUrl)
.scheme("http")
.host("127.0.0.1")
.port(environment.getProperty("local.server.port"))
.build(false)
.expand(uriVariables)
.toString();
}
public HttpEntity<String> defaultRequest() {
return new HttpEntity<>(getHeaders());
}
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
headers.add("Content-Type", "application/json");
return headers;
}
public HttpHeaders getHeadersAdmin() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
headers.add("Content-Type", "application/hal+json");
return headers;
}
public HttpHeaders getHeadersBusinessAdmin() {
HttpHeaders headers = new HttpHeaders();
// businessadmin:businessadmin
headers.add("Authorization", "Basic YnVzaW5lc3NhZG1pbjpidXNpbmVzc2FkbWlu");
headers.add("Content-Type", "application/hal+json");
return headers;
}
/**
* Return a REST template which is capable of dealing with responses in HAL format.
*
* @return RestTemplate
*/
public static RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate();
// important to add first to ensure priority
template.getMessageConverters().add(0, converter);
return template;
}
}

View File

@ -1,168 +1,167 @@
package pro.taskana.jobs;
import static org.assertj.core.api.Assertions.assertThat;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.RestTemplate;
import pro.taskana.RestHelper;
import pro.taskana.classification.api.Classification;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.rest.Mapping;
import pro.taskana.rest.RestConfiguration;
import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.ClassificationResourceAssembler;
import pro.taskana.rest.resource.TaskResource;
import pro.taskana.rest.resource.TaskResourceAssembler;
import pro.taskana.task.api.Task;
/** Test async updates. */
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.allow-bean-definition-overriding=true")
class AsyncUpdateJobIntTest {
private static final String CLASSIFICATION_ID = "CLI:100000000000000000000000000000000003";
@SuppressWarnings("checkstyle:DeclarationOrder")
static RestTemplate template;
@Autowired ClassificationResourceAssembler classificationResourceAssembler;
@Autowired TaskResourceAssembler taskResourceAssembler;
@Autowired JobScheduler jobScheduler;
@Autowired RestHelper restHelper;
@BeforeAll
static void init() {
template = RestHelper.getRestTemplate();
}
@Test
void testUpdateClassificationPrioServiceLevel() throws Exception {
// 1st step: get old classification :
final Instant before = Instant.now();
final ObjectMapper mapper = new ObjectMapper();
ResponseEntity<ClassificationResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(response.getBody()).isNotNull();
ClassificationResource classification = response.getBody();
assertThat(classification.getLink(Link.REL_SELF)).isNotNull();
// 2nd step: modify classification and trigger update
classification.removeLinks();
classification.setServiceLevel("P5D");
classification.setPriority(1000);
template.put(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
new HttpEntity<>(mapper.writeValueAsString(classification), restHelper.getHeaders()));
// trigger jobs twice to refresh all entries. first entry on the first call and follow up on the
// seconds call
jobScheduler.triggerJobs();
jobScheduler.triggerJobs();
// verify the classification modified timestamp is after 'before'
ResponseEntity<ClassificationResource> repeatedResponse =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(repeatedResponse.getBody()).isNotNull();
ClassificationResource modifiedClassificationResource = repeatedResponse.getBody();
Classification modifiedClassification =
classificationResourceAssembler.toModel(modifiedClassificationResource);
assertThat(before).isBefore(modifiedClassification.getModified());
List<String> affectedTasks =
new ArrayList<>(
Arrays.asList(
"TKI:000000000000000000000000000000000003",
"TKI:000000000000000000000000000000000004",
"TKI:000000000000000000000000000000000005",
"TKI:000000000000000000000000000000000006",
"TKI:000000000000000000000000000000000007",
"TKI:000000000000000000000000000000000008",
"TKI:000000000000000000000000000000000009",
"TKI:000000000000000000000000000000000010",
"TKI:000000000000000000000000000000000011",
"TKI:000000000000000000000000000000000012",
"TKI:000000000000000000000000000000000013",
"TKI:000000000000000000000000000000000014",
"TKI:000000000000000000000000000000000015",
"TKI:000000000000000000000000000000000016",
"TKI:000000000000000000000000000000000017",
"TKI:000000000000000000000000000000000018",
"TKI:000000000000000000000000000000000019",
"TKI:000000000000000000000000000000000020",
"TKI:000000000000000000000000000000000021",
"TKI:000000000000000000000000000000000022",
"TKI:000000000000000000000000000000000023",
"TKI:000000000000000000000000000000000024",
"TKI:000000000000000000000000000000000025",
"TKI:000000000000000000000000000000000026",
"TKI:000000000000000000000000000000000027",
"TKI:000000000000000000000000000000000028",
"TKI:000000000000000000000000000000000029",
"TKI:000000000000000000000000000000000030",
"TKI:000000000000000000000000000000000031",
"TKI:000000000000000000000000000000000032",
"TKI:000000000000000000000000000000000033",
"TKI:000000000000000000000000000000000034",
"TKI:000000000000000000000000000000000035",
"TKI:000000000000000000000000000000000100",
"TKI:000000000000000000000000000000000101",
"TKI:000000000000000000000000000000000102",
"TKI:000000000000000000000000000000000103"));
for (String taskId : affectedTasks) {
verifyTaskIsModifiedAfterOrEquals(taskId, before);
}
}
private void verifyTaskIsModifiedAfterOrEquals(String taskId, Instant before)
throws InvalidArgumentException {
ResponseEntity<TaskResource> taskResponse =
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS_ID, taskId),
HttpMethod.GET,
new HttpEntity<>(restHelper.getHeadersAdmin()),
ParameterizedTypeReference.forType(TaskResource.class));
TaskResource taskResource = taskResponse.getBody();
Task task = taskResourceAssembler.toModel(taskResource);
Instant modified = task.getModified();
assertThat(before).as("Task " + task.getId() + " has not been refreshed.").isBefore(modified);
}
}
package pro.taskana.jobs;
import static org.assertj.core.api.Assertions.assertThat;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.hateoas.Link;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.web.client.RestTemplate;
import pro.taskana.RestHelper;
import pro.taskana.classification.api.Classification;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.rest.Mapping;
import pro.taskana.rest.RestConfiguration;
import pro.taskana.rest.resource.ClassificationResource;
import pro.taskana.rest.resource.ClassificationResourceAssembler;
import pro.taskana.rest.resource.TaskResource;
import pro.taskana.rest.resource.TaskResourceAssembler;
import pro.taskana.task.api.Task;
/** Test async updates. */
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class AsyncUpdateJobIntTest {
private static final String CLASSIFICATION_ID = "CLI:100000000000000000000000000000000003";
@SuppressWarnings("checkstyle:DeclarationOrder")
static RestTemplate template;
@Autowired ClassificationResourceAssembler classificationResourceAssembler;
@Autowired TaskResourceAssembler taskResourceAssembler;
@Autowired JobScheduler jobScheduler;
@Autowired RestHelper restHelper;
@BeforeAll
static void init() {
template = RestHelper.getRestTemplate();
}
@Test
void testUpdateClassificationPrioServiceLevel() throws Exception {
// 1st step: get old classification :
final Instant before = Instant.now();
final ObjectMapper mapper = new ObjectMapper();
ResponseEntity<ClassificationResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(response.getBody()).isNotNull();
ClassificationResource classification = response.getBody();
assertThat(classification.getLink(Link.REL_SELF)).isNotNull();
// 2nd step: modify classification and trigger update
classification.removeLinks();
classification.setServiceLevel("P5D");
classification.setPriority(1000);
template.put(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
new HttpEntity<>(mapper.writeValueAsString(classification), restHelper.getHeaders()));
// trigger jobs twice to refresh all entries. first entry on the first call and follow up on the
// seconds call
jobScheduler.triggerJobs();
jobScheduler.triggerJobs();
// verify the classification modified timestamp is after 'before'
ResponseEntity<ClassificationResource> repeatedResponse =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, CLASSIFICATION_ID),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(repeatedResponse.getBody()).isNotNull();
ClassificationResource modifiedClassificationResource = repeatedResponse.getBody();
Classification modifiedClassification =
classificationResourceAssembler.toModel(modifiedClassificationResource);
assertThat(before).isBefore(modifiedClassification.getModified());
List<String> affectedTasks =
new ArrayList<>(
Arrays.asList(
"TKI:000000000000000000000000000000000003",
"TKI:000000000000000000000000000000000004",
"TKI:000000000000000000000000000000000005",
"TKI:000000000000000000000000000000000006",
"TKI:000000000000000000000000000000000007",
"TKI:000000000000000000000000000000000008",
"TKI:000000000000000000000000000000000009",
"TKI:000000000000000000000000000000000010",
"TKI:000000000000000000000000000000000011",
"TKI:000000000000000000000000000000000012",
"TKI:000000000000000000000000000000000013",
"TKI:000000000000000000000000000000000014",
"TKI:000000000000000000000000000000000015",
"TKI:000000000000000000000000000000000016",
"TKI:000000000000000000000000000000000017",
"TKI:000000000000000000000000000000000018",
"TKI:000000000000000000000000000000000019",
"TKI:000000000000000000000000000000000020",
"TKI:000000000000000000000000000000000021",
"TKI:000000000000000000000000000000000022",
"TKI:000000000000000000000000000000000023",
"TKI:000000000000000000000000000000000024",
"TKI:000000000000000000000000000000000025",
"TKI:000000000000000000000000000000000026",
"TKI:000000000000000000000000000000000027",
"TKI:000000000000000000000000000000000028",
"TKI:000000000000000000000000000000000029",
"TKI:000000000000000000000000000000000030",
"TKI:000000000000000000000000000000000031",
"TKI:000000000000000000000000000000000032",
"TKI:000000000000000000000000000000000033",
"TKI:000000000000000000000000000000000034",
"TKI:000000000000000000000000000000000035",
"TKI:000000000000000000000000000000000100",
"TKI:000000000000000000000000000000000101",
"TKI:000000000000000000000000000000000102",
"TKI:000000000000000000000000000000000103"));
for (String taskId : affectedTasks) {
verifyTaskIsModifiedAfterOrEquals(taskId, before);
}
}
private void verifyTaskIsModifiedAfterOrEquals(String taskId, Instant before)
throws InvalidArgumentException {
ResponseEntity<TaskResource> taskResponse =
template.exchange(
restHelper.toUrl(Mapping.URL_TASKS_ID, taskId),
HttpMethod.GET,
new HttpEntity<>(restHelper.getHeadersAdmin()),
ParameterizedTypeReference.forType(TaskResource.class));
TaskResource taskResource = taskResponse.getBody();
Task task = taskResourceAssembler.toModel(taskResource);
Instant modified = task.getModified();
assertThat(before).as("Task " + task.getId() + " has not been refreshed.").isBefore(modified);
}
}

View File

@ -1,37 +1,36 @@
package pro.taskana.ldap;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import pro.taskana.common.api.LoggerUtils;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.rest.RestConfiguration;
import pro.taskana.rest.resource.AccessIdResource;
/** Test Ldap attachment. */
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.allow-bean-definition-overriding=true")
class LdapTest {
@Autowired private LdapClient ldapClient;
@Test
void testFindUsers() throws InvalidArgumentException {
if (ldapClient.useLdap()) {
List<AccessIdResource> usersAndGroups = ldapClient.searchUsersAndGroups("ser0");
System.out.println("#### found " + LoggerUtils.listToString(usersAndGroups));
assertThat(usersAndGroups.size()).isEqualTo(50);
}
}
package pro.taskana.ldap;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import pro.taskana.common.api.LoggerUtils;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.rest.RestConfiguration;
import pro.taskana.rest.resource.AccessIdResource;
/** Test Ldap attachment. */
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class LdapTest {
@Autowired private LdapClient ldapClient;
@Test
void testFindUsers() throws InvalidArgumentException {
if (ldapClient.useLdap()) {
List<AccessIdResource> usersAndGroups = ldapClient.searchUsersAndGroups("ser0");
System.out.println("#### found " + LoggerUtils.listToString(usersAndGroups));
assertThat(usersAndGroups).hasSize(50);
}
}
}

View File

@ -1,73 +1,73 @@
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();
}
}
}
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

@ -36,6 +36,7 @@ taskana.ldap.maxNumberOfReturnedAccessIds=50
taskana.jobscheduler.async.cron=0 0 * * * *
####### cache static resources properties
spring.resources.cache.cachecontrol.cache-private=true
spring.main.allow-bean-definition-overriding=true
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.internal-proxies=.*
server.use-forward-headers=true

View File

@ -1,360 +1,360 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-wildfly</artifactId>
<packaging>war</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for the taskana REST APP in a wildfly environment.</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<skipIntegrationTests>true</skipIntegrationTests>
<!-- Default H2 DB configuration -->
<connection-url>jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0</connection-url>
<driver-class>org.h2.Driver</driver-class>
<driver-name>h2</driver-name>
<user-name>sa</user-name>
<password>sa</password>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>bom</artifactId>
<version>${version.thorntail}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${version.arquillian}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring-example-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron</artifactId>
<version>${version.wildfly.security}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${version.resteasy}</version>
<scope>test</scope>
</dependency>
<!-- Brought in via WildFly Swarm bom -->
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>arquillian</artifactId>
<scope>test</scope>
</dependency>
<!-- Brought in via Arquillian BOM, see dependencyManagement section
above -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-api-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>postgres</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<!-- Reading properties from file and use then as data source
properties is a pending improvement of Jboss development team check out ->
https://issues.jboss.org/browse/WFMP-70 That's why we are including postgres
connection properties directly in this pom file. -->
<properties>
<driver-class>org.postgresql.Driver</driver-class>
<connection-url>jdbc:postgresql://localhost:50102/postgres</connection-url>
<driver-name>postgresqldriver</driver-name>
<user-name>postgres</user-name>
<password>postgres</password>
<activatedProperties>postgres</activatedProperties>
<skipIntegrationTests>false</skipIntegrationTests>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.maven.wildfly}</version>
<configuration>
<version>${version.wildfly}</version>
<add-user>
<users>
<user>
<username>admin</username>
<password>admin</password>
</user>
<user>
<username>admin</username>
<password>admin</password>
<groups>
<group>testGroup</group>
</groups>
<applicationUser>true</applicationUser>
</user>
</users>
</add-user>
</configuration>
<executions>
<execution>
<id>run-wildfly</id>
<phase>install</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<!-- Deploy the JDBC library in JBoss -->
<execution>
<id>deploy-driver</id>
<phase>install</phase>
<configuration>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<name>postgresqldriver</name>
</configuration>
<goals>
<goal>deploy-artifact</goal>
</goals>
</execution>
<!-- Add a data source -->
<execution>
<id>add-datasource</id>
<phase>install</phase>
<configuration>
<address>subsystem=datasources,data-source=java:/TaskanaDS</address>
<resources>
<resource>
<properties>
<jndi-name>java:/TaskanaDS</jndi-name>
<enabled>true</enabled>
<connection-url>${connection-url}</connection-url>
<driver-class>${driver-class}</driver-class>
<driver-name>${driver-name}</driver-name>
<user-name>${user-name}</user-name>
<password>${password}</password>
</properties>
</resource>
</resources>
</configuration>
<goals>
<goal>add-resource</goal>
</goals>
</execution>
<execution>
<id>edit-undertow</id>
<phase>install</phase>
<goals>
<goal>execute-commands</goal>
</goals>
<configuration>
<commands>
<command>/subsystem=undertow:write-attribute(name=default-server,value=default-server)</command>
<command>/subsystem=undertow:write-attribute(name=default-virtual-host,value=default-host)</command>
<command>/subsystem=undertow:write-attribute(name=default-servlet-container,value=default)</command>
<command>/subsystem=undertow:write-attribute(name=default-security-domain,value=ApplicationDomain)</command>
</commands>
</configuration>
</execution>
<execution>
<id>add-application-security-domain</id>
<phase>install</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<address>subsystem=undertow</address>
<resources>
<resource>
<address>application-security-domain=ApplicationDomain</address>
<properties>
<http-authentication-factory>application-http-authentication</http-authentication-factory>
</properties>
</resource>
</resources>
</configuration>
</execution>
<!-- Deploy the application on install -->
<execution>
<id>wildfly-deploy</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
<!-- shutdown the application on install -->
<execution>
<id>wildfly-shutdown</id>
<phase>install</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.surefire}</version>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
<execution>
<id>integration-tests</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>${skipIntegrationTests}</skip>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
../taskana-rest-spring/target/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>taskana-rest-spring-example-wildfly</artifactId>
<packaging>war</packaging>
<name>${project.groupId}:${project.artifactId}</name>
<description>Demo project for the taskana REST APP in a wildfly environment.</description>
<parent>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-parent</artifactId>
<version>1.2.3-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<skipIntegrationTests>true</skipIntegrationTests>
<!-- Default H2 DB configuration -->
<connection-url>jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0</connection-url>
<driver-class>org.h2.Driver</driver-class>
<driver-name>h2</driver-name>
<user-name>sa</user-name>
<password>sa</password>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>bom</artifactId>
<version>${version.thorntail}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${version.arquillian}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring.boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>pro.taskana</groupId>
<artifactId>taskana-rest-spring-example-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>${version.spring.hateos}</version>
</dependency>
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${version.spring.core}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.wildfly.security</groupId>
<artifactId>wildfly-elytron</artifactId>
<version>${version.wildfly.security}</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>${version.resteasy}</version>
<scope>test</scope>
</dependency>
<!-- Brought in via WildFly Swarm bom -->
<dependency>
<groupId>io.thorntail</groupId>
<artifactId>arquillian</artifactId>
<scope>test</scope>
</dependency>
<!-- Brought in via Arquillian BOM, see dependencyManagement section
above -->
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-api-maven</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>postgres</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<!-- Reading properties from file and use then as data source
properties is a pending improvement of Jboss development team check out ->
https://issues.jboss.org/browse/WFMP-70 That's why we are including postgres
connection properties directly in this pom file. -->
<properties>
<driver-class>org.postgresql.Driver</driver-class>
<connection-url>jdbc:postgresql://localhost:50102/postgres</connection-url>
<driver-name>postgresqldriver</driver-name>
<user-name>postgres</user-name>
<password>postgres</password>
<activatedProperties>postgres</activatedProperties>
<skipIntegrationTests>false</skipIntegrationTests>
</properties>
</profile>
</profiles>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>${version.maven.wildfly}</version>
<configuration>
<version>${version.wildfly}</version>
<add-user>
<users>
<user>
<username>admin</username>
<password>admin</password>
</user>
<user>
<username>admin</username>
<password>admin</password>
<groups>
<group>testGroup</group>
</groups>
<applicationUser>true</applicationUser>
</user>
</users>
</add-user>
</configuration>
<executions>
<execution>
<id>run-wildfly</id>
<phase>install</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<!-- Deploy the JDBC library in JBoss -->
<execution>
<id>deploy-driver</id>
<phase>install</phase>
<configuration>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<name>postgresqldriver</name>
</configuration>
<goals>
<goal>deploy-artifact</goal>
</goals>
</execution>
<!-- Add a data source -->
<execution>
<id>add-datasource</id>
<phase>install</phase>
<configuration>
<address>subsystem=datasources,data-source=java:/TaskanaDS</address>
<resources>
<resource>
<properties>
<jndi-name>java:/TaskanaDS</jndi-name>
<enabled>true</enabled>
<connection-url>${connection-url}</connection-url>
<driver-class>${driver-class}</driver-class>
<driver-name>${driver-name}</driver-name>
<user-name>${user-name}</user-name>
<password>${password}</password>
</properties>
</resource>
</resources>
</configuration>
<goals>
<goal>add-resource</goal>
</goals>
</execution>
<execution>
<id>edit-undertow</id>
<phase>install</phase>
<goals>
<goal>execute-commands</goal>
</goals>
<configuration>
<commands>
<command>/subsystem=undertow:write-attribute(name=default-server,value=default-server)</command>
<command>/subsystem=undertow:write-attribute(name=default-virtual-host,value=default-host)</command>
<command>/subsystem=undertow:write-attribute(name=default-servlet-container,value=default)</command>
<command>/subsystem=undertow:write-attribute(name=default-security-domain,value=ApplicationDomain)</command>
</commands>
</configuration>
</execution>
<execution>
<id>add-application-security-domain</id>
<phase>install</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<address>subsystem=undertow</address>
<resources>
<resource>
<address>application-security-domain=ApplicationDomain</address>
<properties>
<http-authentication-factory>application-http-authentication</http-authentication-factory>
</properties>
</resource>
</resources>
</configuration>
</execution>
<!-- Deploy the application on install -->
<execution>
<id>wildfly-deploy</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
<!-- shutdown the application on install -->
<execution>
<id>wildfly-shutdown</id>
<phase>install</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${version.maven.surefire}</version>
<executions>
<execution>
<id>default-test</id>
<configuration>
<skip>true</skip>
</configuration>
</execution>
<execution>
<id>integration-tests</id>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>${skipIntegrationTests}</skip>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${version.maven.resources}</version>
<executions>
<execution>
<id>copy-documentation-to-static-folder</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.outputDirectory}/static/docs/rest
</outputDirectory>
<resources>
<resource>
<directory>
../taskana-rest-spring/target/generated-docs
</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
</project>

View File

@ -1,121 +1,121 @@
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();
}
}
}
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() {
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

@ -1,44 +1,44 @@
spring.profiles.active=@activatedProperties@
logging.level.pro.taskana=INFO
### logging.level.org.springframework=DEBUG
######## Taskana DB #######
datasource.jndi=java:/TaskanaDS
taskana.schemaName=TASKANA
####### control LDAP usage
taskana.ldap.useLdap=false
####### properties to connect to LDAP
taskana.ldap.serverUrl=ldap://localhost:10389
taskana.ldap.bindDn=uid=admin,ou=system
taskana.ldap.bindPassword=secret
taskana.ldap.baseDn=o=TaskanaTest
####### properties that control search for users and groups
taskana.ldap.userSearchBase=ou=people
taskana.ldap.userSearchFilterName=objectclass
taskana.ldap.userSearchFilterValue=person
taskana.ldap.userFirstnameAttribute=givenName
taskana.ldap.userLastnameAttribute=sn
taskana.ldap.userIdAttribute=uid
taskana.ldap.groupSearchBase=ou=groups
taskana.ldap.groupSearchFilterName=objectclass
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
taskana.ldap.groupNameAttribute=cn
taskana.ldap.minSearchForLength=3
taskana.ldap.maxNumberOfReturnedAccessIds=50
taskana.ldap.groupsOfUser=memberUid
####### JobScheduler cron expression that specifies when the JobSchedler runs
taskana.jobscheduler.async.cron=0 * * * * *
####### cache static resources properties
spring.resources.cache.cachecontrol.cache-private=true
####### for upload of big workbasket- or classification-files
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.main.allow-bean-definition-overriding=true
server.tomcat.max-http-post-size=-1
server.tomcat.max-save-post-size=-1
server.tomcat.max-swallow-size=-1
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.internal-proxies=.*
server.use-forward-headers=true
spring.profiles.active=@activatedProperties@
logging.level.pro.taskana=INFO
### logging.level.org.springframework=DEBUG
######## Taskana DB #######
datasource.jndi=java:/TaskanaDS
taskana.schemaName=TASKANA
####### control LDAP usage
taskana.ldap.useLdap=false
####### properties to connect to LDAP
taskana.ldap.serverUrl=ldap://localhost:10389
taskana.ldap.bindDn=uid=admin,ou=system
taskana.ldap.bindPassword=secret
taskana.ldap.baseDn=o=TaskanaTest
####### properties that control search for users and groups
taskana.ldap.userSearchBase=ou=people
taskana.ldap.userSearchFilterName=objectclass
taskana.ldap.userSearchFilterValue=person
taskana.ldap.userFirstnameAttribute=givenName
taskana.ldap.userLastnameAttribute=sn
taskana.ldap.userIdAttribute=uid
taskana.ldap.groupSearchBase=ou=groups
taskana.ldap.groupSearchFilterName=objectclass
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
taskana.ldap.groupNameAttribute=cn
taskana.ldap.minSearchForLength=3
taskana.ldap.maxNumberOfReturnedAccessIds=50
taskana.ldap.groupsOfUser=memberUid
####### JobScheduler cron expression that specifies when the JobSchedler runs
taskana.jobscheduler.async.cron=0 * * * * *
####### cache static resources properties
spring.resources.cache.cachecontrol.cache-private=true
####### for upload of big workbasket- or classification-files
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
spring.main.allow-bean-definition-overriding=true
server.tomcat.max-http-post-size=-1
server.tomcat.max-save-post-size=-1
server.tomcat.max-swallow-size=-1
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.internal-proxies=.*
server.use-forward-headers=true

View File

@ -31,6 +31,7 @@ taskana.jobscheduler.async.cron=0 * * * * *
####### cache static resources propertiesgit add --
spring.resources.cache.cachecontrol.cache-private=true
spring.main.allow-bean-definition-overriding=true
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.internal-proxies=.*
server.use-forward-headers=true

View File

@ -1,78 +1,78 @@
package pro.taskana.rest;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.http.converter.json.SpringHandlerInstantiator;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.configuration.SpringTaskanaEngineConfiguration;
import pro.taskana.ldap.LdapClient;
import pro.taskana.report.api.TaskMonitorService;
import pro.taskana.task.api.TaskService;
import pro.taskana.workbasket.api.WorkbasketService;
/** Configuration for REST service. */
@Configuration
@ComponentScan
@EnableTransactionManagement
public class RestConfiguration {
@Value("${taskana.schemaName:TASKANA}")
private String schemaName;
@Bean
public ClassificationService getClassificationService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getClassificationService();
}
@Bean
public TaskService getTaskService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getTaskService();
}
@Bean
public TaskMonitorService getTaskMonitorService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getTaskMonitorService();
}
@Bean
public WorkbasketService getWorkbasketService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getWorkbasketService();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration) {
return taskanaEngineConfiguration.buildTaskanaEngine();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource)
throws SQLException {
return new SpringTaskanaEngineConfiguration(dataSource, true, true, schemaName);
}
@Bean
public LdapClient ldapClient() {
return new LdapClient();
}
// Needed for injection into jackson deserializer.
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext context) {
return new SpringHandlerInstantiator(context.getAutowireCapableBeanFactory());
}
}
package pro.taskana.rest;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.http.converter.json.SpringHandlerInstantiator;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import pro.taskana.TaskanaEngineConfiguration;
import pro.taskana.classification.api.ClassificationService;
import pro.taskana.common.api.TaskanaEngine;
import pro.taskana.configuration.SpringTaskanaEngineConfiguration;
import pro.taskana.ldap.LdapClient;
import pro.taskana.report.api.TaskMonitorService;
import pro.taskana.task.api.TaskService;
import pro.taskana.workbasket.api.WorkbasketService;
/** Configuration for REST service. */
@Configuration
@ComponentScan
@EnableTransactionManagement
public class RestConfiguration {
@Value("${taskana.schemaName:TASKANA}")
private String schemaName;
@Bean
public ClassificationService getClassificationService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getClassificationService();
}
@Bean
public TaskService getTaskService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getTaskService();
}
@Bean
public TaskMonitorService getTaskMonitorService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getTaskMonitorService();
}
@Bean
public WorkbasketService getWorkbasketService(TaskanaEngine taskanaEngine) {
return taskanaEngine.getWorkbasketService();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngine getTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration) {
return taskanaEngineConfiguration.buildTaskanaEngine();
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public TaskanaEngineConfiguration taskanaEngineConfiguration(DataSource dataSource)
throws SQLException {
return new SpringTaskanaEngineConfiguration(dataSource, true, true, schemaName);
}
@Bean
public LdapClient ldapClient() {
return new LdapClient();
}
// Needed for injection into jackson deserializer.
@Bean
public HandlerInstantiator handlerInstantiator(ApplicationContext context) {
return new SpringHandlerInstantiator(context.getAutowireCapableBeanFactory());
}
}

View File

@ -1,80 +1,80 @@
package pro.taskana;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/** Helps to simplify rest api testing. */
@Component
public class RestHelper {
public static final RestTemplate template = getRestTemplate();
@Autowired Environment environment;
public String toUrl(String relativeUrl, Object... uriVariables) {
return UriComponentsBuilder.fromPath(relativeUrl)
.scheme("http")
.host("127.0.0.1")
.port(environment.getProperty("local.server.port"))
.build(false)
.expand(uriVariables)
.toString();
}
public HttpEntity<String> defaultRequest() {
return new HttpEntity<>(getHeaders());
}
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
headers.add("Content-Type", "application/json");
return headers;
}
public HttpHeaders getHeadersAdmin() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
headers.add("Content-Type", "application/hal+json");
return headers;
}
public HttpHeaders getHeadersBusinessAdmin() {
HttpHeaders headers = new HttpHeaders();
// businessadmin:businessadmin
headers.add("Authorization", "Basic YnVzaW5lc3NhZG1pbjpidXNpbmVzc2FkbWlu");
headers.add("Content-Type", "application/hal+json");
return headers;
}
/**
* Return a REST template which is capable of dealing with responses in HAL format.
*
* @return RestTemplate
*/
public static RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate();
// important to add first to ensure priority
template.getMessageConverters().add(0, converter);
return template;
}
}
package pro.taskana;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.hateoas.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
/** Helps to simplify rest api testing. */
@Component
public class RestHelper {
public static final RestTemplate template = getRestTemplate();
@Autowired Environment environment;
public String toUrl(String relativeUrl, Object... uriVariables) {
return UriComponentsBuilder.fromPath(relativeUrl)
.scheme("http")
.host("127.0.0.1")
.port(environment.getProperty("local.server.port"))
.build(false)
.expand(uriVariables)
.toString();
}
public HttpEntity<String> defaultRequest() {
return new HttpEntity<>(getHeaders());
}
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
headers.add("Content-Type", "application/json");
return headers;
}
public HttpHeaders getHeadersAdmin() {
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic YWRtaW46YWRtaW4="); // admin:admin
headers.add("Content-Type", "application/hal+json");
return headers;
}
public HttpHeaders getHeadersBusinessAdmin() {
HttpHeaders headers = new HttpHeaders();
// businessadmin:businessadmin
headers.add("Authorization", "Basic YnVzaW5lc3NhZG1pbjpidXNpbmVzc2FkbWlu");
headers.add("Content-Type", "application/hal+json");
return headers;
}
/**
* Return a REST template which is capable of dealing with responses in HAL format.
*
* @return RestTemplate
*/
public static RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.registerModule(new Jackson2HalModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"));
converter.setObjectMapper(mapper);
RestTemplate template = new RestTemplate();
// important to add first to ensure priority
template.getMessageConverters().add(0, converter);
return template;
}
}

View File

@ -1,25 +1,24 @@
package pro.taskana;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import pro.taskana.rest.RestConfiguration;
/** Use this annotation to test with a spring context and a standardized configuration. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = "spring.main.allow-bean-definition-overriding=true")
public @interface TaskanaSpringBootTest {}
package pro.taskana;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import pro.taskana.rest.RestConfiguration;
/** Use this annotation to test with a spring context and a standardized configuration. */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@ActiveProfiles({"test"})
@ExtendWith(SpringExtension.class)
@SpringBootTest(
classes = RestConfiguration.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public @interface TaskanaSpringBootTest {}

View File

@ -1,364 +1,364 @@
package pro.taskana.doc.api;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import pro.taskana.rest.Mapping;
/** Generate REST Dokumentation for ClassificationController. */
class ClassificationControllerRestDocumentation extends BaseRestDocumentation {
private HashMap<String, String> classificationFieldDescriptionsMap =
new HashMap<String, String>();
private FieldDescriptor[] allClassificationsFieldDescriptors;
private FieldDescriptor[] classificationFieldDescriptors;
private FieldDescriptor[] classificationSubsetFieldDescriptors;
private FieldDescriptor[] createClassificationFieldDescriptors;
@BeforeEach
void setUp() {
classificationFieldDescriptionsMap.put("classificationId", "Unique Id");
classificationFieldDescriptionsMap.put(
"key",
"The key of the classification. This is typically an externally "
+ "known code or abbreviation of the classification");
classificationFieldDescriptionsMap.put(
"parentId",
"The id of the parent classification. Empty string (\"\") "
+ "if this is a root classification.");
classificationFieldDescriptionsMap.put(
"parentKey",
"The key of the parent classification. Empty string (\"\") "
+ "if this is a root classification.");
classificationFieldDescriptionsMap.put(
"category", "The category of the classification (MANUAL, EXTERNAL, AUTOMATIC, PROCESS)");
classificationFieldDescriptionsMap.put("type", "The type of classification (TASK, DOCUMENT)");
classificationFieldDescriptionsMap.put(
"domain", "The domain for which this classification is specified");
classificationFieldDescriptionsMap.put(
"isValidInDomain", "True, if this classification to objects in this domain");
classificationFieldDescriptionsMap.put(
"created", "The creation timestamp of the classification in the system");
classificationFieldDescriptionsMap.put(
"modified", "The timestamp of the last modification date");
classificationFieldDescriptionsMap.put("name", "The name of the classification");
classificationFieldDescriptionsMap.put("description", "The description of the classification");
classificationFieldDescriptionsMap.put("priority", "The priority of the classification");
classificationFieldDescriptionsMap.put(
"serviceLevel",
"The service level of the classification. This is stated according to ISO 8601");
classificationFieldDescriptionsMap.put(
"applicationEntryPoint",
"The logical name of the entry point, the task list application "
+ "should redirect to work on a task of this classification");
classificationFieldDescriptionsMap.put("custom1", "A custom property with name \"1\"");
classificationFieldDescriptionsMap.put("custom2", "A custom property with name \"2\"");
classificationFieldDescriptionsMap.put("custom3", "A custom property with name \"3\"");
classificationFieldDescriptionsMap.put("custom4", "A custom property with name \"4\"");
classificationFieldDescriptionsMap.put("custom5", "A custom property with name \"5\"");
classificationFieldDescriptionsMap.put("custom6", "A custom property with name \"6\"");
classificationFieldDescriptionsMap.put("custom7", "A custom property with name \"7\"");
classificationFieldDescriptionsMap.put("custom8", "A custom property with name \"8\"");
classificationFieldDescriptionsMap.put(
"_links.getAllClassifications.href", "Link to all classifications");
classificationFieldDescriptionsMap.put("_links.getAllClassifications.templated", "");
allClassificationsFieldDescriptors =
new FieldDescriptor[] {
subsectionWithPath("classifications")
.description("An Array of <<classification-subset, Classification-Subsets>>"),
fieldWithPath("_links.self.href").ignored(),
fieldWithPath("page").ignored(),
fieldWithPath("page.size").ignored(),
fieldWithPath("page.totalElements").ignored(),
fieldWithPath("page.totalPages").ignored(),
fieldWithPath("page.number").ignored()
};
classificationFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("classificationId")
.description(classificationFieldDescriptionsMap.get("classificationId")),
fieldWithPath("key").description(classificationFieldDescriptionsMap.get("key")),
fieldWithPath("parentId").description(classificationFieldDescriptionsMap.get("parentId")),
fieldWithPath("parentKey")
.description(classificationFieldDescriptionsMap.get("parentKey")),
fieldWithPath("category").description(classificationFieldDescriptionsMap.get("category")),
fieldWithPath("type").description(classificationFieldDescriptionsMap.get("type")),
fieldWithPath("domain").description(classificationFieldDescriptionsMap.get("domain")),
fieldWithPath("isValidInDomain")
.description(classificationFieldDescriptionsMap.get("isValidInDomain")),
fieldWithPath("created").description(classificationFieldDescriptionsMap.get("created")),
fieldWithPath("modified").description(classificationFieldDescriptionsMap.get("modified")),
fieldWithPath("name").description(classificationFieldDescriptionsMap.get("name")),
fieldWithPath("description")
.description(classificationFieldDescriptionsMap.get("description")),
fieldWithPath("priority").description(classificationFieldDescriptionsMap.get("priority")),
fieldWithPath("serviceLevel")
.description(classificationFieldDescriptionsMap.get("serviceLevel")),
fieldWithPath("applicationEntryPoint")
.description(classificationFieldDescriptionsMap.get("applicationEntryPoint")),
fieldWithPath("custom1").description(classificationFieldDescriptionsMap.get("custom1")),
fieldWithPath("custom2").description(classificationFieldDescriptionsMap.get("custom2")),
fieldWithPath("custom3").description(classificationFieldDescriptionsMap.get("custom3")),
fieldWithPath("custom4").description(classificationFieldDescriptionsMap.get("custom4")),
fieldWithPath("custom5").description(classificationFieldDescriptionsMap.get("custom5")),
fieldWithPath("custom6").description(classificationFieldDescriptionsMap.get("custom6")),
fieldWithPath("custom7").description(classificationFieldDescriptionsMap.get("custom7")),
fieldWithPath("custom8").description(classificationFieldDescriptionsMap.get("custom8")),
fieldWithPath("_links.self.href").ignored()
};
classificationSubsetFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("classificationId")
.description(classificationFieldDescriptionsMap.get("classificationId")),
fieldWithPath("key").description(classificationFieldDescriptionsMap.get("key")),
fieldWithPath("category").description(classificationFieldDescriptionsMap.get("category")),
fieldWithPath("type").description(classificationFieldDescriptionsMap.get("type")),
fieldWithPath("domain").description(classificationFieldDescriptionsMap.get("domain")),
fieldWithPath("isValidInDomain").ignored(),
fieldWithPath("created").ignored(),
fieldWithPath("modified").ignored(),
fieldWithPath("name").description(classificationFieldDescriptionsMap.get("name")),
fieldWithPath("parentId").description(classificationFieldDescriptionsMap.get("parentId")),
fieldWithPath("parentKey")
.description(classificationFieldDescriptionsMap.get("parentKey")),
fieldWithPath("description").ignored(),
fieldWithPath("priority").description(classificationFieldDescriptionsMap.get("priority")),
fieldWithPath("serviceLevel")
.description(classificationFieldDescriptionsMap.get("serviceLevel")),
fieldWithPath("applicationEntryPoint").ignored(),
fieldWithPath("custom1").description(classificationFieldDescriptionsMap.get("custom1")),
fieldWithPath("custom2").description(classificationFieldDescriptionsMap.get("custom2")),
fieldWithPath("custom3").description(classificationFieldDescriptionsMap.get("custom3")),
fieldWithPath("custom4").description(classificationFieldDescriptionsMap.get("custom4")),
fieldWithPath("custom5").description(classificationFieldDescriptionsMap.get("custom5")),
fieldWithPath("custom6").description(classificationFieldDescriptionsMap.get("custom6")),
fieldWithPath("custom7").description(classificationFieldDescriptionsMap.get("custom7")),
fieldWithPath("custom8").description(classificationFieldDescriptionsMap.get("custom8")),
fieldWithPath("_links.self.href").ignored()
};
createClassificationFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("category")
.type("String")
.description(
"The category of the classification (MANUAL, EXTERNAL, AUTOMATIC, PROCESS)")
.optional(),
fieldWithPath("domain")
.description("The domain for which this classification is specified"),
fieldWithPath("key")
.description(
"The key of the classification. This is typically an externally "
+ "known code or abbreviation of the classification"),
fieldWithPath("name")
.type("String")
.description("The name of the classification")
.optional(),
fieldWithPath("type")
.type("String")
.description("The type of classification (TASK, DOCUMENT)")
.optional(),
fieldWithPath("parentId")
.type("String")
.description(classificationFieldDescriptionsMap.get("parentId"))
.optional(),
fieldWithPath("parentKey")
.type("String")
.description(classificationFieldDescriptionsMap.get("parentKey"))
.optional(),
fieldWithPath("isValidInDomain")
.type("Boolean")
.description(classificationFieldDescriptionsMap.get("isValidInDomain"))
.optional(),
fieldWithPath("created")
.type("String")
.description(classificationFieldDescriptionsMap.get("created"))
.optional(),
fieldWithPath("modified")
.type("String")
.description(classificationFieldDescriptionsMap.get("modified"))
.optional(),
fieldWithPath("description")
.type("String")
.description(classificationFieldDescriptionsMap.get("description"))
.optional(),
fieldWithPath("priority")
.type("Number")
.description(classificationFieldDescriptionsMap.get("priority"))
.optional(),
fieldWithPath("serviceLevel")
.type("String")
.description(classificationFieldDescriptionsMap.get("serviceLevel"))
.optional(),
fieldWithPath("applicationEntryPoint")
.type("String")
.description(classificationFieldDescriptionsMap.get("applicationEntryPoint"))
.optional(),
fieldWithPath("custom1")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom1"))
.optional(),
fieldWithPath("custom2")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom2"))
.optional(),
fieldWithPath("custom3")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom3"))
.optional(),
fieldWithPath("custom4")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom4"))
.optional(),
fieldWithPath("custom5")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom5"))
.optional(),
fieldWithPath("custom6")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom6"))
.optional(),
fieldWithPath("custom7")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom7"))
.optional(),
fieldWithPath("custom8")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom8"))
.optional()
};
}
@Test
void getAllClassificationsDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_B")
.accept("application/hal+json")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"GetAllClassificationsDocTest",
responseFields(allClassificationsFieldDescriptors)));
}
@Test
void getSpecificClassificationDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"GetSpecificClassificationDocTest",
responseFields(classificationFieldDescriptors)));
}
@Test
void classificationSubsetDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"ClassificationSubset", responseFields(classificationSubsetFieldDescriptors)));
}
@Test
void createAndDeleteClassificationDocTest() throws Exception {
MvcResult result =
this.mockMvc
.perform(
RestDocumentationRequestBuilders.post(restHelper.toUrl(Mapping.URL_CLASSIFICATIONS))
.contentType("application/hal+json")
.content("{\"key\":\"Key0815casdgdgh\", \"domain\":\"DOMAIN_B\"}")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andDo(
MockMvcRestDocumentation.document(
"CreateClassificationDocTest",
requestFields(createClassificationFieldDescriptors),
responseFields(classificationFieldDescriptors)))
.andReturn();
String content = result.getResponse().getContentAsString();
String newId = content.substring(content.indexOf("CLI:"), content.indexOf("CLI:") + 40);
this.mockMvc
.perform(
RestDocumentationRequestBuilders.delete(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, newId))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isNoContent())
.andDo(MockMvcRestDocumentation.document("DeleteClassificationDocTest"));
}
@Test
void updateClassificationDocTest() throws Exception {
URL url =
new URL(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"));
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
assertEquals(200, con.getResponseCode());
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
String originalTask = content.toString();
String modifiedTask = originalTask;
this.mockMvc
.perform(
RestDocumentationRequestBuilders.put(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x")
.contentType("application/json")
.content(modifiedTask))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"UpdateClassificationDocTest",
requestFields(classificationFieldDescriptors),
responseFields(classificationFieldDescriptors)));
}
}
package pro.taskana.doc.api;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.restdocs.mockmvc.MockMvcRestDocumentation;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import pro.taskana.rest.Mapping;
/** Generate REST Dokumentation for ClassificationController. */
class ClassificationControllerRestDocumentation extends BaseRestDocumentation {
private HashMap<String, String> classificationFieldDescriptionsMap =
new HashMap<String, String>();
private FieldDescriptor[] allClassificationsFieldDescriptors;
private FieldDescriptor[] classificationFieldDescriptors;
private FieldDescriptor[] classificationSubsetFieldDescriptors;
private FieldDescriptor[] createClassificationFieldDescriptors;
@BeforeEach
void setUp() {
classificationFieldDescriptionsMap.put("classificationId", "Unique Id");
classificationFieldDescriptionsMap.put(
"key",
"The key of the classification. This is typically an externally "
+ "known code or abbreviation of the classification");
classificationFieldDescriptionsMap.put(
"parentId",
"The id of the parent classification. Empty string (\"\") "
+ "if this is a root classification.");
classificationFieldDescriptionsMap.put(
"parentKey",
"The key of the parent classification. Empty string (\"\") "
+ "if this is a root classification.");
classificationFieldDescriptionsMap.put(
"category", "The category of the classification (MANUAL, EXTERNAL, AUTOMATIC, PROCESS)");
classificationFieldDescriptionsMap.put("type", "The type of classification (TASK, DOCUMENT)");
classificationFieldDescriptionsMap.put(
"domain", "The domain for which this classification is specified");
classificationFieldDescriptionsMap.put(
"isValidInDomain", "True, if this classification to objects in this domain");
classificationFieldDescriptionsMap.put(
"created", "The creation timestamp of the classification in the system");
classificationFieldDescriptionsMap.put(
"modified", "The timestamp of the last modification date");
classificationFieldDescriptionsMap.put("name", "The name of the classification");
classificationFieldDescriptionsMap.put("description", "The description of the classification");
classificationFieldDescriptionsMap.put("priority", "The priority of the classification");
classificationFieldDescriptionsMap.put(
"serviceLevel",
"The service level of the classification. This is stated according to ISO 8601");
classificationFieldDescriptionsMap.put(
"applicationEntryPoint",
"The logical name of the entry point, the task list application "
+ "should redirect to work on a task of this classification");
classificationFieldDescriptionsMap.put("custom1", "A custom property with name \"1\"");
classificationFieldDescriptionsMap.put("custom2", "A custom property with name \"2\"");
classificationFieldDescriptionsMap.put("custom3", "A custom property with name \"3\"");
classificationFieldDescriptionsMap.put("custom4", "A custom property with name \"4\"");
classificationFieldDescriptionsMap.put("custom5", "A custom property with name \"5\"");
classificationFieldDescriptionsMap.put("custom6", "A custom property with name \"6\"");
classificationFieldDescriptionsMap.put("custom7", "A custom property with name \"7\"");
classificationFieldDescriptionsMap.put("custom8", "A custom property with name \"8\"");
classificationFieldDescriptionsMap.put(
"_links.getAllClassifications.href", "Link to all classifications");
classificationFieldDescriptionsMap.put("_links.getAllClassifications.templated", "");
allClassificationsFieldDescriptors =
new FieldDescriptor[] {
subsectionWithPath("classifications")
.description("An Array of <<classification-subset, Classification-Subsets>>"),
fieldWithPath("_links.self.href").ignored(),
fieldWithPath("page").ignored(),
fieldWithPath("page.size").ignored(),
fieldWithPath("page.totalElements").ignored(),
fieldWithPath("page.totalPages").ignored(),
fieldWithPath("page.number").ignored()
};
classificationFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("classificationId")
.description(classificationFieldDescriptionsMap.get("classificationId")),
fieldWithPath("key").description(classificationFieldDescriptionsMap.get("key")),
fieldWithPath("parentId").description(classificationFieldDescriptionsMap.get("parentId")),
fieldWithPath("parentKey")
.description(classificationFieldDescriptionsMap.get("parentKey")),
fieldWithPath("category").description(classificationFieldDescriptionsMap.get("category")),
fieldWithPath("type").description(classificationFieldDescriptionsMap.get("type")),
fieldWithPath("domain").description(classificationFieldDescriptionsMap.get("domain")),
fieldWithPath("isValidInDomain")
.description(classificationFieldDescriptionsMap.get("isValidInDomain")),
fieldWithPath("created").description(classificationFieldDescriptionsMap.get("created")),
fieldWithPath("modified").description(classificationFieldDescriptionsMap.get("modified")),
fieldWithPath("name").description(classificationFieldDescriptionsMap.get("name")),
fieldWithPath("description")
.description(classificationFieldDescriptionsMap.get("description")),
fieldWithPath("priority").description(classificationFieldDescriptionsMap.get("priority")),
fieldWithPath("serviceLevel")
.description(classificationFieldDescriptionsMap.get("serviceLevel")),
fieldWithPath("applicationEntryPoint")
.description(classificationFieldDescriptionsMap.get("applicationEntryPoint")),
fieldWithPath("custom1").description(classificationFieldDescriptionsMap.get("custom1")),
fieldWithPath("custom2").description(classificationFieldDescriptionsMap.get("custom2")),
fieldWithPath("custom3").description(classificationFieldDescriptionsMap.get("custom3")),
fieldWithPath("custom4").description(classificationFieldDescriptionsMap.get("custom4")),
fieldWithPath("custom5").description(classificationFieldDescriptionsMap.get("custom5")),
fieldWithPath("custom6").description(classificationFieldDescriptionsMap.get("custom6")),
fieldWithPath("custom7").description(classificationFieldDescriptionsMap.get("custom7")),
fieldWithPath("custom8").description(classificationFieldDescriptionsMap.get("custom8")),
fieldWithPath("_links.self.href").ignored()
};
classificationSubsetFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("classificationId")
.description(classificationFieldDescriptionsMap.get("classificationId")),
fieldWithPath("key").description(classificationFieldDescriptionsMap.get("key")),
fieldWithPath("category").description(classificationFieldDescriptionsMap.get("category")),
fieldWithPath("type").description(classificationFieldDescriptionsMap.get("type")),
fieldWithPath("domain").description(classificationFieldDescriptionsMap.get("domain")),
fieldWithPath("isValidInDomain").ignored(),
fieldWithPath("created").ignored(),
fieldWithPath("modified").ignored(),
fieldWithPath("name").description(classificationFieldDescriptionsMap.get("name")),
fieldWithPath("parentId").description(classificationFieldDescriptionsMap.get("parentId")),
fieldWithPath("parentKey")
.description(classificationFieldDescriptionsMap.get("parentKey")),
fieldWithPath("description").ignored(),
fieldWithPath("priority").description(classificationFieldDescriptionsMap.get("priority")),
fieldWithPath("serviceLevel")
.description(classificationFieldDescriptionsMap.get("serviceLevel")),
fieldWithPath("applicationEntryPoint").ignored(),
fieldWithPath("custom1").description(classificationFieldDescriptionsMap.get("custom1")),
fieldWithPath("custom2").description(classificationFieldDescriptionsMap.get("custom2")),
fieldWithPath("custom3").description(classificationFieldDescriptionsMap.get("custom3")),
fieldWithPath("custom4").description(classificationFieldDescriptionsMap.get("custom4")),
fieldWithPath("custom5").description(classificationFieldDescriptionsMap.get("custom5")),
fieldWithPath("custom6").description(classificationFieldDescriptionsMap.get("custom6")),
fieldWithPath("custom7").description(classificationFieldDescriptionsMap.get("custom7")),
fieldWithPath("custom8").description(classificationFieldDescriptionsMap.get("custom8")),
fieldWithPath("_links.self.href").ignored()
};
createClassificationFieldDescriptors =
new FieldDescriptor[] {
fieldWithPath("category")
.type("String")
.description(
"The category of the classification (MANUAL, EXTERNAL, AUTOMATIC, PROCESS)")
.optional(),
fieldWithPath("domain")
.description("The domain for which this classification is specified"),
fieldWithPath("key")
.description(
"The key of the classification. This is typically an externally "
+ "known code or abbreviation of the classification"),
fieldWithPath("name")
.type("String")
.description("The name of the classification")
.optional(),
fieldWithPath("type")
.type("String")
.description("The type of classification (TASK, DOCUMENT)")
.optional(),
fieldWithPath("parentId")
.type("String")
.description(classificationFieldDescriptionsMap.get("parentId"))
.optional(),
fieldWithPath("parentKey")
.type("String")
.description(classificationFieldDescriptionsMap.get("parentKey"))
.optional(),
fieldWithPath("isValidInDomain")
.type("Boolean")
.description(classificationFieldDescriptionsMap.get("isValidInDomain"))
.optional(),
fieldWithPath("created")
.type("String")
.description(classificationFieldDescriptionsMap.get("created"))
.optional(),
fieldWithPath("modified")
.type("String")
.description(classificationFieldDescriptionsMap.get("modified"))
.optional(),
fieldWithPath("description")
.type("String")
.description(classificationFieldDescriptionsMap.get("description"))
.optional(),
fieldWithPath("priority")
.type("Number")
.description(classificationFieldDescriptionsMap.get("priority"))
.optional(),
fieldWithPath("serviceLevel")
.type("String")
.description(classificationFieldDescriptionsMap.get("serviceLevel"))
.optional(),
fieldWithPath("applicationEntryPoint")
.type("String")
.description(classificationFieldDescriptionsMap.get("applicationEntryPoint"))
.optional(),
fieldWithPath("custom1")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom1"))
.optional(),
fieldWithPath("custom2")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom2"))
.optional(),
fieldWithPath("custom3")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom3"))
.optional(),
fieldWithPath("custom4")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom4"))
.optional(),
fieldWithPath("custom5")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom5"))
.optional(),
fieldWithPath("custom6")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom6"))
.optional(),
fieldWithPath("custom7")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom7"))
.optional(),
fieldWithPath("custom8")
.type("String")
.description(classificationFieldDescriptionsMap.get("custom8"))
.optional()
};
}
@Test
void getAllClassificationsDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS) + "?domain=DOMAIN_B")
.accept("application/hal+json")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"GetAllClassificationsDocTest",
responseFields(allClassificationsFieldDescriptors)));
}
@Test
void getSpecificClassificationDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"GetSpecificClassificationDocTest",
responseFields(classificationFieldDescriptors)));
}
@Test
void classificationSubsetDocTest() throws Exception {
this.mockMvc
.perform(
RestDocumentationRequestBuilders.get(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"ClassificationSubset", responseFields(classificationSubsetFieldDescriptors)));
}
@Test
void createAndDeleteClassificationDocTest() throws Exception {
MvcResult result =
this.mockMvc
.perform(
RestDocumentationRequestBuilders.post(restHelper.toUrl(Mapping.URL_CLASSIFICATIONS))
.contentType("application/hal+json")
.content("{\"key\":\"Key0815casdgdgh\", \"domain\":\"DOMAIN_B\"}")
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isCreated())
.andDo(
MockMvcRestDocumentation.document(
"CreateClassificationDocTest",
requestFields(createClassificationFieldDescriptors),
responseFields(classificationFieldDescriptors)))
.andReturn();
String content = result.getResponse().getContentAsString();
String newId = content.substring(content.indexOf("CLI:"), content.indexOf("CLI:") + 40);
this.mockMvc
.perform(
RestDocumentationRequestBuilders.delete(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS_ID, newId))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x"))
.andExpect(MockMvcResultMatchers.status().isNoContent())
.andDo(MockMvcRestDocumentation.document("DeleteClassificationDocTest"));
}
@Test
void updateClassificationDocTest() throws Exception {
URL url =
new URL(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"));
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x");
assertEquals(200, con.getResponseCode());
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream(), UTF_8));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
}
in.close();
con.disconnect();
String originalTask = content.toString();
String modifiedTask = originalTask;
this.mockMvc
.perform(
RestDocumentationRequestBuilders.put(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000009"))
.header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x")
.contentType("application/json")
.content(modifiedTask))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(
MockMvcRestDocumentation.document(
"UpdateClassificationDocTest",
requestFields(classificationFieldDescriptors),
responseFields(classificationFieldDescriptors)));
}
}

View File

@ -1,91 +1,93 @@
package pro.taskana.rest;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.AccessIdResource;
@TaskanaSpringBootTest
class AccessIdControllerIntTest {
private static RestTemplate template;
@Autowired RestHelper restHelper;
@BeforeAll
static void init() {
template = RestHelper.getRestTemplate();
}
@Test
void testQueryGroupsByDn() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID)
+ "?search-for=cn=developersgroup,ou=groups,o=taskanatest",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class));
assertThat(response.getBody().size()).isEqualTo(1);
}
@Test
void testQueryGroupsByCn() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=developer",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class));
assertThat(response.getBody().size()).isEqualTo(1);
}
@Test
void testGetMatches() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=ali",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(AccessIdListResource.class));
List<AccessIdResource> body = response.getBody();
assertThat(body).isNotNull();
assertThat(body.size()).isEqualTo(3);
assertThat(body)
.extracting(AccessIdResource::getName)
.containsExactlyInAnyOrder("Tralisch, Thea", "Bert, Ali", "Mente, Ali");
}
@Test
void testBadRequestWhenSearchForIsTooShort() {
try {
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=al",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class));
} catch (HttpClientErrorException e) {
assertThat(HttpStatus.BAD_REQUEST).isEqualTo(e.getStatusCode());
assertThat(e.getResponseBodyAsString()).containsSequence("Minimum searchFor length =");
}
}
static class AccessIdListResource extends ArrayList<AccessIdResource> {
private static final long serialVersionUID = 1L;
}
}
package pro.taskana.rest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
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.AccessIdResource;
@TaskanaSpringBootTest
class AccessIdControllerIntTest {
private static RestTemplate template;
@Autowired RestHelper restHelper;
@BeforeAll
static void init() {
template = RestHelper.getRestTemplate();
}
@Test
void testQueryGroupsByDn() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID)
+ "?search-for=cn=developersgroup,ou=groups,o=taskanatest",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class));
assertThat(response.getBody()).hasSize(1);
}
@Test
void testQueryGroupsByCn() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=developer",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class));
assertThat(response.getBody()).hasSize(1);
}
@Test
void testGetMatches() {
ResponseEntity<List<AccessIdResource>> response =
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=ali",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(AccessIdListResource.class));
List<AccessIdResource> body = response.getBody();
assertThat(body).isNotNull();
assertThat(body).hasSize(3);
assertThat(body)
.extracting(AccessIdResource::getName)
.containsExactlyInAnyOrder("Tralisch, Thea", "Bert, Ali", "Mente, Ali");
}
@Test
void testBadRequestWhenSearchForIsTooShort() {
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=al",
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(List.class)))
.isInstanceOf(HttpClientErrorException.class)
.hasMessageContaining("Minimum searchFor length =")
.extracting(ex -> ((HttpClientErrorException)ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);
}
static class AccessIdListResource extends ArrayList<AccessIdResource> {
private static final long serialVersionUID = 1L;
}
}

View File

@ -1,294 +1,295 @@
package pro.taskana.rest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
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 testGetClassification() {
ResponseEntity<ClassificationResource> response =
template.exchange(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000002"),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
}
@Test
void testGetAllClassifications() {
ResponseEntity<ClassificationSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationSummaryListResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
}
@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));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getContent().size()).isEqualTo(13);
}
@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));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_SELF).getHref())
.endsWith("/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc");
assertThat(response.getBody().getContent().size()).isEqualTo(17);
assertThat(response.getBody().getContent().iterator().next().key).isEqualTo("A12");
}
@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));
assertThat(response.getBody().getContent().size()).isEqualTo(5);
assertThat(response.getBody().getContent().iterator().next().key).isEqualTo("L1050");
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_SELF).getHref())
.endsWith(
"/api/v1/classifications?"
+ "domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5");
assertThat(response.getBody().getLink(Link.REL_FIRST)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_LAST)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_NEXT)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_PREVIOUS)).isNotNull();
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
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));
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<ClassificationSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationSummaryListResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
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;
}
}
assertThat(foundClassificationCreated).isTrue();
}
@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\"}";
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.POST,
new HttpEntity<>(newClassification, restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.hasFieldOrPropertyWithValue("statusCode", HttpStatus.BAD_REQUEST);
}
@Test
@DirtiesContext
void testCreateClassificationWithClassificationIdReturnsError400() {
String newClassification =
"{\"classificationId\":\"someId\",\"category\":\"MANUAL\","
+ "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\","
+ "\"name\":\"new classification\",\"type\":\"TASK\"}";
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.POST,
new HttpEntity<>(newClassification, restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.extracting(ex -> ((HttpClientErrorException)ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);
}
@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));
assertThat(response.getBody().name).isEqualTo("Zustimmungserklärung");
}
@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));
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"),
HttpMethod.GET,
request,
ParameterizedTypeReference.forType(ClassificationSummaryResource.class)))
.isInstanceOf(HttpClientErrorException.class);
}
}
package pro.taskana.rest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
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 testGetClassification() {
ResponseEntity<ClassificationResource> response =
template.exchange(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:100000000000000000000000000000000002"),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
}
@Test
void testGetAllClassifications() {
ResponseEntity<ClassificationSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationSummaryListResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
}
@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));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getContent()).hasSize(13);
}
@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));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_SELF).getHref())
.endsWith("/api/v1/classifications?domain=DOMAIN_A&sort-by=key&order=asc");
assertThat(response.getBody().getContent()).hasSize(17);
assertThat(response.getBody().getContent().iterator().next().key).isEqualTo("A12");
}
@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));
assertThat(response.getBody().getContent()).hasSize(5);
assertThat(response.getBody().getContent().iterator().next().key).isEqualTo("L1050");
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_SELF).getHref())
.endsWith(
"/api/v1/classifications?"
+ "domain=DOMAIN_A&sort-by=key&order=asc&page=2&page-size=5");
assertThat(response.getBody().getLink(Link.REL_FIRST)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_LAST)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_NEXT)).isNotNull();
assertThat(response.getBody().getLink(Link.REL_PREVIOUS)).isNotNull();
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
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));
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
}
@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));
assertThat(responseEntity).isNotNull();
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.CREATED);
ResponseEntity<ClassificationSummaryListResource> response =
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.GET,
restHelper.defaultRequest(),
ParameterizedTypeReference.forType(ClassificationSummaryListResource.class));
assertThat(response.getBody().getLink(Link.REL_SELF)).isNotNull();
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;
}
}
assertThat(foundClassificationCreated).isTrue();
}
@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\"}";
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.POST,
new HttpEntity<>(newClassification, restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.extracting(ex -> ((HttpClientErrorException)ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);;
}
@Test
@DirtiesContext
void testCreateClassificationWithClassificationIdReturnsError400() {
String newClassification =
"{\"classificationId\":\"someId\",\"category\":\"MANUAL\","
+ "\"domain\":\"DOMAIN_A\",\"key\":\"NEW_CLASS\","
+ "\"name\":\"new classification\",\"type\":\"TASK\"}";
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(Mapping.URL_CLASSIFICATIONS),
HttpMethod.POST,
new HttpEntity<>(newClassification, restHelper.getHeaders()),
ParameterizedTypeReference.forType(ClassificationResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.extracting(ex -> ((HttpClientErrorException)ex).getStatusCode())
.isEqualTo(HttpStatus.BAD_REQUEST);
}
@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));
assertThat(response.getBody().name).isEqualTo("Zustimmungserklärung");
}
@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));
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(
Mapping.URL_CLASSIFICATIONS_ID, "CLI:200000000000000000000000000000000004"),
HttpMethod.GET,
request,
ParameterizedTypeReference.forType(ClassificationSummaryResource.class)))
.isInstanceOf(HttpClientErrorException.class);
}
}

View File

@ -1,72 +1,72 @@
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();
}
}
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

@ -113,14 +113,13 @@ class WorkbasketControllerIntTest {
workbasketResource.setOwner("Joerg");
workbasketResource.setModified(String.valueOf(Instant.now()));
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
HttpMethod.PUT,
new HttpEntity<>(
mapper.writeValueAsString(workbasketResource), restHelper.getHeaders()),
ParameterizedTypeReference.forType(WorkbasketResource.class)))
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
HttpMethod.PUT,
new HttpEntity<>(
mapper.writeValueAsString(workbasketResource), restHelper.getHeaders()),
ParameterizedTypeReference.forType(WorkbasketResource.class)))
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
.isEqualTo(HttpStatus.CONFLICT);
}
@ -130,13 +129,12 @@ class WorkbasketControllerIntTest {
String workbasketId = "WBI:100004857400039500000999999999999999";
assertThatThrownBy(
() ->
template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(WorkbasketResource.class)))
assertThatThrownBy(() ->
template.exchange(
restHelper.toUrl(Mapping.URL_WORKBASKET_ID, workbasketId),
HttpMethod.GET,
new HttpEntity<String>(restHelper.getHeaders()),
ParameterizedTypeReference.forType(WorkbasketResource.class)))
.isInstanceOf(HttpClientErrorException.class)
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
.isEqualTo(HttpStatus.NOT_FOUND);

View File

@ -1,138 +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.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);
}
}
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);
}
}

View File

@ -36,6 +36,7 @@ taskana.ldap.maxNumberOfReturnedAccessIds=50
taskana.jobscheduler.async.cron=0 0 * * * *
####### cache static resources properties
spring.resources.cache.cachecontrol.cache-private=true
spring.main.allow-bean-definition-overriding=true
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.internal-proxies=.*
server.use-forward-headers=true