Results 1 to 7 of 7

Thread: Which Class is responsible for saving the job metadata in repository?

Hybrid View

  1. #1

    Default Which Class is responsible for saving the job metadata in repository?

    I am trying to make a small batch admin (just to learn the basic functionalities; i know the spring-batch-admin already exists).
    What I want to do is : I have two applications running on different servers.
    1st is the Client that will send the job configuration files to the admin.
    2nd is the batch admin that i am trying to make;

    1st application is ready. I am able to send the data to the admin.
    The admin is taking the data but not putting in the repository.
    Where could possibly be i wrong?
    Here is the code. I am just for now implementing it in a controller.
    Code:
    @RequestMapping(value="uploadjob", method=RequestMethod.POST)
    	public @ResponseBody String upload(@RequestBody String job){
    		Collection<Job> jobs=jobLoader.reload(createContextFactory(job));
    		System.out.println(jobs);
    		return "Your Job has been submitted successfully :)";
    		
    	}
    
    private ApplicationContextFactory createContextFactory(String job) {
    		Resource r=new ByteArrayResource(job.getBytes());
    		ClassPathXmlApplicationContextFactory acf=new ClassPathXmlApplicationContextFactory();
    		acf.setResource(r);
    		acf.setApplicationContext(ctx1);
    		return acf;
    	}
    I am getting everything correct. except the job is not going in the repository. The above System.out.println(jobs) gives me [FlowJob: [name=mynewfilejob]]. I tried to debug the code but didn't get any method that takes me to saving it to repository.

    Please help.

  2. #2
    Join Date
    Sep 2008
    Location
    Chicagoland, IL
    Posts
    366

    Default

    How is your repository configured? What is the value of the job String you are receiving?
    Michael Minella
    Spring Batch Lead
    Author - Pro Spring Batch
    http://www.michaelminella.com
    Twitter: @MichaelMinella

  3. #3

    Default

    OK i am writing the complete configuration here.
    Capture.jpg

    db-context.xml
    Code:
    <bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="${db.driver}"></property>
    		<property name="url" value="${db.url}"></property>
    		<property name="username" value="${db.username}"></property>
    		<property name="password" value="${db.password}"></property>
    	</bean>
    
    	<bean id="transactionManager"
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<jdbc:initialize-database data-source="dataSource" enabled="false" ignore-failures="NONE">
    		<jdbc:script location="classpath*:/org/springframework/batch/core/schema-mysql.sql"/>
    	</jdbc:initialize-database>
    infrastructure-context.xml
    Code:
    <batch:job-repository id="jobRepository" data-source="dataSource" transaction-manager="transactionManager" isolation-level-for-create="SERIALIZABLE" />
    
    <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
    	<property name="jobRepository" ref="jobRepository"></property>
    	<property name="taskExecutor" ref="jobLauncherTaskExecutor"></property>
    </bean>
    <task:executor id="jobLauncherTaskExecutor" pool-size="20"/>
    
    <bean id="jobLoader" class="org.springframework.batch.core.configuration.support.DefaultJobLoader">
    	<property name="jobRegistry" ref="jobRegistry" ></property>	
    </bean>
    <bean id="jobRegistry" class="org.springframework.batch.core.configuration.support.MapJobRegistry" />
    webapp-config.xml
    Code:
    <import resource="classpath*:/bootstrap/*.xml"/>

    This is the controller
    Code:
    @Controller
    public class HomeController {
    
    	@Autowired
    	ListableJobLocator jobRegistry;
    	
    	@Autowired
    	JobLauncher jobLauncher;
    	
    	@Autowired
    	JobRepository jobRepository;
    	
    	@Autowired
    	JobLoader jobLoader;
    	private static final Logger logger = LoggerFactory
    			.getLogger(HomeController.class);
    	ApplicationContext ctx1 = new ClassPathXmlApplicationContext(
    			"/webapp-config.xml");
    
    	@RequestMapping(value = "/abc", method = RequestMethod.GET)
    	public String home(Locale locale, Model model) {
    		return "home";
    		}
    
    	@RequestMapping(value="uploadjob", method=RequestMethod.POST)
    	public @ResponseBody String upload(@RequestBody String job){
    		Collection<Job> jobs=jobLoader.reload(createContextFactory(job));
    		System.out.println(jobs);
    		return "Your Job has been submitted successfully :)";
    		
    	}
    
    	
    	@RequestMapping(value="launchjob/{jobName}")
    	public @ResponseBody String launch(@PathVariable("jobName") String jobName ) throws NoSuchJobException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException{
    		JobService jobService=new SimpleJobService(jobRegistry, jobLauncher, jobRepository);
    		jobService.launch(jobName, new JobParametersBuilder().toJobParameters());
    		return "Your Job is running";
    	}
    	
    	
    	
    	private ApplicationContextFactory createContextFactory(String job) {
    		Resource r=new ByteArrayResource(job.getBytes());
    		ClassPathXmlApplicationContextFactory acf=new ClassPathXmlApplicationContextFactory();
    		acf.setResource(r);
    		acf.setApplicationContext(ctx1);
    		return acf;
    	}
    }

    Code:
    public class SimpleJobService implements JobService {
    
    	ListableJobLocator jobLocator;
    	JobLauncher jobLauncher;
    	JobRepository jobRepository;
    	
    	
    	
    	public SimpleJobService(ListableJobLocator jobLocator,
    			JobLauncher jobLauncher, JobRepository jobRepository) {
    		super();
    		this.jobLocator = jobLocator;
    		this.jobLauncher = jobLauncher;
    		this.jobRepository = jobRepository;
    	}
    
    
    
    	@Override
    	public JobExecution launch(String jobName, JobParameters jobParameters) throws NoSuchJobException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException{
    
    		Job job = jobLocator.getJob(jobName);
    
    		JobExecution lastJobExecution = jobRepository.getLastJobExecution(
    				jobName, jobParameters);
    		boolean restart = false;
    		if (lastJobExecution != null) {
    			BatchStatus status = lastJobExecution.getStatus();
    			if (status.isUnsuccessful() && status != BatchStatus.ABANDONED) {
    				restart = true;
    			}
    		}
    
    		if (job.getJobParametersIncrementer() != null && !restart) {
    			jobParameters = job.getJobParametersIncrementer().getNext(
    					jobParameters);
    		}
    
    		JobExecution jobExecution = jobLauncher.run(job, jobParameters);
    		
    		return jobExecution;
    
    	}
    
    }
    Code:
    public interface JobService {
    
    	JobExecution launch(String jobName, JobParameters params) throws NoSuchJobException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException;
    }
    I am not yet launching the job; since the job is not being saved into the repository.

  4. #4
    Join Date
    Sep 2008
    Location
    Chicagoland, IL
    Posts
    366

    Default

    If you are not launching the job yet, why would it be in the repository? The repository consists of historical data only. If you are looking for something to store job instances to be executed in the future, that is a job registry.
    Michael Minella
    Spring Batch Lead
    Author - Pro Spring Batch
    http://www.michaelminella.com
    Twitter: @MichaelMinella

  5. #5

    Default

    Thank you so much. It is working now. The problem was in my concept. Nowhere else. Thanks a lot.

  6. #6

    Default

    Hi,
    jobRegistry is in memory. If jobRegistry is destroyed, all the future jobs are gone! ie. if admin stops or crashes, the jobs are gone.. only the jobs that were launched will be in repository. with a running state.
    The problem is when i start the admin again, and upload the job again, i get a JobExecutionAlreadyRunningException.
    So how should i handle this case?

    Thankyou.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •