Announcement Announcement Module
Collapse
No announcement yet.
Which Class is responsible for saving the job metadata in repository? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    How is your repository configured? What is the value of the job String you are receiving?

    Comment


    • #3
      OK i am writing the complete configuration here.
      Attachment

      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.
      Attached Files

      Comment


      • #4
        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.

        Comment


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

          Comment


          • #6
            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.

            Comment


            • #7
              The only JobRegistry implementation we provide is a Map based JobRegistry, however you can implement that interface to store the jobs in a persistent way (using a database, file system, etc).

              Comment

              Working...
              X