Search in sources :

Example 11 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by caskdata.

the class TimeTrigger method getTriggerInfos.

@Override
public List<TriggerInfo> getTriggerInfos(TriggerInfoContext context) {
    for (Notification notification : context.getNotifications()) {
        if (!isSatisfied(context.getSchedule(), notification)) {
            continue;
        }
        Long logicalStartTime = getLogicalStartTime(notification);
        if (logicalStartTime == null) {
            LOG.warn("The notification '{}' in the job of schedule '{}' does not contain logical start time", notification, context.getSchedule());
            continue;
        }
        TriggerInfo triggerInfo = new DefaultTimeTriggerInfo(getCronExpression(), logicalStartTime);
        return Collections.singletonList(triggerInfo);
    }
    return Collections.emptyList();
}
Also used : TriggerInfo(io.cdap.cdap.api.schedule.TriggerInfo) Notification(io.cdap.cdap.proto.Notification)

Example 12 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by caskdata.

the class CoreSchedulerServiceTest method testRunScheduledJobs.

@Test
@Category(XSlowTests.class)
public void testRunScheduledJobs() throws Exception {
    CConfiguration cConf = getInjector().getInstance(CConfiguration.class);
    dataEventTopic = NamespaceId.SYSTEM.topic(cConf.get(Constants.Dataset.DATA_EVENT_TOPIC));
    // Deploy the app with version
    Id.Artifact appArtifactId = Id.Artifact.from(Id.Namespace.DEFAULT, "appwithschedules", VERSION1);
    addAppArtifact(appArtifactId, AppWithFrequentScheduledWorkflows.class);
    AppRequest<? extends Config> appRequest = new AppRequest<>(new ArtifactSummary(appArtifactId.getName(), appArtifactId.getVersion().getVersion()));
    deploy(APP_ID, appRequest);
    // Resume the schedule because schedules are initialized as paused
    enableSchedule(AppWithFrequentScheduledWorkflows.TEN_SECOND_SCHEDULE_1);
    enableSchedule(AppWithFrequentScheduledWorkflows.TEN_SECOND_SCHEDULE_2);
    enableSchedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_1);
    enableSchedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_2);
    for (int i = 0; i < 5; i++) {
        testNewPartition(i + 1);
    }
    // Enable COMPOSITE_SCHEDULE before publishing events to DATASET_NAME2
    enableSchedule(AppWithFrequentScheduledWorkflows.COMPOSITE_SCHEDULE);
    // disable the two partition schedules, send them notifications (but they should not trigger)
    int runs1 = getRuns(WORKFLOW_1, ProgramRunStatus.ALL);
    int runs2 = getRuns(WORKFLOW_2, ProgramRunStatus.ALL);
    disableSchedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_1);
    // ensure schedule 2 is disabled after schedule 1
    Thread.sleep(BUFFER);
    long disableBeforeTime = System.currentTimeMillis();
    disableSchedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_2);
    long disableAfterTime = System.currentTimeMillis() + 1;
    publishNotification(dataEventTopic, NamespaceId.DEFAULT, AppWithFrequentScheduledWorkflows.DATASET_NAME1);
    long minPublishTime = System.currentTimeMillis();
    publishNotification(dataEventTopic, NamespaceId.DEFAULT, AppWithFrequentScheduledWorkflows.DATASET_NAME2);
    // This would make sure the subscriber has processed the data event
    waitUntilProcessed(dataEventTopic, minPublishTime);
    // Both workflows must run at least once.
    // If the testNewPartition() loop took longer than expected, it may be more (quartz fired multiple times)
    Tasks.waitFor(true, () -> getRuns(SCHEDULED_WORKFLOW_1, ProgramRunStatus.COMPLETED) > 0 && getRuns(SCHEDULED_WORKFLOW_2, ProgramRunStatus.COMPLETED) > 0, 10, TimeUnit.SECONDS);
    // There shouldn't be any partition trigger in the job queue
    Assert.assertFalse(Iterables.any(getAllJobs(), job -> job.getSchedule().getTrigger() instanceof ProtoTrigger.PartitionTrigger));
    ProgramId compositeWorkflow = APP_ID.workflow(AppWithFrequentScheduledWorkflows.COMPOSITE_WORKFLOW);
    // Workflow scheduled with the composite trigger has never been started
    Assert.assertEquals(0, getRuns(compositeWorkflow, ProgramRunStatus.ALL));
    // Publish two more new partition notifications to satisfy the partition trigger in the composite trigger,
    // and thus the whole composite trigger will be satisfied
    publishNotification(dataEventTopic, NamespaceId.DEFAULT, AppWithFrequentScheduledWorkflows.DATASET_NAME2);
    minPublishTime = System.currentTimeMillis();
    publishNotification(dataEventTopic, NamespaceId.DEFAULT, AppWithFrequentScheduledWorkflows.DATASET_NAME2);
    // This would make sure the subscriber has processed the data event
    waitUntilProcessed(dataEventTopic, minPublishTime);
    // Wait for 1 run to complete for compositeWorkflow
    waitForCompleteRuns(1, compositeWorkflow);
    for (RunRecordDetail runRecordMeta : store.getRuns(SCHEDULED_WORKFLOW_1, ProgramRunStatus.ALL, 0, Long.MAX_VALUE, Integer.MAX_VALUE).values()) {
        Map<String, String> sysArgs = runRecordMeta.getSystemArgs();
        Assert.assertNotNull(sysArgs);
        TriggeringScheduleInfo scheduleInfo = GSON.fromJson(sysArgs.get(ProgramOptionConstants.TRIGGERING_SCHEDULE_INFO), TriggeringScheduleInfo.class);
        Assert.assertEquals(AppWithFrequentScheduledWorkflows.TEN_SECOND_SCHEDULE_1, scheduleInfo.getName());
        List<TriggerInfo> triggerInfos = scheduleInfo.getTriggerInfos();
        // Only one notification is enough to satisfy Time Trigger
        Assert.assertEquals(1, triggerInfos.size());
        Assert.assertEquals(TriggerInfo.Type.TIME, triggerInfos.get(0).getType());
    }
    // Also verify that the two partition schedules did not trigger
    Assert.assertEquals(runs1, getRuns(WORKFLOW_1, ProgramRunStatus.ALL));
    Assert.assertEquals(runs2, getRuns(WORKFLOW_2, ProgramRunStatus.ALL));
    // enable partition schedule 2 and test reEnableSchedules
    scheduler.reEnableSchedules(NamespaceId.DEFAULT, disableBeforeTime, disableAfterTime);
    Assert.assertEquals(ProgramScheduleStatus.SCHEDULED, scheduler.getScheduleStatus(APP_ID.schedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_2)));
    Assert.assertEquals(ProgramScheduleStatus.SUSPENDED, scheduler.getScheduleStatus(APP_ID.schedule(AppWithFrequentScheduledWorkflows.DATASET_PARTITION_SCHEDULE_1)));
    testScheduleUpdate("disable");
    testScheduleUpdate("update");
    testScheduleUpdate("delete");
}
Also used : RunRecordDetail(io.cdap.cdap.internal.app.store.RunRecordDetail) WorkflowTokenDetailCodec(io.cdap.cdap.proto.codec.WorkflowTokenDetailCodec) TypeToken(com.google.gson.reflect.TypeToken) StoreRequestBuilder(io.cdap.cdap.messaging.client.StoreRequestBuilder) TransactionRunners(io.cdap.cdap.spi.data.transaction.TransactionRunners) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) Notification(io.cdap.cdap.proto.Notification) HttpResponse(io.cdap.common.http.HttpResponse) XSlowTests(io.cdap.cdap.test.XSlowTests) Bytes(io.cdap.cdap.api.common.Bytes) AlreadyExistsException(io.cdap.cdap.common.AlreadyExistsException) GsonBuilder(com.google.gson.GsonBuilder) ProgramScheduleStatus(io.cdap.cdap.internal.app.runtime.schedule.ProgramScheduleStatus) AppWithFrequentScheduledWorkflows(io.cdap.cdap.AppWithFrequentScheduledWorkflows) ProgramStateWriter(io.cdap.cdap.app.runtime.ProgramStateWriter) SimpleProgramOptions(io.cdap.cdap.internal.app.runtime.SimpleProgramOptions) DatasetId(io.cdap.cdap.proto.id.DatasetId) ScheduleId(io.cdap.cdap.proto.id.ScheduleId) Gson(com.google.gson.Gson) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) WorkflowTokenDetail(io.cdap.cdap.proto.WorkflowTokenDetail) Map(java.util.Map) AppWithMultipleSchedules(io.cdap.cdap.AppWithMultipleSchedules) ClassRule(org.junit.ClassRule) Tasks(io.cdap.cdap.common.utils.Tasks) AfterClass(org.junit.AfterClass) ImmutableMap(com.google.common.collect.ImmutableMap) ApplicationSpecification(io.cdap.cdap.api.app.ApplicationSpecification) MessagingService(io.cdap.cdap.messaging.MessagingService) PartitionKey(io.cdap.cdap.api.dataset.lib.PartitionKey) Constraint(io.cdap.cdap.internal.schedule.constraint.Constraint) ProgramRunStatus(io.cdap.cdap.proto.ProgramRunStatus) Category(org.junit.experimental.categories.Category) Id(io.cdap.cdap.common.id.Id) MessageId(io.cdap.cdap.messaging.data.MessageId) List(java.util.List) TransactionRunner(io.cdap.cdap.spi.data.transaction.TransactionRunner) Constants(io.cdap.cdap.common.conf.Constants) ProfileId(io.cdap.cdap.proto.id.ProfileId) ProgramOptionConstants(io.cdap.cdap.internal.app.runtime.ProgramOptionConstants) TimeTrigger(io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) NotFoundException(io.cdap.cdap.common.NotFoundException) RunRecord(io.cdap.cdap.proto.RunRecord) TriggerInfo(io.cdap.cdap.api.schedule.TriggerInfo) ProfileConflictException(io.cdap.cdap.common.ProfileConflictException) Iterables(com.google.common.collect.Iterables) WorkflowId(io.cdap.cdap.proto.id.WorkflowId) BeforeClass(org.junit.BeforeClass) MessagingProgramStateWriter(io.cdap.cdap.internal.app.program.MessagingProgramStateWriter) AppFabricTestBase(io.cdap.cdap.internal.app.services.http.AppFabricTestBase) JobQueueTable(io.cdap.cdap.internal.app.runtime.schedule.queue.JobQueueTable) TopicId(io.cdap.cdap.proto.id.TopicId) ProgramType(io.cdap.cdap.proto.ProgramType) WorkflowToken(io.cdap.cdap.api.workflow.WorkflowToken) PartitionTrigger(io.cdap.cdap.internal.app.runtime.schedule.trigger.PartitionTrigger) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) ProgramOptions(io.cdap.cdap.app.runtime.ProgramOptions) TriggeringScheduleInfoAdapter(io.cdap.cdap.internal.app.runtime.schedule.TriggeringScheduleInfoAdapter) Profile(io.cdap.cdap.proto.profile.Profile) SystemArguments(io.cdap.cdap.internal.app.runtime.SystemArguments) TriggeringScheduleInfo(io.cdap.cdap.api.schedule.TriggeringScheduleInfo) Nullable(javax.annotation.Nullable) ProtoTrigger(io.cdap.cdap.proto.ProtoTrigger) DefaultApplicationSpecification(io.cdap.cdap.internal.app.DefaultApplicationSpecification) RunIds(io.cdap.cdap.common.app.RunIds) ProgramId(io.cdap.cdap.proto.id.ProgramId) Config(io.cdap.cdap.api.Config) ProgramDescriptor(io.cdap.cdap.app.program.ProgramDescriptor) Test(org.junit.Test) ConflictException(io.cdap.cdap.common.ConflictException) ProjectInfo(io.cdap.cdap.common.utils.ProjectInfo) CloseableIterator(io.cdap.cdap.api.dataset.lib.CloseableIterator) Service(com.google.common.util.concurrent.Service) ProgramSchedule(io.cdap.cdap.internal.app.runtime.schedule.ProgramSchedule) Store(io.cdap.cdap.app.store.Store) Job(io.cdap.cdap.internal.app.runtime.schedule.queue.Job) TimeUnit(java.util.concurrent.TimeUnit) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) AppRequest(io.cdap.cdap.proto.artifact.AppRequest) Assert(org.junit.Assert) Collections(java.util.Collections) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) TemporaryFolder(org.junit.rules.TemporaryFolder) BasicArguments(io.cdap.cdap.internal.app.runtime.BasicArguments) RunRecordDetail(io.cdap.cdap.internal.app.store.RunRecordDetail) TriggerInfo(io.cdap.cdap.api.schedule.TriggerInfo) TriggeringScheduleInfo(io.cdap.cdap.api.schedule.TriggeringScheduleInfo) ProgramId(io.cdap.cdap.proto.id.ProgramId) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) Constraint(io.cdap.cdap.internal.schedule.constraint.Constraint) AppRequest(io.cdap.cdap.proto.artifact.AppRequest) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) NamespaceId(io.cdap.cdap.proto.id.NamespaceId) DatasetId(io.cdap.cdap.proto.id.DatasetId) ScheduleId(io.cdap.cdap.proto.id.ScheduleId) Id(io.cdap.cdap.common.id.Id) MessageId(io.cdap.cdap.messaging.data.MessageId) ProfileId(io.cdap.cdap.proto.id.ProfileId) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) WorkflowId(io.cdap.cdap.proto.id.WorkflowId) TopicId(io.cdap.cdap.proto.id.TopicId) ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ProgramId(io.cdap.cdap.proto.id.ProgramId) ArtifactId(io.cdap.cdap.api.artifact.ArtifactId) PartitionTrigger(io.cdap.cdap.internal.app.runtime.schedule.trigger.PartitionTrigger) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 13 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by caskdata.

the class ScheduleTaskPublisher method publishNotification.

/**
 * Publish notification for the triggered schedule
 *  @param notificationType type of the notification
 * @param scheduleId       {@link ScheduleId} of the triggered schedule
 * @param systemOverrides Arguments that would be supplied as system runtime arguments for the program.
 * @param userOverrides Arguments to add to the user runtime arguments for the program.
 */
public void publishNotification(Notification.Type notificationType, ScheduleId scheduleId, Map<String, String> systemOverrides, Map<String, String> userOverrides) throws Exception {
    Map<String, String> properties = new HashMap<>();
    properties.put(ProgramOptionConstants.SCHEDULE_ID, GSON.toJson(scheduleId));
    properties.put(ProgramOptionConstants.SYSTEM_OVERRIDES, GSON.toJson(systemOverrides));
    properties.put(ProgramOptionConstants.USER_OVERRIDES, GSON.toJson(userOverrides));
    Notification notification = new Notification(notificationType, properties);
    messagingService.publish(StoreRequestBuilder.of(topicId).addPayload(GSON.toJson(notification)).build());
}
Also used : HashMap(java.util.HashMap) Notification(io.cdap.cdap.proto.Notification)

Example 14 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by caskdata.

the class RuntimeProgramStatusSubscriberService method processMessages.

@Override
protected void processMessages(StructuredTableContext context, Iterator<ImmutablePair<String, Notification>> messages) throws Exception {
    while (messages.hasNext()) {
        ImmutablePair<String, Notification> pair = messages.next();
        Notification notification = pair.getSecond();
        if (notification.getNotificationType() != Notification.Type.PROGRAM_STATUS) {
            continue;
        }
        processNotification(pair.getFirst().getBytes(StandardCharsets.UTF_8), notification, getAppMetadataStore(context));
    }
}
Also used : Notification(io.cdap.cdap.proto.Notification)

Example 15 with Notification

use of io.cdap.cdap.proto.Notification in project cdap by caskdata.

the class ProgramStatusTrigger method getTriggerSatisfiedResult.

/**
 * Helper method to return a result from the given supplier if the trigger is satisfied with the given notifications,
 * or return the default result if the trigger is not satisfied.
 *
 * @param notifications notifications used to determine whether the trigger is satisfied
 * @param defaultResult the default result to return if the trigger is not satisfied
 * @param function the function to get result from if the trigger is satisfied
 * @param <T> type of the result to be returned
 * @return a result of type T
 */
private <T> T getTriggerSatisfiedResult(List<Notification> notifications, T defaultResult, Function<ProgramRunInfo, T> function) {
    for (Notification notification : notifications) {
        if (!Notification.Type.PROGRAM_STATUS.equals(notification.getNotificationType())) {
            continue;
        }
        String programRunIdString = notification.getProperties().get(ProgramOptionConstants.PROGRAM_RUN_ID);
        String programRunStatusString = notification.getProperties().get(ProgramOptionConstants.PROGRAM_STATUS);
        // Ignore notifications which specify an invalid programRunId or programStatus
        if (programRunIdString == null || programRunStatusString == null) {
            continue;
        }
        ProgramStatus programStatus;
        try {
            programStatus = ProgramRunStatus.toProgramStatus(ProgramRunStatus.valueOf(programRunStatusString));
        } catch (IllegalArgumentException e) {
            // Return silently, this happens for statuses that are not meant to be scheduled
            continue;
        }
        ProgramRunId programRunId = GSON.fromJson(programRunIdString, ProgramRunId.class);
        ProgramId triggeringProgramId = programRunId.getParent();
        if (this.programId.equals(triggeringProgramId) && programStatuses.contains(programStatus)) {
            return function.apply(new ProgramRunInfo(programStatus, programRunId));
        }
    }
    return defaultResult;
}
Also used : ProgramRunId(io.cdap.cdap.proto.id.ProgramRunId) ProgramId(io.cdap.cdap.proto.id.ProgramId) Notification(io.cdap.cdap.proto.Notification) ProgramStatus(io.cdap.cdap.api.ProgramStatus)

Aggregations

Notification (io.cdap.cdap.proto.Notification)52 ProgramRunId (io.cdap.cdap.proto.id.ProgramRunId)14 IOException (java.io.IOException)14 Map (java.util.Map)14 Test (org.junit.Test)14 MessagingService (io.cdap.cdap.messaging.MessagingService)12 ProgramRunStatus (io.cdap.cdap.proto.ProgramRunStatus)12 Gson (com.google.gson.Gson)10 ProgramStateWriter (io.cdap.cdap.app.runtime.ProgramStateWriter)10 RunIds (io.cdap.cdap.common.app.RunIds)10 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)10 Constants (io.cdap.cdap.common.conf.Constants)10 MessagingProgramStateWriter (io.cdap.cdap.internal.app.program.MessagingProgramStateWriter)10 ProgramOptionConstants (io.cdap.cdap.internal.app.runtime.ProgramOptionConstants)10 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)10 ArrayList (java.util.ArrayList)10 Collections (java.util.Collections)10 List (java.util.List)10 TimeUnit (java.util.concurrent.TimeUnit)10 Nullable (javax.annotation.Nullable)10