com.webbfontaine.valuewebb.irms.impl.core.AbstractRuleHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.irms.impl.core.AbstractRuleHandler.java

Source

/*
 * Copyrights 2002-2011 Webb Fontaine
 * Developer: Sargis Harutyunyan
 * Date: 23/11/11
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */
package com.webbfontaine.valuewebb.irms.impl.core;

import com.webbfontaine.valuewebb.irms.core.RuleCallable;
import com.webbfontaine.valuewebb.irms.impl.core.event.DataEvent;
import com.webbfontaine.valuewebb.irms.repo.CriteriaRepository;
import com.webbfontaine.valuewebb.irms.repo.RuleTtRepository;
import com.webbfontaine.valuewebb.irms.utils.ConcurrentUtils;
import com.webbfontaine.valuewebb.model.TtGen;
import com.webbfontaine.valuewebb.model.irms.Criteria;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.time.StopWatch;
import org.jboss.seam.annotations.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PreDestroy;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public abstract class AbstractRuleHandler<T extends DataEvent> implements RuleHandler<T> {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRuleHandler.class);

    private static final int N_THREADS = 6;

    private CriteriaRepository criteriaRepository;

    private RuleTtRepository ruleTtRepository;

    private final ExecutorService executor = Executors.newFixedThreadPool(N_THREADS,
            new BasicThreadFactory.Builder().namingPattern("IrmsDataRuleHandler-%d")
                    .uncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                        @Override
                        public void uncaughtException(Thread t, Throwable e) {
                            LOGGER.error("", e);
                        }
                    }).build());

    protected final void doHandle(T event) {
        List<Criteria> rules = criteriaRepository.loadRules(event.getCriteriaType());

        if (notEmpty(rules)) {
            TtGen ttEntity = getTTEntity(event.getId()); // retrieve only if we have rules to run

            applyRule(ttEntity, event, rules);
        }
    }

    private void applyRule(TtGen ttEntity, T event, List<Criteria> rules) {
        for (Criteria criterion : rules) {
            try {
                RuleCallable<Object> runnable = createCallable(ttEntity, criterion, event);
                executor.submit(runnable);
            } catch (Exception e) {
                LOGGER.error("", e);
            }
        }
    }

    private TtGen getTTEntity(Long ttId) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        TtGen ttGen = ruleTtRepository.loadTT(ttId);

        stopWatch.stop();
        LOGGER.info("TT with id: {} and pds size {} loaded in {} milliseconds",
                new Object[] { ttId, ttGen.getPdsNbr(), stopWatch.getTime() });

        return ttGen;
    }

    private static boolean notEmpty(List<Criteria> rules) {
        return !rules.isEmpty();
    }

    @PreDestroy
    public void destroy() {
        LOGGER.info("Shutting down Irms Data rule handler executor, please wait...");
        ConcurrentUtils.shutdownExecutor(executor, 30L, TimeUnit.SECONDS);
    }

    @In(create = true)
    public void setCriteriaRepository(CriteriaRepository criteriaRepository) {
        this.criteriaRepository = criteriaRepository;
    }

    @In(create = true)
    public void setRuleTtRepository(RuleTtRepository ruleTtRepository) {
        this.ruleTtRepository = ruleTtRepository;
    }

    protected abstract RuleCallable<Object> createCallable(TtGen ttEntity, Criteria criterion, T event);

}