diff --git a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java index 0b8fde33..1bbef9a0 100644 --- a/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java +++ b/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDao.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ import java.sql.Types; import java.util.ArrayList; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -58,6 +59,7 @@ import org.springframework.util.StringUtils; * @author Gunnar Hillert * @author David Turanski * @author Ilayaperumal Gopinathan + * @author Michael Minella */ public class JdbcTaskExecutionDao implements TaskExecutionDao { @@ -161,6 +163,21 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { private DataFieldMaxValueIncrementer taskIncrementer; + private static final Set validSortColumns = new HashSet<>(10); + + static { + validSortColumns.add("TASK_EXECUTION_ID"); + validSortColumns.add("START_TIME"); + validSortColumns.add("END_TIME"); + validSortColumns.add("TASK_NAME"); + validSortColumns.add("EXIT_CODE"); + validSortColumns.add("EXIT_MESSAGE"); + validSortColumns.add("ERROR_MESSAGE"); + validSortColumns.add("LAST_UPDATED"); + validSortColumns.add("EXTERNAL_EXECUTION_ID"); + validSortColumns.add("PARENT_EXECUTION_ID"); + } + /** * Initializes the JdbcTaskExecutionDao. * @param dataSource used by the dao to execute queries and update the tables. @@ -511,8 +528,13 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { if (sort != null) { for (Sort.Order sortOrder : sort) { - sortOrderMap.put(sortOrder.getProperty(), + if (validSortColumns.contains(sortOrder.getProperty().toUpperCase())) { + sortOrderMap.put(sortOrder.getProperty(), sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING); + } + else { + throw new IllegalArgumentException(String.format("Invalid sort option selected: %s", sortOrder.getProperty())); + } } } diff --git a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDaoTests.java b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDaoTests.java index e18535f0..c8438496 100644 --- a/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDaoTests.java +++ b/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/repository/dao/JdbcTaskExecutionDaoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,12 +46,14 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Executes unit tests on JdbcTaskExecutionDao. * * @author Glenn Renfro * @author Gunnar Hillert + * @author Michael Minella */ @ExtendWith(SpringExtension.class) @ContextConfiguration( @@ -209,6 +211,31 @@ public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases { expectedTaskExecution.getExecutionId())); } + @Test + @DirtiesContext + public void testFindRunningTaskExecutions() { + initializeRepositoryNotInOrderWithMultipleTaskExecutions(); + assertThat(this.dao.findRunningTaskExecutions("FOO1", PageRequest.of(1, Integer.MAX_VALUE, Sort.by("START_TIME"))).getTotalElements()) + .isEqualTo(4); + } + + @Test + @DirtiesContext + public void testFindRunningTaskExecutionsIllegalSort() { + initializeRepositoryNotInOrderWithMultipleTaskExecutions(); + assertThatThrownBy(() -> this.dao.findRunningTaskExecutions("FOO1", PageRequest.of(1, Integer.MAX_VALUE, Sort.by("ILLEGAL_SORT"))).getTotalElements()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Invalid sort option selected: ILLEGAL_SORT"); + } + + @Test + @DirtiesContext + public void testFindRunningTaskExecutionsSortWithDifferentCase() { + initializeRepositoryNotInOrderWithMultipleTaskExecutions(); + assertThat(this.dao.findRunningTaskExecutions("FOO1", PageRequest.of(1, Integer.MAX_VALUE, Sort.by("StArT_TiMe"))).getTotalElements()) + .isEqualTo(4); + } + private TaskExecution initializeTaskExecutionWithExternalExecutionId() { TaskExecution expectedTaskExecution = TestVerifierUtils .createSampleTaskExecutionNoArg();