com.github.jrrdev.mantisbtsync.core.jobs.JobIssuesConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for com.github.jrrdev.mantisbtsync.core.jobs.JobIssuesConfiguration.java

Source

/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2016 Jrard Devarulrajah
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.github.jrrdev.mantisbtsync.core.jobs;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.support.CompositeItemProcessor;
import org.springframework.batch.item.support.CompositeItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import biz.futureware.mantis.rpc.soap.client.IssueData;

import com.github.jrrdev.mantisbtsync.core.common.auth.PortalAuthManager;
import com.github.jrrdev.mantisbtsync.core.common.listener.CloseAuthManagerListener;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.beans.BugBean;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.beans.BugIdBean;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.listener.CacheEvictionListener;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.processors.IssuesProcessor;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.readers.OpenIssuesReader;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.readers.OtherIssuesReader;
import com.github.jrrdev.mantisbtsync.core.jobs.issues.tasklets.IssuesLastRunExtractorTasklet;

/**
 * Configuration for the jobs to sync MantisBT enumerations.
 * Several jobs are available :
 * - syncIssuesJob
 * - forceSyncIssuesJob
 * - fileSyncIssuesJob
 *
 * @author jrrdev
 *
 */
@Configuration
public class JobIssuesConfiguration {

    /**
     * Build the syncIssuesJob job. This job will update all modified issues which
     * are still marked as open is MantisBT or in the local DB. The update is perform
     * in differential mode since last successful execution of this job for the given project.
     *
     * Note that all issues related to a subproject are updated to.
     *
     * Parameters for this job are :
     *    - mantis.username
     *       MantisBT username. If anonymous access is used, should be an empty string.
     *  - mantis.password
     *     MantisBT password. If anonymous access is used, should be an empty string.
     *  - mantis.project_id
     *     The id of the project
     *
     * @param jobs
     *          Job build factory
     * @param issuesLastSuccessExtractorStep
     *          Step extracting the last succeful datetime of this job
     * @param openIssuesSyncStep
     *          Step syncing all modified issues which are still open in MantisBT
     * @param otherIssuesSyncStep
     *          Step syncing all issues which are still open in the local DB
     * @param authIssuesStep
     *          Step for portal authentication at the begining of the job
     * @param closeIssuesListener
     *          Listener for closing the portal authentication connection at the end of the job
     * @return the job
     */
    @Bean
    public Job syncIssuesJob(final JobBuilderFactory jobs, final Step issuesLastSuccessExtractorStep,
            final Step openIssuesSyncStep, final Step otherIssuesSyncStep, final Step authIssuesStep,
            final CloseAuthManagerListener closeIssuesListener) {

        return jobs.get("syncIssuesJob").incrementer(new RunIdIncrementer()).listener(closeIssuesListener)
                .flow(authIssuesStep).next(issuesLastSuccessExtractorStep).next(openIssuesSyncStep)
                .next(otherIssuesSyncStep).end().build();
    }

    /**
     * Build the forceSyncIssuesJob job. This job will update all issues for which
     * the id is passed as job parameter.
     *
     *
     * Parameters for this job are :
     *    - mantis.username
     *       MantisBT username. If anonymous access is used, should be an empty string.
     *  - mantis.password
     *     MantisBT password. If anonymous access is used, should be an empty string.
     *  - mantis.issues_id
     *     Semi-colon separated list of issues ids
     *
     * @param jobs
     *          Job build factory
     * @param authIssuesStep
     *          Step for portal authentication at the begining of the job
     * @param closeIssuesListener
     *          Listener for closing the portal authentication connection at the end of the job
     * @param forceIssuesSyncStep
     *          Step syncing all issues matching the given ids
     * @return the job
     */
    @Bean
    public Job forceSyncIssuesJob(final JobBuilderFactory jobs, final Step authIssuesStep,
            final CloseAuthManagerListener closeIssuesListener, final Step forceIssuesSyncStep) {

        return jobs.get("forceSyncIssuesJob").incrementer(new RunIdIncrementer()).listener(closeIssuesListener)
                .flow(authIssuesStep).next(forceIssuesSyncStep).end().build();
    }

    /**
     * Build the fileSyncIssuesJob job. This job will update all issues matching a list
     * of ids contains in a CSV file.
     * The CSV file must not have a header line for columns definition.
     * The file is loaded through Spring resource loader so the filepath can contains
     * definitions like classpath: and others.
     *
     * Parameters for this job are :
     *    - mantis.username
     *       MantisBT username. If anonymous access is used, should be an empty string.
     *  - mantis.password
     *     MantisBT password. If anonymous access is used, should be an empty string.
     *  - mantis.filepath
     *     File path of the CSV file
     *
     * @param jobs
     *          Job build factory
     * @param authIssuesStep
     *          Step for portal authentication at the begining of the job
     * @param closeIssuesListener
     *          Listener for closing the portal authentication connection at the end of the job
     * @param fileIssuesSyncStep
     *          Step syncing all issues matching the given ids
     * @return the job
     */
    @Bean
    public Job fileSyncIssuesJob(final JobBuilderFactory jobs, final Step authIssuesStep,
            final CloseAuthManagerListener closeIssuesListener, final Step fileIssuesSyncStep) {

        return jobs.get("fileSyncIssuesJob").incrementer(new RunIdIncrementer()).listener(closeIssuesListener)
                .flow(authIssuesStep).next(fileIssuesSyncStep).end().build();
    }

    /**
     * Build the listener for closing the portal authentication connection at the end of the job.
     *
     * @param authManager
     *          The portal auth manager
     * @return the listener
     */
    @Bean
    public CloseAuthManagerListener closeIssuesListener(final PortalAuthManager authManager) {
        final CloseAuthManagerListener listener = new CloseAuthManagerListener();
        listener.setMgr(authManager);
        return listener;
    }

    /**
     * Build the step for portal authentication at the begining of the job.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param authTasklet
     *          The tasklet performing the authentication
     * @return the step
     */
    @Bean
    public Step authIssuesStep(final StepBuilderFactory stepBuilderFactory,
            final MethodInvokingTaskletAdapter authTasklet) {

        return stepBuilderFactory.get("authIssuesStep").allowStartIfComplete(true).tasklet(authTasklet).build();
    }

    /**
     * Build the step extracting the last succeful datetime of this job.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param mantisLastRunExtractorTasklet
     *          The tasklet getting the last successful start time of the job
     * @param mantisLastRunExtractorPromotionListener
     *          The execution context promotion listener that promotes
     *          mantis.update.last_job_run and mantis.update.current_job_run to the job context.
     * @return the step
     */
    @Bean
    public Step issuesLastSuccessExtractorStep(final StepBuilderFactory stepBuilderFactory,
            final IssuesLastRunExtractorTasklet mantisLastRunExtractorTasklet,
            final StepExecutionListener mantisLastRunExtractorPromotionListener) {

        return stepBuilderFactory.get("issuesLastSuccessExtractorStep").tasklet(mantisLastRunExtractorTasklet)
                .listener(mantisLastRunExtractorPromotionListener).build();
    }

    /**
     * The step syncing all modified issues which are still open in MantisBT.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param openIssuesReader
     *          The reader
     * @param issuesProcessor
     *          The processor
     * @param compositeIssuesWriter
     *          The writer
     * @param cacheEvictionListener
     *          Listener for caches eviction if the step fails
     * @return
     */
    @Bean
    public Step openIssuesSyncStep(final StepBuilderFactory stepBuilderFactory,
            final OpenIssuesReader openIssuesReader, final IssuesProcessor issuesProcessor,
            final CompositeItemWriter<BugBean> compositeIssuesWriter,
            final CacheEvictionListener cacheEvictionListener) {

        return stepBuilderFactory.get("openIssuesSyncStep").<IssueData, BugBean>chunk(10).reader(openIssuesReader)
                .processor(issuesProcessor).writer(compositeIssuesWriter).listener(cacheEvictionListener).build();
    }

    /**
     * Build the step syncing all issues which are still open in the local DB.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param otherIssuesReader
     *          The reader
     * @param issuesProcessor
     *          The processor
     * @param compositeIssuesWriter
     *          The writer
     * @param cacheEvictionListener
     *          Listener for caches eviction if the step fails
     * @return
     */
    @Bean
    public Step otherIssuesSyncStep(final StepBuilderFactory stepBuilderFactory,
            final OtherIssuesReader otherIssuesReader, final IssuesProcessor issuesProcessor,
            final CompositeItemWriter<BugBean> compositeIssuesWriter,
            final CacheEvictionListener cacheEvictionListener) {

        return stepBuilderFactory.get("otherIssuesSyncStep").<IssueData, BugBean>chunk(10).reader(otherIssuesReader)
                .processor(issuesProcessor).writer(compositeIssuesWriter).listener(cacheEvictionListener).build();
    }

    /**
     * The step syncing all issues matching the given ids.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param listIssuesReader
     *          The reader
     * @param compositeIssuesProcessor
     *          The processor
     * @param compositeIssuesWriter
     *          The writer
     * @param cacheEvictionListener
     *          Listener for caches eviction if the step fails
     * @return
     */
    @Bean
    public Step forceIssuesSyncStep(final StepBuilderFactory stepBuilderFactory,
            final ListItemReader<BugIdBean> listIssuesReader,
            final CompositeItemProcessor<BugIdBean, BugBean> compositeIssuesProcessor,
            final CompositeItemWriter<BugBean> compositeIssuesWriter,
            final CacheEvictionListener cacheEvictionListener) {

        return stepBuilderFactory.get("forceIssuesSyncStep").<BugIdBean, BugBean>chunk(10).reader(listIssuesReader)
                .processor(compositeIssuesProcessor).writer(compositeIssuesWriter).listener(cacheEvictionListener)
                .build();
    }

    /**
     * The step syncing all issues matching the given ids.
     *
     * @param stepBuilderFactory
     *          The step builder factory
     * @param csvIssuesReader
     *          The reader
     * @param compositeIssuesProcessor
     *          The processor
     * @param compositeIssuesWriter
     *          The writer
     * @param cacheEvictionListener
     *          Listener for caches eviction if the step fails
     * @return
     */
    @Bean
    public Step fileIssuesSyncStep(final StepBuilderFactory stepBuilderFactory,
            final FlatFileItemReader<BugIdBean> csvIssuesReader,
            final CompositeItemProcessor<BugIdBean, BugBean> compositeIssuesProcessor,
            final CompositeItemWriter<BugBean> compositeIssuesWriter,
            final CacheEvictionListener cacheEvictionListener) {

        return stepBuilderFactory.get("fileIssuesSyncStep").<BugIdBean, BugBean>chunk(10).reader(csvIssuesReader)
                .processor(compositeIssuesProcessor).writer(compositeIssuesWriter).listener(cacheEvictionListener)
                .build();
    }

    /**
     * Build the listener for caches eviction if the step fails.
     *
     * @return the listener
     */
    @Bean
    public CacheEvictionListener cacheEvictionListener() {
        return new CacheEvictionListener();
    }
}