use of co.cask.cdap.api.workflow.ScheduleProgramInfo in project cdap by caskdata.
the class ScheduleSpecificationCodecTest method testStreamSizeSchedule.
@Test
public void testStreamSizeSchedule() throws Exception {
Schedule dataSchedule = Schedules.builder("foo").setDescription("bar").createDataSchedule(Schedules.Source.STREAM, "stream", 10);
ScheduleProgramInfo programInfo = new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, "testWorkflow");
ImmutableMap<String, String> properties = ImmutableMap.of("a", "b", "c", "d");
ScheduleSpecification specification = new ScheduleSpecification(dataSchedule, programInfo, properties);
String jsonStr = GSON.toJson(specification);
ScheduleSpecification deserialized = GSON.fromJson(jsonStr, ScheduleSpecification.class);
Assert.assertEquals(specification, deserialized);
}
use of co.cask.cdap.api.workflow.ScheduleProgramInfo in project cdap by caskdata.
the class ProgramLifecycleHttpHandlerTest method testAddSchedule.
private void testAddSchedule(String scheduleName) throws Exception {
TimeSchedule timeSchedule = (TimeSchedule) Schedules.builder(scheduleName).setDescription("Something").createTimeSchedule("0 * * * ?");
TimeTrigger timeTrigger = new TimeTrigger("0 * * * ?");
ScheduleProgramInfo programInfo = new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, AppWithSchedule.WORKFLOW_NAME);
ImmutableMap<String, String> properties = ImmutableMap.of("a", "b", "c", "d");
ScheduleSpecification specification = new ScheduleSpecification(timeSchedule, programInfo, properties);
ScheduleDetail detail = new ScheduleDetail(scheduleName, specification.getSchedule().getDescription(), specification.getProgram(), specification.getProperties(), new TimeTrigger(timeSchedule.getCronEntry()), Collections.<Constraint>emptyList(), Schedulers.JOB_QUEUE_TIMEOUT_MILLIS);
// 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", detail);
Assert.assertEquals(HttpResponseStatus.BAD_REQUEST.getCode(), response.getStatusLine().getStatusCode());
// adding a schedule to a non-existing app should fail
response = addSchedule(TEST_NAMESPACE1, "nonExistingApp", null, scheduleName, specification);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.getCode(), response.getStatusLine().getStatusCode());
// adding a schedule to invalid type of program type should fail
ScheduleDetail invalidScheduleDetail = new ScheduleDetail(scheduleName, "Something", new ScheduleProgramInfo(SchedulableProgramType.MAPREDUCE, AppWithSchedule.MAPREDUCE), properties, timeTrigger, ImmutableList.<Constraint>of(), TimeUnit.MINUTES.toMillis(1));
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, invalidScheduleDetail);
Assert.assertEquals(HttpResponseStatus.BAD_REQUEST.getCode(), response.getStatusLine().getStatusCode());
// adding a schedule for a program that does not exist
ScheduleSpecification nonExistingSpecification = new ScheduleSpecification(timeSchedule, new ScheduleProgramInfo(SchedulableProgramType.MAPREDUCE, "nope"), properties);
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, nonExistingSpecification);
Assert.assertEquals(HttpResponseStatus.NOT_FOUND.getCode(), response.getStatusLine().getStatusCode());
// adding a schedule with invalid schedule details should fail
TimeSchedule invalidTimeSchedule = (TimeSchedule) Schedules.builder("invalidTimeSchedule").setDescription("Something").createTimeSchedule(// invalid cron expression
"0 * ? * ?");
// Intentionally keep this ScheduleSpecification to test backward compatibility
ScheduleSpecification invalidSpecification = new ScheduleSpecification(invalidTimeSchedule, programInfo, properties);
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, "invalidTimeSchedule", invalidSpecification);
Assert.assertEquals(HttpResponseStatus.BAD_REQUEST.getCode(), response.getStatusLine().getStatusCode());
// test adding a schedule
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, null, scheduleName, specification);
Assert.assertEquals(HttpResponseStatus.OK.getCode(), response.getStatusLine().getStatusCode());
List<ScheduleDetail> schedules = getSchedules(TEST_NAMESPACE1, AppWithSchedule.NAME, AppWithSchedule.WORKFLOW_NAME);
Assert.assertEquals(2, schedules.size());
Assert.assertEquals(detail, schedules.get(1));
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, detail);
Assert.assertEquals(HttpResponseStatus.CONFLICT.getCode(), response.getStatusLine().getStatusCode());
// although we should be able to add schedule to a different version of the app
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, scheduleName, detail);
Assert.assertEquals(HttpResponseStatus.OK.getCode(), response.getStatusLine().getStatusCode());
// 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(detail, 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(null, "Something 2", programInfo, properties, new TimeTrigger("0 * * * ?"), Collections.<Constraint>emptyList(), TimeUnit.HOURS.toMillis(6));
response = addSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, "schedule-100", detail2);
Assert.assertEquals(HttpResponseStatus.OK.getCode(), response.getStatusLine().getStatusCode());
ScheduleDetail detail100 = getSchedule(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, "schedule-100");
Assert.assertEquals("schedule-100", detail100.getName());
Assert.assertEquals(detail2.getTimeoutMillis(), detail100.getTimeoutMillis());
// test backward-compatible api
ScheduleSpecification spec100 = getScheduleSpec(TEST_NAMESPACE1, AppWithSchedule.NAME, VERSION2, "schedule-100");
Assert.assertEquals(detail100.toScheduleSpec(), spec100);
}
use of co.cask.cdap.api.workflow.ScheduleProgramInfo in project cdap by caskdata.
the class ProtoTriggerCodecTest method testObjectContainingTrigger.
@Test
public void testObjectContainingTrigger() {
ScheduleDetail sched1 = new ScheduleDetail("sched1", "one partition schedule", new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, "ww"), ImmutableMap.of("prop3", "abc"), new ProtoTrigger.PartitionTrigger(new DatasetId("test1", "pdfs1"), 1), ImmutableList.<Constraint>of(), null);
ScheduleDetail sched2 = new ScheduleDetail("schedone", "one time schedule", new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, "wf112"), ImmutableMap.of("prop", "all"), new ProtoTrigger.TimeTrigger("* * * 1 1"), ImmutableList.<Constraint>of(), null);
Assert.assertEquals(sched1, GSON.fromJson(GSON.toJson(sched1), ScheduleDetail.class));
Assert.assertEquals(sched2, GSON.fromJson(GSON.toJson(sched2), ScheduleDetail.class));
}
use of co.cask.cdap.api.workflow.ScheduleProgramInfo in project cdap by caskdata.
the class DistributedWorkflowProgramRunner method findDriverResources.
/**
* Returns the {@link Resources} requirement for the workflow runnable deduced by Spark
* or MapReduce driver resources requirement.
*/
private Resources findDriverResources(Map<String, SparkSpecification> sparkSpecs, Map<String, MapReduceSpecification> mrSpecs, WorkflowSpecification spec) {
// Find the resource requirements from the workflow with 768MB as minimum.
// It is the largest memory and cores from all Spark and MapReduce programs inside the workflow
Resources resources = new Resources(768);
for (WorkflowNode node : spec.getNodeIdMap().values()) {
if (WorkflowNodeType.ACTION == node.getType()) {
ScheduleProgramInfo programInfo = ((WorkflowActionNode) node).getProgram();
SchedulableProgramType programType = programInfo.getProgramType();
if (programType == SchedulableProgramType.SPARK || programType == SchedulableProgramType.MAPREDUCE) {
// The program spec shouldn't be null, otherwise the Workflow is not valid
Resources driverResources;
if (programType == SchedulableProgramType.SPARK) {
driverResources = sparkSpecs.get(programInfo.getProgramName()).getClientResources();
} else {
driverResources = mrSpecs.get(programInfo.getProgramName()).getDriverResources();
}
if (driverResources != null) {
resources = max(resources, driverResources);
}
}
}
}
return resources;
}
use of co.cask.cdap.api.workflow.ScheduleProgramInfo in project cdap by caskdata.
the class WorkflowNodeCreator method createWorkflowActionNode.
static WorkflowNode createWorkflowActionNode(String programName, SchedulableProgramType programType) {
switch(programType) {
case MAPREDUCE:
Preconditions.checkNotNull(programName, "MapReduce name is null.");
Preconditions.checkArgument(!programName.isEmpty(), "MapReduce name is empty.");
break;
case SPARK:
Preconditions.checkNotNull(programName, "Spark name is null.");
Preconditions.checkArgument(!programName.isEmpty(), "Spark name is empty.");
break;
case CUSTOM_ACTION:
//no-op
break;
default:
break;
}
return new WorkflowActionNode(programName, new ScheduleProgramInfo(programType, programName));
}
Aggregations