All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.jbatch.container.jobinstance.JobExecutionHelper Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012 International Business Machines Corp.
 * 
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. 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 com.ibm.jbatch.container.jobinstance;

import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import jakarta.batch.operations.JobExecutionAlreadyCompleteException;
import jakarta.batch.operations.JobExecutionNotMostRecentException;
import jakarta.batch.operations.JobRestartException;
import jakarta.batch.operations.JobStartException;
import jakarta.batch.operations.NoSuchJobExecutionException;
import jakarta.batch.runtime.BatchStatus;
import jakarta.batch.runtime.JobInstance;

import com.ibm.jbatch.container.context.impl.JobContextImpl;
import com.ibm.jbatch.container.jsl.ModelResolverFactory;
import com.ibm.jbatch.container.modelresolver.PropertyResolver;
import com.ibm.jbatch.container.modelresolver.PropertyResolverFactory;
import com.ibm.jbatch.container.navigator.ModelNavigator;
import com.ibm.jbatch.container.navigator.NavigatorFactory;
import com.ibm.jbatch.container.services.IBatchKernelService;
import com.ibm.jbatch.container.services.IJobExecution;
import com.ibm.jbatch.container.services.IJobStatusManagerService;
import com.ibm.jbatch.container.services.IPersistenceManagerService;
import com.ibm.jbatch.container.servicesmanager.ServicesManager;
import com.ibm.jbatch.container.servicesmanager.ServicesManagerImpl;
import com.ibm.jbatch.container.status.JobStatus;
import com.ibm.jbatch.jsl.model.JSLJob;
import com.ibm.jbatch.jsl.model.JSLProperties;

public class JobExecutionHelper {

	private final static String CLASSNAME = JobExecutionHelper.class.getName();
	private final static Logger logger = Logger.getLogger(CLASSNAME);

	private static ServicesManager servicesManager = ServicesManagerImpl.getInstance();

	private static IJobStatusManagerService _jobStatusManagerService = 
			servicesManager.getJobStatusManagerService();

	private static IPersistenceManagerService _persistenceManagementService = 
			servicesManager.getPersistenceManagerService();
	private static IBatchKernelService _batchKernelService = servicesManager.getBatchKernelService();


	private static ModelNavigator getResolvedJobNavigator(String jobXml, Properties jobParameters, boolean parallelExecution) {

		JSLJob jobModel = ModelResolverFactory.createJobResolver().resolveModel(jobXml); 
		PropertyResolver propResolver = PropertyResolverFactory.createJobPropertyResolver(parallelExecution);
		propResolver.substituteProperties(jobModel, jobParameters);

		return NavigatorFactory.createJobNavigator(jobModel);
	}

	private static ModelNavigator getResolvedJobNavigator(JSLJob jobModel, Properties jobParameters, boolean isPartitionedStep) {

		PropertyResolver propResolver = PropertyResolverFactory.createJobPropertyResolver(isPartitionedStep);
		propResolver.substituteProperties(jobModel, jobParameters);

		return NavigatorFactory.createJobNavigator(jobModel);
	}

	private static JobContextImpl getJobContext(ModelNavigator jobNavigator) {
		JSLProperties jslProperties = new JSLProperties();
		if(jobNavigator.getRootModelElement() != null) {
			jslProperties = jobNavigator.getRootModelElement().getProperties();
		}
		return new JobContextImpl(jobNavigator, jslProperties); 
	}

	private static JobInstance getNewJobInstance(String name, String jobXml) {
		String apptag = _batchKernelService.getBatchSecurityHelper().getCurrentTag();
		return _persistenceManagementService.createJobInstance(name, apptag, jobXml);
	}

	private static JobInstance getNewSubJobInstance(String name) {
		String apptag = _batchKernelService.getBatchSecurityHelper().getCurrentTag();
		return _persistenceManagementService.createSubJobInstance(name, apptag);
	}

	private static JobStatus createNewJobStatus(JobInstance jobInstance) {
		long instanceId = jobInstance.getInstanceId();
		JobStatus jobStatus = _jobStatusManagerService.createJobStatus(instanceId);
		jobStatus.setJobInstance(jobInstance);
		return jobStatus;
	}

	private static void validateRestartableFalseJobsDoNotRestart(JSLJob jobModel)
			throws JobRestartException {
		if (jobModel.getRestartable() != null && jobModel.getRestartable().equalsIgnoreCase("false")) {
			throw new JobRestartException("Job Restartable attribute is false, Job cannot be restarted.");
		}
	}

	public static RuntimeJobExecution startJob(String jobXML, Properties jobParameters) throws JobStartException {
		logger.entering(CLASSNAME, "startJob", new Object[]{jobXML, jobParameters==null ? "" : jobParameters});

		JSLJob jobModel = ModelResolverFactory.createJobResolver().resolveModel(jobXML); 

		ModelNavigator jobNavigator = getResolvedJobNavigator(jobModel, jobParameters, false);

		JobContextImpl jobContext = getJobContext(jobNavigator);

		JobInstance jobInstance = getNewJobInstance(jobNavigator.getRootModelElement().getId(), jobXML);

		RuntimeJobExecution executionHelper = 
				_persistenceManagementService.createJobExecution(jobInstance, jobParameters, jobContext.getBatchStatus());

		executionHelper.prepareForExecution(jobContext);

		JobStatus jobStatus = createNewJobStatus(jobInstance);
		_jobStatusManagerService.updateJobStatus(jobStatus);

		logger.exiting(CLASSNAME, "startJob", executionHelper);

		return executionHelper;
	}

	public static RuntimeFlowInSplitExecution startFlowInSplit(JSLJob jobModel) throws JobStartException{
		logger.entering(CLASSNAME, "startFlowInSplit", jobModel);

		ModelNavigator jobNavigator = getResolvedJobNavigator(jobModel, null, false);
		JobContextImpl jobContext = getJobContext(jobNavigator);
		
		JobInstance jobInstance = getNewSubJobInstance(jobNavigator.getRootModelElement().getId());

		RuntimeFlowInSplitExecution executionHelper = 
				_persistenceManagementService.createFlowInSplitExecution(jobInstance, jobContext.getBatchStatus());

		executionHelper.prepareForExecution(jobContext);

		JobStatus jobStatus = createNewJobStatus(jobInstance);
		_jobStatusManagerService.updateJobStatus(jobStatus);

		logger.exiting(CLASSNAME, "startFlowInSplit", executionHelper);
		return executionHelper;
	}
	
	public static RuntimeJobExecution startPartition(JSLJob jobModel, Properties jobParameters) throws JobStartException{
		logger.entering(CLASSNAME, "startPartition", new Object[]{jobModel, jobParameters ==null ? "" :jobParameters});

		ModelNavigator jobNavigator = getResolvedJobNavigator(jobModel, jobParameters, true);
		JobContextImpl jobContext = getJobContext(jobNavigator);
		
		JobInstance jobInstance = getNewSubJobInstance(jobNavigator.getRootModelElement().getId());

		RuntimeJobExecution executionHelper = 
				_persistenceManagementService.createJobExecution(jobInstance, jobParameters, jobContext.getBatchStatus());

		executionHelper.prepareForExecution(jobContext);

		JobStatus jobStatus = createNewJobStatus(jobInstance);
		_jobStatusManagerService.updateJobStatus(jobStatus);

		logger.exiting(CLASSNAME, "startPartition", executionHelper);
		return executionHelper;
	}
	
	public static RuntimeJobExecution restartJob(long executionId, JSLJob gennedJobModel) throws JobRestartException, JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
		return restartExecution(executionId, null, null, false, false);
	}

	private static void validateJobInstanceNotCompleteOrAbandonded(JobStatus jobStatus) throws JobRestartException, JobExecutionAlreadyCompleteException {
		if (jobStatus.getBatchStatus() == null) {
			String msg = "On restart, we didn't find an earlier batch status.";
			logger.warning(msg);
			throw new IllegalStateException(msg);
		}

		if (jobStatus.getBatchStatus().equals(BatchStatus.COMPLETED)) {
			String msg = "Already completed job instance = " + jobStatus.getJobInstanceId();
			logger.fine(msg);
			throw new JobExecutionAlreadyCompleteException(msg);
		} else if (jobStatus.getBatchStatus().equals(BatchStatus.ABANDONED)) {
			String msg = "Abandoned job instance = " + jobStatus.getJobInstanceId();
			logger.warning(msg);
			throw new JobRestartException(msg);
		} 
	}

	private static void validateJobExecutionIsMostRecent(long jobInstanceId, long executionId) throws JobExecutionNotMostRecentException {

		long mostRecentExecutionId = _persistenceManagementService.getMostRecentExecutionId(jobInstanceId);

		if ( mostRecentExecutionId != executionId ) {
			String message = "ExecutionId: " + executionId + " is not the most recent execution.";
			logger.warning(message);
			throw new JobExecutionNotMostRecentException(message);
		}
	}
	
	public static RuntimeJobExecution restartPartition(long execId, JSLJob gennedJobModel, Properties partitionProps) throws JobRestartException, 
	JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
		return restartExecution(execId, gennedJobModel, partitionProps, true, false);	
	}

	public static RuntimeFlowInSplitExecution restartFlowInSplit(long execId, JSLJob gennedJobModel) throws JobRestartException, 
	JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
		
		long jobInstanceId = _persistenceManagementService.getJobInstanceIdByExecutionId(execId);
		
		JobStatus jobStatus = _jobStatusManagerService.getJobStatus(jobInstanceId);
		
		validateJobExecutionIsMostRecent(jobInstanceId, execId);
		
		// In particular, don't ensure that job hasn't been completed, since we always restart 
		// split-flows.
		
		JobInstanceImpl jobInstance = jobStatus.getJobInstance();

		ModelNavigator jobNavigator = getResolvedJobNavigator(gennedJobModel, null, false);
		
		JobContextImpl jobContext = getJobContext(jobNavigator);
		
		RuntimeFlowInSplitExecution executionHelper = _persistenceManagementService.createFlowInSplitExecution(jobInstance, jobContext.getBatchStatus());

		executionHelper.prepareForExecution(jobContext, jobStatus.getRestartOn());

		_jobStatusManagerService.updateJobStatusWithNewExecution(jobInstance.getInstanceId(), executionHelper.getExecutionId());        

		return executionHelper;
		
	}
	
	public static RuntimeJobExecution restartJob(long executionId, Properties restartJobParameters) throws JobRestartException, 
	JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
		return restartExecution(executionId, null, restartJobParameters, false, false);	
	}
	
	private static RuntimeJobExecution restartExecution(long executionId, JSLJob gennedJobModel, Properties restartJobParameters, boolean parallelExecution, boolean flowInSplit) throws JobRestartException, 
	JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {

		long jobInstanceId = _persistenceManagementService.getJobInstanceIdByExecutionId(executionId);

		JobStatus jobStatus = _jobStatusManagerService.getJobStatus(jobInstanceId);

		if (logger.isLoggable(Level.FINE)) {
			logger.fine("On restartJob with jobInstance Id = " + jobInstanceId + " , found JobStatus: " + jobStatus + 
					", batchStatus = " + jobStatus.getBatchStatus().name() ); 
		}

		validateJobExecutionIsMostRecent(jobInstanceId, executionId);

		validateJobInstanceNotCompleteOrAbandonded(jobStatus);

		JobInstanceImpl jobInstance = jobStatus.getJobInstance();

		ModelNavigator jobNavigator = null;

		// If we are in a parallel job that is genned use the regenned JSL.
		if (gennedJobModel == null) {
			jobNavigator = getResolvedJobNavigator(jobInstance.getJobXML(), restartJobParameters, parallelExecution);
		} else {
			jobNavigator = getResolvedJobNavigator(gennedJobModel, restartJobParameters, parallelExecution);
		}
		// JSLJob jobModel = ModelResolverFactory.createJobResolver().resolveModel(jobInstance.getJobXML());
		validateRestartableFalseJobsDoNotRestart(jobNavigator.getRootModelElement());

		JobContextImpl jobContext = getJobContext(jobNavigator);
		
		RuntimeJobExecution executionHelper;
		if (flowInSplit) {
			executionHelper = _persistenceManagementService.createFlowInSplitExecution(jobInstance, jobContext.getBatchStatus());
		} else {
			executionHelper = _persistenceManagementService.createJobExecution(jobInstance, restartJobParameters, jobContext.getBatchStatus());
		}
		executionHelper.prepareForExecution(jobContext, jobStatus.getRestartOn());
		_jobStatusManagerService.updateJobStatusWithNewExecution(jobInstance.getInstanceId(), executionHelper.getExecutionId());        

		return executionHelper;
	}    

	public static IJobExecution getPersistedJobOperatorJobExecution(long jobExecutionId) throws NoSuchJobExecutionException {
		return _persistenceManagementService.jobOperatorGetJobExecution(jobExecutionId);
	}

	
	public static JobInstance getJobInstance(long executionId){
		JobStatus jobStatus = _jobStatusManagerService.getJobStatusFromExecutionId(executionId);
		JobInstanceImpl jobInstance = jobStatus.getJobInstance();
		return jobInstance;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy