diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationServiceImpl.java index fda9984e4..0bd218cb2 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/ClassificationServiceImpl.java @@ -53,6 +53,27 @@ public class ClassificationServiceImpl implements ClassificationService { this.taskMapper = taskMapper; } + private static void validateServiceLevel(String serviceLevel) throws InvalidArgumentException { + try { + Duration.parse(serviceLevel); + + } catch (Exception e) { + throw new InvalidArgumentException("Invalid service level " + serviceLevel + + ". The formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS with days considered to be exactly 24 hours. " + + "For example: \"P2D\" represents a period of \"two days.\" ", + e.getCause()); + } + // check that the duration is based on format PnD, i.e. it must start with a P, end with a D + String serviceLevelLower = serviceLevel.toLowerCase(); + if (!('p' == serviceLevelLower.charAt(0)) + || !('d' == serviceLevelLower.charAt(serviceLevel.length() - 1))) { + + throw new InvalidArgumentException( + "Invalid service level " + serviceLevel + ". Taskana only supports service levels that" + + " contain a number of whole days specified according to the format 'PnD' where n is the number of days"); + } + } + @Override public Classification createClassification(Classification classification) throws ClassificationAlreadyExistException, NotAuthorizedException, @@ -196,7 +217,9 @@ public class ClassificationServiceImpl implements ClassificationService { /** * Fill missing values and validate classification before saving the classification. * - * @param classification + * @param classification the classification which will be verified. + * + * @throws InvalidArgumentException if the given classification has no key. */ private void initDefaultClassificationValues(ClassificationImpl classification) throws InvalidArgumentException { Instant now = Instant.now(); @@ -253,27 +276,6 @@ public class ClassificationServiceImpl implements ClassificationService { } } - private static void validateServiceLevel(String serviceLevel) throws InvalidArgumentException { - try { - Duration.parse(serviceLevel); - - } catch (Exception e) { - throw new InvalidArgumentException("Invalid service level " + serviceLevel - + ". The formats accepted are based on the ISO-8601 duration format PnDTnHnMn.nS with days considered to be exactly 24 hours. " - + "For example: \"P2D\" represents a period of \"two days.\" ", - e.getCause()); - } - // check that the duration is based on format PnD, i.e. it must start with a P, end with a D - String serviceLevelLower = serviceLevel.toLowerCase(); - if (!('p' == serviceLevelLower.charAt(0)) - || !('d' == serviceLevelLower.charAt(serviceLevel.length() - 1))) { - - throw new InvalidArgumentException( - "Invalid service level " + serviceLevel + ". Taskana only supports service levels that" - + " contain a number of whole days specified according to the format 'PnD' where n is the number of days"); - } - } - @Override public Classification getClassification(String id) throws ClassificationNotFoundException { if (id == null) { @@ -343,8 +345,8 @@ public class ClassificationServiceImpl implements ClassificationService { } } catch (Exception ex) { LOGGER.warn( - "Classification-Service throwed Exception while calling mapper and searching for classification. EX={}", - ex); + "Classification-Service threw Exception while calling mapper and searching for classification. EX={}", + ex, ex); } return isExisting; } @@ -433,6 +435,9 @@ public class ClassificationServiceImpl implements ClassificationService { * * @param classificationImpl the classification * @return the old classification + * + * @throws ConcurrencyException if the classification has been modified by some other process. + * @throws ClassificationNotFoundException if the given classification does not exist. */ private Classification getExistingClassificationAndVerifyTimestampHasNotChanged( ClassificationImpl classificationImpl) @@ -472,6 +477,8 @@ public class ClassificationServiceImpl implements ClassificationService { * * @param classificationImpl the new classification * @param oldClassification the old classification + * + * @throws ClassificationNotFoundException if the given classification does not exist. */ private void checkExistenceOfParentClassification(Classification oldClassification, ClassificationImpl classificationImpl) diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java index c4b1772cd..269e7c5fa 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskanaEngineImpl.java @@ -391,7 +391,7 @@ public class TaskanaEngineImpl implements TaskanaEngine { /** * creates the MyBatis transaction factory. * - * @param useManagedTransactions + * @param useManagedTransactions true, if managed transations should be used. Otherwise false. */ private void createTransactionFactory(boolean useManagedTransactions) { if (useManagedTransactions) { diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/DBCleaner.java b/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/DBCleaner.java index 42eea3ccb..deec515f6 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/DBCleaner.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/DBCleaner.java @@ -28,6 +28,7 @@ public class DBCleaner { /** * Clears the db. * + * @param dataSource the datasource * @param dropTables * if true drop tables, else clean tables */ @@ -51,7 +52,7 @@ public class DBCleaner { LOGGER.debug(outWriter.toString()); String errorMsg = errorWriter.toString().trim(); - if (!errorMsg.isEmpty() && errorMsg.indexOf("SQLCODE=-204, SQLSTATE=42704") == -1) { + if (!errorMsg.isEmpty() && !errorMsg.contains("SQLCODE=-204, SQLSTATE=42704")) { LOGGER.error(errorWriter.toString()); } } diff --git a/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/TaskanaEngineConfigurationTest.java b/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/TaskanaEngineConfigurationTest.java index 4cc21b2c2..8548ef3ee 100644 --- a/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/TaskanaEngineConfigurationTest.java +++ b/lib/taskana-core/src/test/java/pro/taskana/impl/configuration/TaskanaEngineConfigurationTest.java @@ -26,21 +26,10 @@ import pro.taskana.configuration.TaskanaEngineConfiguration; */ public class TaskanaEngineConfigurationTest { - private static DataSource dataSource = null; - private static String schemaName = null; private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaEngineConfigurationTest.class); private static final int POOL_TIME_TO_WAIT = 50; - - @Test - public void testCreateTaskanaEngine() throws SQLException { - DataSource ds = getDataSource(); - TaskanaEngineConfiguration taskEngineConfiguration = new TaskanaEngineConfiguration(ds, false, - TaskanaEngineConfigurationTest.getSchemaName()); - - TaskanaEngine te = taskEngineConfiguration.buildTaskanaEngine(); - - Assert.assertNotNull(te); - } + private static DataSource dataSource = null; + private static String schemaName = null; /** * returns the Datasource used for Junit test. If the file {user.home}/taskanaUnitTest.properties is present, the @@ -69,7 +58,7 @@ public class TaskanaEngineConfigurationTest { /** * create Default Datasource for in-memory database. * - * @return + * @return the default datasource. */ private static DataSource createDefaultDataSource() { // JdbcDataSource ds = new JdbcDataSource(); @@ -81,10 +70,10 @@ public class TaskanaEngineConfigurationTest { String jdbcUrl = "jdbc:h2:mem:taskana;IGNORECASE=TRUE;LOCK_MODE=0"; String dbUserName = "sa"; String dbPassword = "sa"; - DataSource ds = new PooledDataSource(Thread.currentThread().getContextClassLoader(), jdbcDriver, + PooledDataSource ds = new PooledDataSource(Thread.currentThread().getContextClassLoader(), jdbcDriver, jdbcUrl, dbUserName, dbPassword); - ((PooledDataSource) ds).setPoolTimeToWait(POOL_TIME_TO_WAIT); - ((PooledDataSource) ds).forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly + ds.setPoolTimeToWait(POOL_TIME_TO_WAIT); + ds.forceCloseAll(); // otherwise the MyBatis pool is not initialized correctly return ds; } @@ -116,11 +105,11 @@ public class TaskanaEngineConfigurationTest { /** * create data source from properties file. * - * @param propertiesFileName - * @return + * @param propertiesFileName the name of the property file + * @return the parsed datasource. */ public static DataSource createDataSourceFromProperties(String propertiesFileName) { - DataSource ds = null; + DataSource ds; try (InputStream input = new FileInputStream(propertiesFileName)) { Properties prop = new Properties(); prop.load(input); @@ -157,10 +146,6 @@ public class TaskanaEngineConfigurationTest { ds = createDefaultDataSource(); } - } catch (FileNotFoundException e) { - LOGGER.warn("createDataSourceFromProperties caught Exception " + e); - LOGGER.warn("Using default Datasource for Test"); - ds = createDefaultDataSource(); } catch (IOException e) { LOGGER.warn("createDataSourceFromProperties caught Exception " + e); LOGGER.warn("Using default Datasource for Test"); @@ -200,4 +185,15 @@ public class TaskanaEngineConfigurationTest { return schemaName; } + @Test + public void testCreateTaskanaEngine() throws SQLException { + DataSource ds = getDataSource(); + TaskanaEngineConfiguration taskEngineConfiguration = new TaskanaEngineConfiguration(ds, false, + TaskanaEngineConfigurationTest.getSchemaName()); + + TaskanaEngine te = taskEngineConfiguration.buildTaskanaEngine(); + + Assert.assertNotNull(te); + } + } diff --git a/qa/checkstyle/checkstyle.xml b/qa/checkstyle/checkstyle.xml index a34f931bb..b8a824ba8 100644 --- a/qa/checkstyle/checkstyle.xml +++ b/qa/checkstyle/checkstyle.xml @@ -1,7 +1,7 @@ + "-//Puppy Crawl//DTD Check Configuration 1.2//EN" + "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> - - - + + + - - - + + + - + - - - + + + - - - - - + + + + + - + - + + - - - + + + - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + - - - - - + + + + + + + + + + + - - - - - - - - - - - + + + + - - - - + + + + + + + - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + - - - - - + + + + + - - - - - + - + + + - - - - - - - + + + diff --git a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/AbstractPagingControllerRestDocumentation.java b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/AbstractPagingControllerRestDocumentation.java index da41e56b8..2385a0a1a 100644 --- a/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/AbstractPagingControllerRestDocumentation.java +++ b/rest/taskana-rest-spring-test/src/test/java/pro/taskana/doc/api/AbstractPagingControllerRestDocumentation.java @@ -1,5 +1,17 @@ package pro.taskana.doc.api; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; +import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; +import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; +import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath; +import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields; +import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath; +import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity; + +import java.util.HashMap; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -17,17 +29,8 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import pro.taskana.rest.RestConfiguration; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document; -import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint; -import static org.springframework.restdocs.payload.PayloadDocumentation.*; -import static org.springframework.restdocs.payload.PayloadDocumentation.subsectionWithPath; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest; -import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse; -import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*; -import java.util.HashMap; +import pro.taskana.rest.RestConfiguration; /** * Generate Rest Docu for AbstractPagingController. @@ -36,12 +39,10 @@ import java.util.HashMap; @SpringBootTest(classes = RestConfiguration.class, webEnvironment = WebEnvironment.RANDOM_PORT) public class AbstractPagingControllerRestDocumentation { - @LocalServerPort - int port; - @Rule public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation(); - + @LocalServerPort + int port; @Autowired private WebApplicationContext context; @@ -54,16 +55,16 @@ public class AbstractPagingControllerRestDocumentation { @Before public void setUp() { document("{methodName}", - preprocessRequest(prettyPrint()), - preprocessResponse(prettyPrint())); + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint())); this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context) - .apply(springSecurity()) - .apply(documentationConfiguration(this.restDocumentation) - .operationPreprocessors() - .withResponseDefaults(prettyPrint()) - .withRequestDefaults(prettyPrint())) - .build(); + .apply(springSecurity()) + .apply(documentationConfiguration(this.restDocumentation) + .operationPreprocessors() + .withResponseDefaults(prettyPrint()) + .withRequestDefaults(prettyPrint())) + .build(); pagingFieldDescriptionsMap.put("page", "Contains metainfo if there are multiple pages, else it is null"); pagingFieldDescriptionsMap.put("page.size", "Number of items per page"); @@ -76,30 +77,29 @@ public class AbstractPagingControllerRestDocumentation { pagingFieldDescriptionsMap.put("_links.next.href", "Link to next page"); pagingFieldDescriptors = new FieldDescriptor[] { - - subsectionWithPath("_embedded.classificationSummaryResourceList").ignored(), - fieldWithPath("_links").ignored(), - fieldWithPath("_links.self").ignored(), - fieldWithPath("_links.self.href").ignored(), - fieldWithPath("page").description(pagingFieldDescriptionsMap.get("page")), - fieldWithPath("page.size").description(pagingFieldDescriptionsMap.get("page.size")), - fieldWithPath("page.totalElements").description(pagingFieldDescriptionsMap.get("page.totalElements")), - fieldWithPath("page.totalPages").description(pagingFieldDescriptionsMap.get("page.totalPages")), - fieldWithPath("page.number").description(pagingFieldDescriptionsMap.get("page.number")), - fieldWithPath("_links.first.href").description(pagingFieldDescriptionsMap.get("_links.first.href")), - fieldWithPath("_links.last.href").description(pagingFieldDescriptionsMap.get("_links.last.href")), - fieldWithPath("_links.prev.href").description(pagingFieldDescriptionsMap.get("_links.prev.href")), - fieldWithPath("_links.next.href").description(pagingFieldDescriptionsMap.get("_links.next.href")) + subsectionWithPath("_embedded.classificationSummaryResourceList").ignored(), + fieldWithPath("_links").ignored(), + fieldWithPath("_links.self").ignored(), + fieldWithPath("_links.self.href").ignored(), + fieldWithPath("page").description(pagingFieldDescriptionsMap.get("page")), + fieldWithPath("page.size").description(pagingFieldDescriptionsMap.get("page.size")), + fieldWithPath("page.totalElements").description(pagingFieldDescriptionsMap.get("page.totalElements")), + fieldWithPath("page.totalPages").description(pagingFieldDescriptionsMap.get("page.totalPages")), + fieldWithPath("page.number").description(pagingFieldDescriptionsMap.get("page.number")), + fieldWithPath("_links.first.href").description(pagingFieldDescriptionsMap.get("_links.first.href")), + fieldWithPath("_links.last.href").description(pagingFieldDescriptionsMap.get("_links.last.href")), + fieldWithPath("_links.prev.href").description(pagingFieldDescriptionsMap.get("_links.prev.href")), + fieldWithPath("_links.next.href").description(pagingFieldDescriptionsMap.get("_links.next.href")) }; } @Test public void commonSummaryResourceFieldsDocTest() throws Exception { this.mockMvc.perform(RestDocumentationRequestBuilders - .get("http://127.0.0.1:" + port + "/v1/classifications?page=2&page-size=5") - .header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x")) - .andExpect(MockMvcResultMatchers.status().isOk()) - .andDo(MockMvcRestDocumentation.document("CommonSummaryResourceFields", + .get("http://127.0.0.1:" + port + "/v1/classifications?page=2&page-size=5") + .header("Authorization", "Basic dGVhbWxlYWRfMTp0ZWFtbGVhZF8x")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andDo(MockMvcRestDocumentation.document("CommonSummaryResourceFields", responseFields(pagingFieldDescriptors))); } } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AbstractPagingController.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AbstractPagingController.java index 9d92dd11e..dc47ec5cd 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AbstractPagingController.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/AbstractPagingController.java @@ -76,9 +76,7 @@ public abstract class AbstractPagingController { return pageMetadata; } - /** - * This method is deprecated please remove it after updating taskana-simple-history reference to it. - */ + // This method is deprecated please remove it after updating taskana-simple-history reference to it. @Deprecated protected PageMetadata initPageMetadata(String pagesizeParam, String pageParam, long totalElements) throws InvalidArgumentException { diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/RestConfiguration.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/RestConfiguration.java index 117ddbe7d..37a2da4c1 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/RestConfiguration.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/rest/RestConfiguration.java @@ -7,7 +7,10 @@ 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.*; +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;