use of io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testSchedules.
@Test
public void testSchedules() throws Exception {
// deploy an app with schedule
Id.Artifact artifactId = Id.Artifact.from(Id.Namespace.fromEntityId(TEST_NAMESPACE_META1.getNamespaceId()), AppWithSchedule.NAME, VERSION1);
addAppArtifact(artifactId, AppWithSchedule.class);
AppRequest<? extends Config> request = new AppRequest<>(new ArtifactSummary(artifactId.getName(), artifactId.getVersion().getVersion()));
ApplicationId defaultAppId = TEST_NAMESPACE_META1.getNamespaceId().app(AppWithSchedule.NAME);
Assert.assertEquals(200, deploy(defaultAppId, request).getResponseCode());
// deploy another version of the app
ApplicationId appV2Id = TEST_NAMESPACE_META1.getNamespaceId().app(AppWithSchedule.NAME, VERSION2);
Assert.assertEquals(200, deploy(appV2Id, request).getResponseCode());
// list schedules for default version app, for the workflow and for the app, they should be same
List<ScheduleDetail> schedules = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(1, schedules.size());
ScheduleDetail schedule = schedules.get(0);
Assert.assertEquals(SchedulableProgramType.WORKFLOW, schedule.getProgram().getProgramType());
Assert.assertEquals(AppWithSchedule.WORKFLOW_NAME, schedule.getProgram().getProgramName());
Assert.assertEquals(new TimeTrigger("0/15 * * * * ?"), schedule.getTrigger());
// there should be two schedules now
List<ScheduleDetail> schedulesForApp = listSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, null);
Assert.assertEquals(1, schedulesForApp.size());
Assert.assertEquals(schedules, schedulesForApp);
List<ScheduleDetail> schedules2 = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(1, schedules2.size());
ScheduleDetail schedule2 = schedules2.get(0);
Assert.assertEquals(SchedulableProgramType.WORKFLOW, schedule2.getProgram().getProgramType());
Assert.assertEquals(AppWithSchedule.WORKFLOW_NAME, schedule2.getProgram().getProgramName());
Assert.assertEquals(new TimeTrigger("0/15 * * * * ?"), schedule2.getTrigger());
String newSchedule = "newTimeSchedule";
testAddSchedule(newSchedule);
testDeleteSchedule(appV2Id, newSchedule);
testUpdateSchedule(appV2Id);
testReEnableSchedule("reEnabledSchedule");
}
use of io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testUpdateSchedule.
private void testUpdateSchedule(ApplicationId appV2Id) throws Exception {
ScheduleDetail updateDetail = new ScheduleDetail(AppWithSchedule.SCHEDULE, "updatedDescription", null, ImmutableMap.of("twoKey", "twoValue", "someKey", "newValue"), new TimeTrigger("0 4 * * *"), ImmutableList.of(new ConcurrencyConstraint(5)), null);
// trying to update schedule for a non-existing app should fail
HttpResponse response = updateSchedule(TEST_NAMESPACE1, "nonExistingApp", null, AppWithSchedule.SCHEDULE, updateDetail);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.code(), response.getResponseCode());
// trying to update a non-existing schedule should fail
ScheduleDetail nonExistingSchedule = new ScheduleDetail("NonExistingSchedule", "updatedDescription", null, ImmutableMap.of("twoKey", "twoValue"), new TimeTrigger("0 4 * * *"), ImmutableList.of(new ConcurrencyConstraint(5)), null);
response = updateSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, "NonExistingSchedule", nonExistingSchedule);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.code(), response.getResponseCode());
// should be able to update an existing schedule with a valid new time schedule
response = updateSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, AppWithSchedule.SCHEDULE, updateDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
// verify that the schedule information for updated
ScheduleDetail schedule = getSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, AppWithSchedule.SCHEDULE);
Assert.assertEquals("updatedDescription", schedule.getDescription());
Assert.assertEquals("0 4 * * *", ((TimeTrigger) schedule.getTrigger()).getCronExpression());
Assert.assertEquals(new ProtoConstraint.ConcurrencyConstraint(5), schedule.getConstraints().get(0));
// the properties should have been replaced
Assert.assertEquals(2, schedule.getProperties().size());
Assert.assertEquals("newValue", schedule.getProperties().get("someKey"));
Assert.assertEquals("twoValue", schedule.getProperties().get("twoKey"));
// the old property should not exist
Assert.assertNull(schedule.getProperties().get("oneKey"));
// the above update should not have affected the schedule for the other version of the app
schedule = getSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, appV2Id.getVersion(), AppWithSchedule.SCHEDULE);
Assert.assertNotEquals("updatedDescription", schedule.getDescription());
Assert.assertEquals("0/15 * * * * ?", ((TimeTrigger) schedule.getTrigger()).getCronExpression());
// try to update the schedule again but this time with property as null. It should retain the old properties
ScheduleDetail scheduleDetail = new ScheduleDetail(AppWithSchedule.SCHEDULE, "updatedDescription", null, null, new ProtoTrigger.TimeTrigger("0 4 * * *"), null, null);
response = updateSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, AppWithSchedule.SCHEDULE, scheduleDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
schedule = getSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, AppWithSchedule.SCHEDULE);
Assert.assertEquals(2, schedule.getProperties().size());
Assert.assertEquals("newValue", schedule.getProperties().get("someKey"));
Assert.assertEquals("twoValue", schedule.getProperties().get("twoKey"));
Assert.assertEquals(new ProtoConstraint.ConcurrencyConstraint(5), schedule.getConstraints().get(0));
}
use of io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testAddSchedule.
private void testAddSchedule(String scheduleName) throws Exception {
String partitionScheduleName = scheduleName + "Partition";
String orScheduleName = scheduleName + "Or";
ProtoTrigger.TimeTrigger protoTime = new ProtoTrigger.TimeTrigger("0 * * * ?");
ProtoTrigger.PartitionTrigger protoPartition = new ProtoTrigger.PartitionTrigger(NamespaceId.DEFAULT.dataset("data"), 5);
ProtoTrigger.OrTrigger protoOr = ProtoTrigger.or(protoTime, protoPartition);
String description = "Something";
ScheduleProgramInfo programInfo = new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, AppWithSchedule.WORKFLOW_NAME);
ImmutableMap<String, String> properties = ImmutableMap.of("a", "b", "c", "d");
TimeTrigger timeTrigger = new TimeTrigger("0 * * * ?");
ScheduleDetail timeDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, scheduleName, description, programInfo, properties, timeTrigger, Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
PartitionTrigger partitionTrigger = new PartitionTrigger(protoPartition.getDataset(), protoPartition.getNumPartitions());
ScheduleDetail expectedPartitionDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, partitionScheduleName, description, programInfo, properties, partitionTrigger, Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
ScheduleDetail requestPartitionDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, partitionScheduleName, description, programInfo, properties, protoPartition, Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
ScheduleDetail expectedOrDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, orScheduleName, description, programInfo, properties, new OrTrigger(timeTrigger, partitionTrigger), Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
ScheduleDetail requestOrDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, orScheduleName, description, programInfo, properties, protoOr, Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
// trying to add the schedule with different name in path param than schedule spec should fail
HttpResponse response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, "differentName", timeDetail);
Assert.assertEquals(HttpResponseStatus.BAD_REQUEST.code(), response.getResponseCode());
// adding a schedule to a non-existing app should fail
response = addSchedule(TEST_NAMESPACE1, "nonExistingApp", null, scheduleName, timeDetail);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.code(), response.getResponseCode());
// adding a schedule to invalid type of program type should fail
ScheduleDetail invalidScheduleDetail = new ScheduleDetail(scheduleName, "Something", new ScheduleProgramInfo(SchedulableProgramType.MAPREDUCE, AppWithSchedule.MAPREDUCE), properties, protoTime, Collections.emptyList(), TimeUnit.MINUTES.toMillis(1));
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, invalidScheduleDetail);
Assert.assertEquals(HttpResponseStatus.BAD_REQUEST.code(), response.getResponseCode());
// adding a schedule for a program that does not exist
ScheduleDetail nonExistingDetail = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, ApplicationId.DEFAULT_VERSION, scheduleName, description, new ScheduleProgramInfo(SchedulableProgramType.MAPREDUCE, "nope"), properties, timeTrigger, Collections.emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS, null, null);
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, nonExistingDetail);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.code(), response.getResponseCode());
// test adding a schedule
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, timeDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, partitionScheduleName, requestPartitionDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, orScheduleName, requestOrDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
List<ScheduleDetail> schedules = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(4, schedules.size());
Assert.assertEquals(timeDetail, schedules.get(1));
Assert.assertEquals(expectedOrDetail, schedules.get(2));
Assert.assertEquals(expectedPartitionDetail, schedules.get(3));
List<ScheduleDetail> schedulesForApp = listSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, null);
Assert.assertEquals(schedules, schedulesForApp);
// trying to add ScheduleDetail of the same schedule again should fail with AlreadyExistsException
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, timeDetail);
Assert.assertEquals(HttpResponseStatus.CONFLICT.code(), response.getResponseCode());
// although we should be able to add schedule to a different version of the app
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, scheduleName, timeDetail);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
// this should not have affected the schedules of the default version
List<ScheduleDetail> scheds = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(schedules, scheds);
// there should be two schedules now for version 2
List<ScheduleDetail> schedules2 = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(2, schedules2.size());
Assert.assertEquals(timeDetail, schedules2.get(1));
List<ScheduleDetail> schedulesForApp2 = listSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2);
Assert.assertEquals(schedules2, schedulesForApp2);
// Add a schedule with no schedule name in spec
ScheduleDetail detail2 = new ScheduleDetail(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, null, "Something 2", programInfo, properties, new TimeTrigger("0 * * * ?"), Collections.emptyList(), TimeUnit.HOURS.toMillis(6), null, null);
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, "schedule-100", detail2);
Assert.assertEquals(HttpResponseStatus.OK.code(), response.getResponseCode());
ScheduleDetail detail100 = getSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, "schedule-100");
Assert.assertEquals("schedule-100", detail100.getName());
Assert.assertEquals(detail2.getTimeoutMillis(), detail100.getTimeoutMillis());
}
use of io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger in project cdap by caskdata.
the class ScheduledRunTimeTest method testGetNextRun.
@Test
public void testGetNextRun() throws Exception {
ApplicationId appId = NamespaceId.DEFAULT.app("test");
deploy(appId, new AppRequest<>(new ArtifactSummary(ARTIFACT_ID.getName(), ARTIFACT_ID.getVersion().getVersion())));
String scheduleName = "schedule1";
// Add a schedule. Use a constraint to make it not going to be executed
ProgramId programId = appId.workflow(WorkflowApp.FunWorkflow.NAME);
Constraint constraint = new DelayConstraint(1, TimeUnit.HOURS);
ScheduleProgramInfo scheduleProgramInfo = new ScheduleProgramInfo(programId.getType().getSchedulableType(), programId.getProgram());
addSchedule(appId.getNamespace(), appId.getApplication(), appId.getVersion(), scheduleName, new ScheduleDetail(scheduleName, null, scheduleProgramInfo, null, new TimeTrigger("0 0 * * * "), Collections.singletonList(constraint), null));
long now = System.currentTimeMillis();
HttpResponse response = enableSchedule(programId.getNamespace(), programId.getApplication(), programId.getVersion(), scheduleName);
Assert.assertEquals(200, response.getResponseCode());
// Get the next run time
List<ScheduledRuntime> scheduledRunTimes = getScheduledRunTimes(programId, true);
Assert.assertEquals(1, scheduledRunTimes.size());
long nextTime = scheduledRunTimes.get(0).getTime();
Assert.assertTrue(nextTime >= now);
}
use of io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger in project cdap by caskdata.
the class ScheduledRunTimeTest method testBatchGetNextRun.
@Test
public void testBatchGetNextRun() throws Exception {
// deploys 5 apps and create schedules for each of them
long now = System.currentTimeMillis();
List<ProgramId> programIds = new ArrayList<>();
// Use a constraint to make it not going to be executed
Constraint constraint = new DelayConstraint(1, TimeUnit.HOURS);
for (int i = 0; i < 5; i++) {
ApplicationId appId = NamespaceId.DEFAULT.app("test" + i);
deploy(appId, new AppRequest<>(new ArtifactSummary(ARTIFACT_ID.getName(), ARTIFACT_ID.getVersion().getVersion())));
String scheduleName = "schedule" + i;
// Add a schedule
ProgramId programId = appId.workflow(WorkflowApp.FunWorkflow.NAME);
programIds.add(programId);
ScheduleProgramInfo scheduleProgramInfo = new ScheduleProgramInfo(programId.getType().getSchedulableType(), programId.getProgram());
addSchedule(appId.getNamespace(), appId.getApplication(), appId.getVersion(), scheduleName, new ScheduleDetail(scheduleName, null, scheduleProgramInfo, null, new TimeTrigger("0 0 * * * "), Collections.singletonList(constraint), null));
HttpResponse response = enableSchedule(programId.getNamespace(), programId.getApplication(), programId.getVersion(), scheduleName);
Assert.assertEquals(200, response.getResponseCode());
}
// Add programs that the app or the program doesn't exist
programIds.add(NamespaceId.DEFAULT.app("not-exist").workflow("not-exist"));
programIds.add(NamespaceId.DEFAULT.app("test1").workflow("not-exist"));
List<BatchProgramSchedule> schedules = getScheduledRunTimes(NamespaceId.DEFAULT.getNamespace(), programIds, true);
Assert.assertEquals(programIds.size(), schedules.size());
// For the first 5 programs, they should have a next run
for (int i = 0; i < 5; i++) {
BatchProgramSchedule schedule = schedules.get(i);
Assert.assertEquals(200, schedule.getStatusCode());
List<ScheduledRuntime> nextRuns = schedule.getSchedules();
Assert.assertNotNull(nextRuns);
Assert.assertEquals(1, nextRuns.size());
long nextTime = nextRuns.get(0).getTime();
Assert.assertTrue(nextTime >= now);
}
// The last two should be a not found
Assert.assertEquals(404, schedules.get(5).getStatusCode());
Assert.assertEquals(404, schedules.get(6).getStatusCode());
}
Aggregations