/*
* Copyright (c) 2012-2016 Red Hat, Inc. and/or its affiliates.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cheng Fang - Initial API and implementation
*/
package org.jberet.runtime.runner;
import java.util.List;
import javax.batch.api.listener.JobListener;
import javax.batch.runtime.BatchStatus;
import org.jberet._private.BatchLogger;
import org.jberet.creation.JobScopedContextImpl;
import org.jberet.job.model.Job;
import org.jberet.job.model.JobElement;
import org.jberet.job.model.Listeners;
import org.jberet.job.model.RefArtifact;
import org.jberet.runtime.JobExecutionImpl;
import org.jberet.runtime.context.JobContextImpl;
import org.jberet.spi.JobTask;
public final class JobExecutionRunner extends CompositeExecutionRunner<JobContextImpl> implements JobTask {
private final Job job;
public JobExecutionRunner(final JobContextImpl jobContext) {
super(jobContext, null);
this.job = jobContext.getJob();
}
@Override
protected List<? extends JobElement> getJobElements() {
return job.getJobElements();
}
@Override
public void run() {
final JobExecutionImpl jobExecution = batchContext.getJobExecution();
// the job may be stopped right after starting
if (jobExecution.getBatchStatus() != BatchStatus.STOPPING) {
jobExecution.setBatchStatus(BatchStatus.STARTED);
batchContext.getJobRepository().updateJobExecution(jobExecution, false, false);
}
JobListener[] jobListeners = null;
int i = 0;
try {
jobListeners = createJobListeners();
for (; i < jobListeners.length; i++) {
jobListeners[i].beforeJob();
}
runFromHeadOrRestartPoint(jobExecution.getRestartPosition());
if (jobExecution.getBatchStatus() == BatchStatus.STARTED) {
jobExecution.setBatchStatus(BatchStatus.COMPLETED);
}
} catch (final Throwable e) {
BatchLogger.LOGGER.failToRunJob(e, job.getId(), "", job);
jobExecution.setBatchStatus(BatchStatus.FAILED);
if (jobListeners == null) {
jobExecution.setExitStatus(e.toString());
}
} finally {
if (jobListeners != null && jobListeners.length > 0) {
for (i = 0; i < jobListeners.length; i++) {
try {
jobListeners[i].afterJob();
} catch (final Throwable e) {
BatchLogger.LOGGER.failToRunJob(e, job.getId(), "", jobListeners[i]);
jobExecution.setBatchStatus(BatchStatus.FAILED);
}
}
batchContext.destroyArtifact(jobListeners);
}
}
boolean saveJobParameters = false;
switch (jobExecution.getBatchStatus()) {
case COMPLETED:
break;
case STARTED:
jobExecution.setBatchStatus(BatchStatus.COMPLETED);
break;
case STOPPING:
jobExecution.setBatchStatus(BatchStatus.STOPPED);
//fall through
case FAILED:
case STOPPED:
saveJobParameters = adjustRestartFailedOrStopped(jobExecution);
break;
}
batchContext.getJobRepository().updateJobExecution(jobExecution, true, saveJobParameters);
batchContext.setTransientUserData(null);
JobScopedContextImpl.ScopedInstance.destroy(batchContext.getScopedBeans());
jobExecution.cleanUp();
}
/**
* Adjusts restart position and job xml name if needed for FAILED or STOPPED job execution.
*
* @param jobExecution a failed or stopped job execution
* @return true if the internal job parameter with key {@link org.jberet.job.model.Job#JOB_XML_NAME} was added to
* {@code jobExecution}; false otherwise.
*/
private boolean adjustRestartFailedOrStopped(final JobExecutionImpl jobExecution) {
if (!job.getRestartableBoolean()) {
jobExecution.setRestartPosition(Job.UNRESTARTABLE);
}
if (job.getJobXmlName() != null) {
//jobXmlName is different than jobId, save it so the restart can correctly locate job xml file if the job
//is not available from the cache.
jobExecution.addJobParameter(Job.JOB_XML_NAME, job.getJobXmlName());
return true;
}
return false;
}
private JobListener[] createJobListeners() {
final Listeners listeners = job.getListeners();
if (listeners != null) {
final List<RefArtifact> listenerList = listeners.getListeners();
final int count = listenerList.size();
final JobListener[] jobListeners = new JobListener[count];
for (int i = 0; i < count; i++) {
final RefArtifact listener = listenerList.get(i);
jobListeners[i] = batchContext.createArtifact(listener.getRef(), null, listener.getProperties());
}
return jobListeners;
} else {
return new JobListener[0];
}
}
@Override
public int getRequiredRemainingPermits() {
return 2;
}
}