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.explore.support;
018
019import org.springframework.batch.core.JobExecution;
020import org.springframework.batch.core.JobInstance;
021import org.springframework.batch.core.StepExecution;
022import org.springframework.batch.core.explore.JobExplorer;
023import org.springframework.batch.core.launch.NoSuchJobException;
024import org.springframework.batch.core.repository.dao.ExecutionContextDao;
025import org.springframework.batch.core.repository.dao.JobExecutionDao;
026import org.springframework.batch.core.repository.dao.JobInstanceDao;
027import org.springframework.batch.core.repository.dao.StepExecutionDao;
028import org.springframework.lang.Nullable;
029
030import java.util.List;
031import java.util.Set;
032
033/**
034 * Implementation of {@link JobExplorer} using the injected DAOs.
035 *
036 * @author Dave Syer
037 * @author Lucas Ward
038 * @author Michael Minella
039 * @author Will Schipp
040 * @author Mahmoud Ben Hassine
041 *
042 * @see JobExplorer
043 * @see JobInstanceDao
044 * @see JobExecutionDao
045 * @see StepExecutionDao
046 * @since 2.0
047 */
048public class SimpleJobExplorer implements JobExplorer {
049
050        private JobInstanceDao jobInstanceDao;
051
052        private JobExecutionDao jobExecutionDao;
053
054        private StepExecutionDao stepExecutionDao;
055
056        private ExecutionContextDao ecDao;
057
058        /**
059         * Provide default constructor with low visibility in case user wants to use
060         * use aop:proxy-target-class="true" for AOP interceptor.
061         */
062        SimpleJobExplorer() {
063        }
064
065        public SimpleJobExplorer(JobInstanceDao jobInstanceDao, JobExecutionDao jobExecutionDao,
066                        StepExecutionDao stepExecutionDao, ExecutionContextDao ecDao) {
067                super();
068                this.jobInstanceDao = jobInstanceDao;
069                this.jobExecutionDao = jobExecutionDao;
070                this.stepExecutionDao = stepExecutionDao;
071                this.ecDao = ecDao;
072        }
073
074        /*
075         * (non-Javadoc)
076         *
077         * @see
078         * org.springframework.batch.core.explore.JobExplorer#findJobExecutions(
079         * org.springframework.batch.core.JobInstance)
080         */
081        @Override
082        public List<JobExecution> getJobExecutions(JobInstance jobInstance) {
083                List<JobExecution> executions = jobExecutionDao.findJobExecutions(jobInstance);
084                for (JobExecution jobExecution : executions) {
085                        getJobExecutionDependencies(jobExecution);
086                        for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
087                                getStepExecutionDependencies(stepExecution);
088                        }
089                }
090                return executions;
091        }
092
093        /*
094         * (non-Javadoc)
095         *
096         * @see
097         * org.springframework.batch.core.explore.JobExplorer#findRunningJobExecutions
098         * (java.lang.String)
099         */
100        @Override
101        public Set<JobExecution> findRunningJobExecutions(String jobName) {
102                Set<JobExecution> executions = jobExecutionDao.findRunningJobExecutions(jobName);
103                for (JobExecution jobExecution : executions) {
104                        getJobExecutionDependencies(jobExecution);
105                        for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
106                                getStepExecutionDependencies(stepExecution);
107                        }
108                }
109                return executions;
110        }
111
112        /*
113         * (non-Javadoc)
114         *
115         * @see
116         * org.springframework.batch.core.explore.JobExplorer#getJobExecution(java
117         * .lang.Long)
118         */
119        @Override
120        public JobExecution getJobExecution(Long executionId) {
121                if (executionId == null) {
122                        return null;
123                }
124                JobExecution jobExecution = jobExecutionDao.getJobExecution(executionId);
125                if (jobExecution == null) {
126                        return null;
127                }
128                getJobExecutionDependencies(jobExecution);
129                for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
130                        getStepExecutionDependencies(stepExecution);
131                }
132                return jobExecution;
133        }
134
135        /*
136         * (non-Javadoc)
137         *
138         * @see
139         * org.springframework.batch.core.explore.JobExplorer#getStepExecution(java
140         * .lang.Long)
141         */
142        @Override
143        public StepExecution getStepExecution(Long jobExecutionId, Long executionId) {
144                JobExecution jobExecution = jobExecutionDao.getJobExecution(jobExecutionId);
145                if (jobExecution == null) {
146                        return null;
147                }
148                getJobExecutionDependencies(jobExecution);
149                StepExecution stepExecution = stepExecutionDao.getStepExecution(jobExecution, executionId);
150                getStepExecutionDependencies(stepExecution);
151                return stepExecution;
152        }
153
154        /*
155         * (non-Javadoc)
156         *
157         * @see
158         * org.springframework.batch.core.explore.JobExplorer#getJobInstance(java
159         * .lang.Long)
160         */
161        @Override
162        public JobInstance getJobInstance(@Nullable Long instanceId) {
163                return jobInstanceDao.getJobInstance(instanceId);
164        }
165
166        /*
167         * (non-Javadoc)
168         *
169         * @see
170         * org.springframework.batch.core.explore.JobExplorer#getLastJobInstances
171         * (java.lang.String, int)
172         */
173        @Override
174        public List<JobInstance> getJobInstances(String jobName, int start, int count) {
175                return jobInstanceDao.getJobInstances(jobName, start, count);
176        }
177
178        /*
179         * (non-Javadoc)
180         *
181         * @see org.springframework.batch.core.explore.JobExplorer#getJobNames()
182         */
183        @Override
184        public List<String> getJobNames() {
185                return jobInstanceDao.getJobNames();
186        }
187
188        /* (non-Javadoc)
189         * @see org.springframework.batch.core.explore.JobExplorer#getJobInstanceCount(java.lang.String)
190         */
191        @Override
192        public int getJobInstanceCount(@Nullable String jobName) throws NoSuchJobException {
193                return jobInstanceDao.getJobInstanceCount(jobName);
194        }
195
196        /*
197         * Find all dependencies for a JobExecution, including JobInstance (which
198         * requires JobParameters) plus StepExecutions
199         */
200        private void getJobExecutionDependencies(JobExecution jobExecution) {
201                JobInstance jobInstance = jobInstanceDao.getJobInstance(jobExecution);
202                stepExecutionDao.addStepExecutions(jobExecution);
203                jobExecution.setJobInstance(jobInstance);
204                jobExecution.setExecutionContext(ecDao.getExecutionContext(jobExecution));
205
206        }
207
208        private void getStepExecutionDependencies(StepExecution stepExecution) {
209                if (stepExecution != null) {
210                        stepExecution.setExecutionContext(ecDao.getExecutionContext(stepExecution));
211                }
212        }
213
214        @Override
215        public List<JobInstance> findJobInstancesByJobName(String jobName, int start, int count) {
216                return jobInstanceDao.findJobInstancesByName(jobName, start, count);
217        }
218}