001/* 002 * Copyright 2006-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.batch.core.repository; 018 019import org.springframework.batch.core.Job; 020import org.springframework.batch.core.JobExecution; 021import org.springframework.batch.core.JobInstance; 022import org.springframework.batch.core.JobParameters; 023import org.springframework.batch.core.Step; 024import org.springframework.batch.core.StepExecution; 025import org.springframework.batch.core.repository.dao.JobExecutionDao; 026import org.springframework.batch.core.repository.dao.JobInstanceDao; 027import org.springframework.batch.item.ExecutionContext; 028import org.springframework.lang.Nullable; 029import org.springframework.transaction.annotation.Isolation; 030 031import java.util.Collection; 032 033/** 034 * <p> 035 * Repository responsible for persistence of batch meta-data entities. 036 * </p> 037 * 038 * @see JobInstance 039 * @see JobExecution 040 * @see StepExecution 041 * 042 * @author Lucas Ward 043 * @author Dave Syer 044 * @author Robert Kasanicky 045 * @author David Turanski 046 * @author Michael Minella 047 * @author Mahmoud Ben Hassine 048 */ 049public interface JobRepository { 050 051 /** 052 * Check if an instance of this job already exists with the parameters 053 * provided. 054 * 055 * @param jobName the name of the job 056 * @param jobParameters the parameters to match 057 * @return true if a {@link JobInstance} already exists for this job name 058 * and job parameters 059 */ 060 boolean isJobInstanceExists(String jobName, JobParameters jobParameters); 061 062 /** 063 * Create a new {@link JobInstance} with the name and job parameters provided. 064 * 065 * @param jobName logical name of the job 066 * @param jobParameters parameters used to execute the job 067 * @return the new {@link JobInstance} 068 */ 069 JobInstance createJobInstance(String jobName, JobParameters jobParameters); 070 071 /** 072 * Create a new {@link JobExecution} based upon the {@link JobInstance} it's associated 073 * with, the {@link JobParameters} used to execute it with and the location of the configuration 074 * file that defines the job. 075 * 076 * @param jobInstance {@link JobInstance} instance to initialize the new JobExecution. 077 * @param jobParameters {@link JobParameters} instance to initialize the new JobExecution. 078 * @param jobConfigurationLocation {@link String} instance to initialize the new JobExecution. 079 * @return the new {@link JobExecution}. 080 */ 081 JobExecution createJobExecution(JobInstance jobInstance, JobParameters jobParameters, String jobConfigurationLocation); 082 083 /** 084 * <p> 085 * Create a {@link JobExecution} for a given {@link Job} and 086 * {@link JobParameters}. If matching {@link JobInstance} already exists, 087 * the job must be restartable and it's last JobExecution must *not* be 088 * completed. If matching {@link JobInstance} does not exist yet it will be 089 * created. 090 * </p> 091 * 092 * <p> 093 * If this method is run in a transaction (as it normally would be) with 094 * isolation level at {@link Isolation#REPEATABLE_READ} or better, then this 095 * method should block if another transaction is already executing it (for 096 * the same {@link JobParameters} and job name). The first transaction to 097 * complete in this scenario obtains a valid {@link JobExecution}, and 098 * others throw {@link JobExecutionAlreadyRunningException} (or timeout). 099 * There are no such guarantees if the {@link JobInstanceDao} and 100 * {@link JobExecutionDao} do not respect the transaction isolation levels 101 * (e.g. if using a non-relational data-store, or if the platform does not 102 * support the higher isolation levels). 103 * </p> 104 * 105 * @param jobName the name of the job that is to be executed 106 * 107 * @param jobParameters the runtime parameters for the job 108 * 109 * @return a valid {@link JobExecution} for the arguments provided 110 * 111 * @throws JobExecutionAlreadyRunningException if there is a 112 * {@link JobExecution} already running for the job instance with the 113 * provided job and parameters. 114 * @throws JobRestartException if one or more existing {@link JobInstance}s 115 * is found with the same parameters and {@link Job#isRestartable()} is 116 * false. 117 * @throws JobInstanceAlreadyCompleteException if a {@link JobInstance} is 118 * found and was already completed successfully. 119 * 120 */ 121 JobExecution createJobExecution(String jobName, JobParameters jobParameters) 122 throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException; 123 124 /** 125 * Update the {@link JobExecution} (but not its {@link ExecutionContext}). 126 * 127 * Preconditions: {@link JobExecution} must contain a valid 128 * {@link JobInstance} and be saved (have an id assigned). 129 * 130 * @param jobExecution {@link JobExecution} instance to be updated in the repo. 131 */ 132 void update(JobExecution jobExecution); 133 134 /** 135 * Save the {@link StepExecution} and its {@link ExecutionContext}. ID will 136 * be assigned - it is not permitted that an ID be assigned before calling 137 * this method. Instead, it should be left blank, to be assigned by a 138 * {@link JobRepository}. 139 * 140 * Preconditions: {@link StepExecution} must have a valid {@link Step}. 141 * 142 * @param stepExecution {@link StepExecution} instance to be added to the repo. 143 */ 144 void add(StepExecution stepExecution); 145 146 /** 147 * Save a collection of {@link StepExecution}s and each {@link ExecutionContext}. The 148 * StepExecution ID will be assigned - it is not permitted that an ID be assigned before calling 149 * this method. Instead, it should be left blank, to be assigned by {@link JobRepository}. 150 * 151 * Preconditions: {@link StepExecution} must have a valid {@link Step}. 152 * 153 * @param stepExecutions collection of {@link StepExecution} instances to be added to the repo. 154 */ 155 void addAll(Collection<StepExecution> stepExecutions); 156 157 /** 158 * Update the {@link StepExecution} (but not its {@link ExecutionContext}). 159 * 160 * Preconditions: {@link StepExecution} must be saved (have an id assigned). 161 * 162 * @param stepExecution {@link StepExecution} instance to be updated in the repo. 163 */ 164 void update(StepExecution stepExecution); 165 166 /** 167 * Persist the updated {@link ExecutionContext}s of the given 168 * {@link StepExecution}. 169 * 170 * @param stepExecution {@link StepExecution} instance to be used to update the context. 171 */ 172 void updateExecutionContext(StepExecution stepExecution); 173 174 /** 175 * Persist the updated {@link ExecutionContext} of the given 176 * {@link JobExecution}. 177 * @param jobExecution {@link JobExecution} instance to be used to update the context. 178 */ 179 void updateExecutionContext(JobExecution jobExecution); 180 181 /** 182 * @param jobInstance {@link JobInstance} instance containing the step executions. 183 * @param stepName the name of the step execution that might have run. 184 * @return the last execution of step for the given job instance. 185 */ 186 @Nullable 187 StepExecution getLastStepExecution(JobInstance jobInstance, String stepName); 188 189 /** 190 * @param jobInstance {@link JobInstance} instance containing the step executions. 191 * @param stepName the name of the step execution that might have run. 192 * @return the execution count of the step within the given job instance. 193 */ 194 int getStepExecutionCount(JobInstance jobInstance, String stepName); 195 196 /** 197 * @param jobName the name of the job that might have run 198 * @param jobParameters parameters identifying the {@link JobInstance} 199 * @return the last execution of job if exists, null otherwise 200 */ 201 @Nullable 202 JobExecution getLastJobExecution(String jobName, JobParameters jobParameters); 203 204}