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..26836fb1 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,14 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao { if (sort != null) { for (Sort.Order sortOrder : sort) { - sortOrderMap.put(sortOrder.getProperty(), - sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING); + 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 d65c4ac9..db4ac20a 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. @@ -45,12 +45,14 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Executes unit tests on JdbcTaskExecutionDao. * * @author Glenn Renfro * @author Gunnar Hillert + * @author Michael Minella */ @RunWith(SpringRunner.class) @ContextConfiguration( @@ -205,6 +207,39 @@ 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();