All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.cdap.cdap.internal.app.runtime.schedule.trigger.ProgramStatusTrigger Maven / Gradle / Ivy
/*
* Copyright © 2017 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.cdap.cdap.internal.app.runtime.schedule.trigger;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import io.cdap.cdap.api.ProgramStatus;
import io.cdap.cdap.api.app.ProgramType;
import io.cdap.cdap.api.schedule.TriggerInfo;
import io.cdap.cdap.common.app.RunIds;
import io.cdap.cdap.internal.app.runtime.ProgramOptionConstants;
import io.cdap.cdap.internal.app.runtime.schedule.ProgramSchedule;
import io.cdap.cdap.internal.app.runtime.schedule.store.Schedulers;
import io.cdap.cdap.proto.Notification;
import io.cdap.cdap.proto.ProgramRunStatus;
import io.cdap.cdap.proto.ProtoTrigger;
import io.cdap.cdap.proto.id.ProgramId;
import io.cdap.cdap.proto.id.ProgramRunId;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A Trigger that schedules a ProgramSchedule, when a certain status of a program has been achieved.
*/
public class ProgramStatusTrigger extends ProtoTrigger.ProgramStatusTrigger implements SatisfiableTrigger {
private static final Gson GSON = new Gson();
public ProgramStatusTrigger(ProgramId programId, Set programStatuses) {
super(programId, programStatuses);
}
@VisibleForTesting
public ProgramStatusTrigger(ProgramId programId, ProgramStatus... programStatuses) {
super(programId, new HashSet<>(Arrays.asList(programStatuses)));
}
@Override
public boolean isSatisfied(ProgramSchedule schedule, List notifications) {
return getTriggerSatisfiedResult(notifications, false, new Function() {
@Override
public Boolean apply(ProgramRunInfo input) {
return true;
}
});
}
@Override
public Set getTriggerKeys() {
return Schedulers.triggerKeysForProgramStatuses(programId, programStatuses);
}
@Override
public List getTriggerInfos(final TriggerInfoContext context) {
Function> function = new Function>() {
@Override
public List apply(ProgramRunInfo runInfo) {
Map runtimeArgs = context.getProgramRuntimeArguments(runInfo.getProgramRunId());
TriggerInfo triggerInfo =
new DefaultProgramStatusTriggerInfo(programId.getNamespace(),
programId.getParent().getApplication(),
ProgramType.valueOf(programId.getType().name()), programId.getProgram(),
RunIds.fromString(runInfo.getProgramRunId().getRun()),
runInfo.getProgramStatus(),
context.getWorkflowToken(runInfo.getProgramRunId()), runtimeArgs);
return Collections.singletonList(triggerInfo);
}
};
return getTriggerSatisfiedResult(context.getNotifications(), ImmutableList.of(), function);
}
@Override
public void updateLaunchArguments(ProgramSchedule schedule, List notifications,
Map systemArgs, Map userArgs) {
// no-op
}
/**
* 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 type of the result to be returned
* @return a result of type T
*/
private T getTriggerSatisfiedResult(List notifications, T defaultResult,
Function 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.isSameProgramExceptVersion(triggeringProgramId) && programStatuses.contains(programStatus)) {
return function.apply(new ProgramRunInfo(programStatus, programRunId));
}
}
return defaultResult;
}
/**
* Class for storing program status and run id of a program run.
*/
private static class ProgramRunInfo {
private final ProgramStatus programStatus;
private final ProgramRunId programRunId;
ProgramRunInfo(ProgramStatus programStatus, ProgramRunId programRunId) {
this.programStatus = programStatus;
this.programRunId = programRunId;
}
ProgramStatus getProgramStatus() {
return programStatus;
}
ProgramRunId getProgramRunId() {
return programRunId;
}
}
}