Skip to content

Commit b3be82a

Browse files
committed
App version should be set on Schedules using the version.app property
Currently it uses the version.taskdefinition property. Add Test to check if user can set app version on schedule Add documentation on how to set version for tasks This includes both Scheduling and Task Launch Update code based on code review comments
1 parent e109a97 commit b3be82a

File tree

3 files changed

+85
-11
lines changed

3 files changed

+85
-11
lines changed

spring-cloud-dataflow-docs/src/main/asciidoc/tasks.adoc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,30 @@ NOTE: Properties configured by using this mechanism have lower precedence than t
288288
They are overridden if a property with the same key is specified at task launch time (for example, `app.trigger.prop2`
289289
overrides the common property).
290290

291+
==== Launching tasks with a specific application version
292+
293+
When launching a task you can specify the specific version of the application.
294+
If no version is specified Spring Cloud Data Flow will use the default version of the application.
295+
To specify a version of the application to be used at launch time use the deployer property `version.<app-name>`.
296+
For example:
297+
298+
====
299+
[source,bash,subs=attributes]
300+
----
301+
task launch my-task --properties 'version.timestamp=3.0.0'
302+
----
303+
====
304+
305+
Similarly, when scheduling a task you will use the same format of `version.<app-name>`. For example:
306+
307+
====
308+
[source,bash,subs=attributes]
309+
----
310+
task schedule create --name my-schedule --definitionName my-task --expression '*/1 * * * *' --properties 'version.timestamp=3.0.0'
311+
----
312+
====
313+
314+
291315
[[spring-cloud-dataflow-task-limit-concurrent-executions]]
292316
=== Limit the number concurrent task launches
293317

spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/service/impl/DefaultSchedulerService.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,12 @@ public void schedule(
224224

225225
String taskAppName = taskDefinition.getRegisteredAppName();
226226
String taskLabel = taskDefinition.getAppDefinition().getName();
227-
if(!StringUtils.hasText(taskLabel)) {
228-
taskLabel = taskAppName;
229-
}
230227
String version = taskDeploymentProperties.get("version." + taskLabel);
228+
if (version == null) {
229+
version = taskDeploymentProperties.get("version." + taskAppName);
230+
}
231+
232+
231233
SchemaVersionTarget schemaVersionTarget = aggregateExecutionSupport.findSchemaVersionTarget(taskAppName, version, taskDefinition);
232234
Assert.notNull(schemaVersionTarget, "schemaVersionTarget not found for " + taskAppName);
233235
TaskParser taskParser = new TaskParser(taskDefinition.getName(), taskDefinition.getDslText(), true, true);

spring-cloud-dataflow-server-core/src/test/java/org/springframework/cloud/dataflow/server/service/impl/DefaultSchedulerServiceTests.java

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.mockito.ArgumentCaptor;
3232
import org.mockito.Mockito;
3333

34+
import org.mockito.stubbing.Answer;
3435
import org.springframework.beans.factory.annotation.Autowired;
3536
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
3637
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
@@ -60,25 +61,27 @@
6061
import org.springframework.cloud.dataflow.server.service.SchedulerServiceProperties;
6162
import org.springframework.cloud.dataflow.server.service.TaskExecutionInfoService;
6263
import org.springframework.cloud.deployer.resource.docker.DockerResource;
63-
import org.springframework.cloud.deployer.spi.core.AppDefinition;
6464
import org.springframework.cloud.deployer.spi.scheduler.CreateScheduleException;
6565
import org.springframework.cloud.deployer.spi.scheduler.ScheduleInfo;
6666
import org.springframework.cloud.deployer.spi.scheduler.ScheduleRequest;
6767
import org.springframework.cloud.deployer.spi.scheduler.Scheduler;
6868
import org.springframework.cloud.deployer.spi.task.TaskLauncher;
6969
import org.springframework.cloud.task.listener.TaskException;
7070
import org.springframework.core.env.PropertyResolver;
71+
import org.springframework.core.io.FileSystemResource;
7172
import org.springframework.core.io.Resource;
7273
import org.springframework.core.io.ResourceLoader;
7374
import org.springframework.data.domain.Page;
7475
import org.springframework.data.domain.PageRequest;
7576
import org.springframework.test.annotation.DirtiesContext;
7677

7778
import static org.assertj.core.api.Assertions.assertThat;
79+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
7880
import static org.junit.jupiter.api.Assertions.assertEquals;
7981
import static org.junit.jupiter.api.Assertions.assertThrows;
8082
import static org.mockito.ArgumentMatchers.any;
8183
import static org.mockito.ArgumentMatchers.anyString;
84+
import static org.mockito.Mockito.doAnswer;
8285
import static org.mockito.Mockito.mock;
8386
import static org.mockito.Mockito.verify;
8487
import static org.mockito.Mockito.when;
@@ -105,7 +108,9 @@ public class DefaultSchedulerServiceTests {
105108

106109
private static final String BASE_DEFINITION_NAME = "myTaskDefinition";
107110

108-
private static final String CTR_DEFINITION_NAME= "myCtrDefinition";
111+
private static final String CTR_DEFINITION_NAME = "myCtrDefinition";
112+
113+
private static final String DEMO_APP_NAME = "demoAppName";
109114

110115
@Autowired
111116
private Scheduler simpleTestScheduler;
@@ -431,18 +436,51 @@ public void testScheduleWithoutCommandLineArguments() {
431436
@Test
432437
public void testGetDefaultCTR() {
433438
ScheduleRequest request = getScheduleRequest(new ArrayList<>(), "springcloudtask/composed-task-runner:latest", "1: timestamp && 2: timestamp");
434-
AppDefinition definition = request.getDefinition();
435439
assertEquals("Docker Resource [docker:springcloudtask/composed-task-runner:latest]", request.getResource().toString());
436440
}
441+
@Test
442+
public void testVersionWithResource() {
443+
String validVersionNumber = "3.0.0";
444+
ScheduleRequest request = scheduleRequest(validVersionNumber);
445+
assertThat(request.getResource().toString()).contains("file:src/test/resources/apps/foo-task");
446+
}
447+
448+
@Test
449+
public void testVersionWithResourceInvalidVersion() {
450+
String invalidVersionNumber = "2.0.0";
451+
assertThatIllegalArgumentException()
452+
.isThrownBy(() -> {
453+
scheduleRequest(invalidVersionNumber);
454+
}).withMessage("Unknown task app: demo");
455+
}
456+
457+
private ScheduleRequest scheduleRequest(String appVersionToTest) {
458+
String definition = "demo";
459+
Map<String, String> resourceTestProps = new HashMap<>(testProperties);
460+
resourceTestProps.put("version.demo", appVersionToTest);
461+
AppRegistryService mockAppRegistryService = mock(AppRegistryService.class);
462+
TaskDefinition taskDefinition = new TaskDefinition(BASE_DEFINITION_NAME, definition);
463+
AppRegistration demoRegistration = new AppRegistration();
464+
demoRegistration.setName(DEMO_APP_NAME);
465+
466+
when(mockAppRegistryService.find(taskDefinition.getRegisteredAppName(), ApplicationType.task, "3.0.0"))
467+
.thenReturn(demoRegistration);
468+
return getScheduleRequest(new ArrayList<>(),
469+
"springcloudtask/composed-task-runner:latest",
470+
definition, resourceTestProps, mockAppRegistryService);
471+
}
437472

438473
private List<String> getCommandLineArguments(List<String> commandLineArguments) {
439474
return getScheduleRequest(commandLineArguments,"springcloudtask/timestamp-task:latest", "timestamp").getCommandlineArguments();
440475
}
441476

442477
private ScheduleRequest getScheduleRequest(List<String> commandLineArguments, String resourceToReturn, String definition) {
478+
AppRegistryService mockAppRegistryService = mock(AppRegistryService.class);
479+
return getScheduleRequest(commandLineArguments, resourceToReturn, definition, this.testProperties, mockAppRegistryService);
480+
}
481+
private ScheduleRequest getScheduleRequest(List<String> commandLineArguments, String resourceToReturn, String definition, Map<String, String> testProperties, AppRegistryService appRegistryService) {
443482
Scheduler mockScheduler = mock(SimpleTestScheduler.class);
444483
TaskDefinitionRepository mockTaskDefinitionRepository = mock(TaskDefinitionRepository.class);
445-
AppRegistryService mockAppRegistryService = mock(AppRegistryService.class);
446484

447485
Launcher launcher = new Launcher("default", "defaultType", null, mockScheduler);
448486
List<Launcher> launchers = new ArrayList<>();
@@ -452,7 +490,7 @@ private ScheduleRequest getScheduleRequest(List<String> commandLineArguments, St
452490
mock(CommonApplicationProperties.class),
453491
taskPlatform,
454492
mockTaskDefinitionRepository,
455-
mockAppRegistryService,
493+
appRegistryService,
456494
mock(ResourceLoader.class),
457495
this.taskConfigurationProperties,
458496
mock(DataSourceProperties.class),
@@ -470,10 +508,20 @@ private ScheduleRequest getScheduleRequest(List<String> commandLineArguments, St
470508
TaskDefinition taskDefinition = new TaskDefinition(BASE_DEFINITION_NAME, definition);
471509

472510
when(mockTaskDefinitionRepository.findById(BASE_DEFINITION_NAME)).thenReturn(Optional.of(taskDefinition));
473-
when(mockAppRegistryService.getAppResource(any())).thenReturn(new DockerResource(resourceToReturn));
474-
when(mockAppRegistryService.find(taskDefinition.getRegisteredAppName(), ApplicationType.task))
511+
doAnswer((Answer<Resource>) invocation -> {
512+
AppRegistration appRegistration = invocation.getArgument(0, AppRegistration.class);
513+
String name = appRegistration.getName();
514+
Resource resource = new DockerResource(resourceToReturn);
515+
if(name != null && name.equals(DEMO_APP_NAME)) {
516+
resource = new FileSystemResource("file:src/test/resources/apps/foo-task");
517+
}
518+
return resource;
519+
}).when(appRegistryService).getAppResource(any());
520+
when(appRegistryService.find(taskDefinition.getRegisteredAppName(), ApplicationType.task))
475521
.thenReturn(new AppRegistration());
476-
mockSchedulerService.schedule(BASE_SCHEDULE_NAME, BASE_DEFINITION_NAME, this.testProperties,
522+
523+
524+
mockSchedulerService.schedule(BASE_SCHEDULE_NAME, BASE_DEFINITION_NAME, testProperties,
477525
commandLineArguments, null);
478526

479527
ArgumentCaptor<ScheduleRequest> scheduleRequestArgumentCaptor = ArgumentCaptor.forClass(ScheduleRequest.class);

0 commit comments

Comments
 (0)