/* * Copyright © 2014-2016 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 co.cask.cdap.app.store; import co.cask.cdap.api.ProgramSpecification; import co.cask.cdap.api.app.ApplicationSpecification; import co.cask.cdap.api.data.stream.StreamSpecification; import co.cask.cdap.api.flow.FlowSpecification; import co.cask.cdap.api.schedule.ScheduleSpecification; import co.cask.cdap.api.worker.Worker; import co.cask.cdap.api.workflow.Workflow; import co.cask.cdap.api.workflow.WorkflowToken; import co.cask.cdap.app.program.Program; import co.cask.cdap.common.ApplicationNotFoundException; import co.cask.cdap.common.ProgramNotFoundException; import co.cask.cdap.internal.app.store.RunRecordMeta; import co.cask.cdap.internal.app.store.WorkflowDataset; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.ProgramRunStatus; import co.cask.cdap.proto.WorkflowNodeStateDetail; import co.cask.cdap.proto.WorkflowStatistics; import co.cask.cdap.proto.id.ProgramRunId; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Predicate; import org.apache.twill.api.RunId; import org.apache.twill.filesystem.Location; import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nullable; /** * {@link Store} operates on a {@link Program}. It's responsible * for managing the non-runtime lifecycle of a {@link Program} */ public interface Store { /** * Compare and set operation that allow to compare and set expected and update status. * Implementation of this method should guarantee that the operation is atomic or in transaction. * * @param id Info about program * @param pid The run id * @param expectedStatus The expected value * @param updateStatus The new value */ void compareAndSetStatus(Id.Program id, String pid, ProgramRunStatus expectedStatus, ProgramRunStatus updateStatus); /** * Loads a given program. * * @param program id of the program * @return An instance of {@link co.cask.cdap.app.program.DefaultProgram} if found. * @throws IOException */ Program loadProgram(Id.Program program) throws IOException, ApplicationNotFoundException, ProgramNotFoundException; /** * Logs start of program run. * * @param id Info about program * @param pid run id * @param startTime start timestamp in seconds; if run id is time-based pass the time from the run id * @param twillRunId twill run id * @param runtimeArgs the runtime arguments for this program run * @param systemArgs the system arguments for this program run */ void setStart(Id.Program id, String pid, long startTime, @Nullable String twillRunId, Map<String, String> runtimeArgs, Map<String, String> systemArgs); /** * Logs start of program run. This is a convenience method for testing, actual run starts should be recorded using * {@link #setStart(Id.Program, String, long, String, Map, Map)}. * * @param id Info about program * @param pid run id * @param startTime start timestamp in seconds; if run id is time-based pass the time from the run id */ @VisibleForTesting void setStart(Id.Program id, String pid, long startTime); /** * Logs end of program run. * * @param id id of program * @param pid run id * @param endTime end timestamp in seconds * @param runStatus {@link ProgramRunStatus} of program run */ void setStop(Id.Program id, String pid, long endTime, ProgramRunStatus runStatus); /** * Logs end of program run. * * @param id id of program * @param pid run id * @param endTime end timestamp in seconds * @param runStatus {@link ProgramRunStatus} of program run * @param failureCause failure cause if the program failed to execute */ void setStop(Id.Program id, String pid, long endTime, ProgramRunStatus runStatus, @Nullable Throwable failureCause); /** * Logs suspend of a program run. * @param id id of the program * @param pid run id */ void setSuspend(Id.Program id, String pid); /** * Logs resume of a program run. * @param id id of the program * @param pid run id */ void setResume(Id.Program id, String pid); /** * Fetches run records for particular program. Returns only finished runs. * Returned ProgramRunRecords are sorted by their startTime. * * @param id program id. * @param status status of the program running/completed/failed or all * @param startTime fetch run history that has started after the startTime in seconds * @param endTime fetch run history that has started before the endTime in seconds * @param limit max number of entries to fetch for this history call * @return list of logged runs */ List<RunRecordMeta> getRuns(Id.Program id, ProgramRunStatus status, long startTime, long endTime, int limit); /** * Fetches run records for particular program. Returns only finished runs. * Returned ProgramRunRecords are sorted by their startTime. * * @param id program id. * @param status status of the program running/completed/failed or all * @param startTime fetch run history that has started after the startTime in seconds * @param endTime fetch run history that has started before the endTime in seconds * @param limit max number of entries to fetch for this history call * @param filter predicate to be passed to filter the records * @return list of logged runs */ List<RunRecordMeta> getRuns(Id.Program id, ProgramRunStatus status, long startTime, long endTime, int limit, Predicate<RunRecordMeta> filter); /** * Fetches the run records for the particular status. * @param status status of the program running/completed/failed or all * @param filter predicate to be passed to filter the records * @return list of logged runs */ List<RunRecordMeta> getRuns(ProgramRunStatus status, Predicate<RunRecordMeta> filter); /** * Fetches the run record for particular run of a program. * * @param id program id * @param runid run id of the program * @return run record for the specified program and runid, null if not found */ @Nullable RunRecordMeta getRun(Id.Program id, String runid); /** * Creates a new stream if it does not exist. * @param id the namespace id * @param stream the stream to create */ void addStream(Id.Namespace id, StreamSpecification stream); /** * Get the spec of a named stream. * @param id the namespace id * @param name the name of the stream */ StreamSpecification getStream(Id.Namespace id, String name); /** * Get the specs of all streams for a namespace. * * @param id the namespace id */ Collection<StreamSpecification> getAllStreams(Id.Namespace id); /** * Creates new application if it doesn't exist. Updates existing one otherwise. * * @param id application id * @param specification application specification to store * @param appArchiveLocation location of the deployed app archive */ void addApplication(Id.Application id, ApplicationSpecification specification, Location appArchiveLocation); /** * Return a list of program specifications that are deleted comparing the specification in the store with the * spec that is passed. * * @param id ApplicationId * @param specification Application specification * @return List of ProgramSpecifications that are deleted */ List<ProgramSpecification> getDeletedProgramSpecifications(Id.Application id, ApplicationSpecification specification); /** * Returns application specification by id. * * @param id application id * @return application specification */ @Nullable ApplicationSpecification getApplication(Id.Application id); /** * Returns a collection of all application specs in the specified namespace * * @param id the namespace to get application specs from * @return collection of all application specs in the namespace */ Collection<ApplicationSpecification> getAllApplications(Id.Namespace id); /** * Returns location of the application archive. * * @param id application id * @return application archive location */ @Nullable Location getApplicationArchiveLocation(Id.Application id); /** * Sets number of instances of specific flowlet. * * @param id flow id * @param flowletId flowlet id * @param count new number of instances * @return The {@link FlowSpecification} before the instance change */ FlowSpecification setFlowletInstances(Id.Program id, String flowletId, int count); /** * Gets number of instances of specific flowlet. * * @param id flow id * @param flowletId flowlet id */ int getFlowletInstances(Id.Program id, String flowletId); /** * Sets the number of instances of a service. * * @param id program id * @param instances number of instances */ void setServiceInstances(Id.Program id, int instances); /** * Returns the number of instances of a service. * @param id program id * @return number of instances */ int getServiceInstances(Id.Program id); /** * Sets the number of instances of a {@link Worker} * * @param id program id * @param instances number of instances */ void setWorkerInstances(Id.Program id, int instances); /** * Gets the number of instances of a {@link Worker} * * @param id program id * @return number of instances */ int getWorkerInstances(Id.Program id); /** * Removes all program under the given application and also the application itself. * * @param id Application id */ void removeApplication(Id.Application id); /** * Removes all applications (with programs) associated with the given namespace. * * @param id namespace id whose applications to remove */ void removeAllApplications(Id.Namespace id); /** * Remove all metadata associated with the given namespace. * * @param id namespace id whose items to remove */ void removeAll(Id.Namespace id); /** * Get run time arguments for a program. * * @param runId id of the program run * @return Map of key, value pairs */ Map<String, String> getRuntimeArguments(Id.Run runId); /** * Adds a schedule for a particular program. If the schedule with the name already exists, the method will * throw RuntimeException. * @param program defines program to which a schedule is being added * @param scheduleSpecification defines the schedule to be added for the program */ void addSchedule(Id.Program program, ScheduleSpecification scheduleSpecification); /** * Deletes a schedules from a particular program * @param program defines program from which a schedule is being deleted * @param scheduleName the name of the schedule to be removed from the program */ void deleteSchedule(Id.Program program, String scheduleName); /** * Check if an application exists. * @param id id of application. * @return true if the application exists, false otherwise. */ boolean applicationExists(Id.Application id); /** * Check if a program exists. * @param id id of program. * @return true if the program exists, false otherwise. */ boolean programExists(Id.Program id); /** * Updates the {@link WorkflowToken} for a specified run of a workflow. * * @param workflowRunId workflow run for which the {@link WorkflowToken} is to be updated * @param token the {@link WorkflowToken} to update */ void updateWorkflowToken(ProgramRunId workflowRunId, WorkflowToken token); /** * Retrieves the {@link WorkflowToken} for a specified run of a workflow. * * @param workflowId {@link Id.Workflow} of the workflow whose {@link WorkflowToken} is to be retrieved * @param workflowRunId Run Id of the workflow for which the {@link WorkflowToken} is to be retrieved * @return the {@link WorkflowToken} for the specified workflow run */ WorkflowToken getWorkflowToken(Id.Workflow workflowId, String workflowRunId); /** * Add node state for the given {@link Workflow} run. This method is used to update the * state of the custom actions started by Workflow. * @param workflowRunId the Workflow run * @param nodeStateDetail the node state to be added for the Workflow run */ void addWorkflowNodeState(ProgramRunId workflowRunId, WorkflowNodeStateDetail nodeStateDetail); /** * Get the node states for a given {@link Workflow} run. * * @param workflowRunId run of the Workflow. * @return {@link List} of {@link WorkflowNodeStateDetail} */ List<WorkflowNodeStateDetail> getWorkflowNodeStates(ProgramRunId workflowRunId); /** * Used by {@link co.cask.cdap.gateway.handlers.WorkflowStatsSLAHttpHandler} to get the statistics of all completed * workflows in a time range. * * @param workflowId Workflow that needs to have its statistics returned * @param startTime StartTime of the range * @param endTime EndTime of the range * @param percentiles List of percentiles that the user wants to see * @return the statistics for a given workflow */ WorkflowStatistics getWorkflowStatistics(Id.Workflow workflowId, long startTime, long endTime, List<Double> percentiles); /** * Returns the record that represents the run of a workflow. * * @param workflowId The Workflow whose run needs to be queried * @param runId RunId of the workflow run * @return A workflow run record corresponding to the runId */ WorkflowDataset.WorkflowRunRecord getWorkflowRun(Id.Workflow workflowId, String runId); /** * Get a list of workflow runs that are spaced apart by time interval in both directions from the run id provided. * * @param workflow The workflow whose statistics need to be obtained * @param runId The run id of the workflow * @param limit The number of the records that the user wants to compare against on either side of the run * @param timeInterval The timeInterval with which the user wants to space out the runs * @return Map of runId of Workflow to DetailedStatistics of the run */ Collection<WorkflowDataset.WorkflowRunRecord> retrieveSpacedRecords(Id.Workflow workflow, String runId, int limit, long timeInterval); /** * @return programs that were running between given start and end time. */ Set<RunId> getRunningInRange(long startTimeInSecs, long endTimeInSecs); }