org.kuali.kfs.sys.context.SpringConfigurationConsistencyCheckTest.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.kfs.sys.context.SpringConfigurationConsistencyCheckTest.java

Source

/*
 * The Kuali Financial System, a comprehensive financial management system for higher education.
 * 
 * Copyright 2005-2014 The Kuali Foundation
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kuali.kfs.sys.context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.sys.ConfigureContext;
import org.kuali.kfs.sys.FinancialSystemModuleConfiguration;
import org.kuali.kfs.sys.batch.JobDescriptor;
import org.kuali.kfs.sys.batch.TriggerDescriptor;
import org.kuali.kfs.sys.batch.dataaccess.FiscalYearMaker;
import org.kuali.kfs.sys.batch.dataaccess.impl.FiscalYearMakerImpl;
import org.kuali.kfs.sys.service.impl.KfsModuleServiceImpl;
import org.kuali.kfs.sys.suite.AnnotationTestSuite;
import org.kuali.kfs.sys.suite.PreCommitSuite;
import org.kuali.rice.core.framework.persistence.dao.PlatformAwareDao;
import org.kuali.rice.core.framework.persistence.jdbc.dao.PlatformAwareDaoBaseJdbc;
import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
import org.kuali.rice.kns.lookup.Lookupable;
import org.kuali.rice.kns.lookup.LookupableHelperService;
import org.kuali.rice.krad.service.ModuleService;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;

@ConfigureContext
@AnnotationTestSuite(PreCommitSuite.class)
public class SpringConfigurationConsistencyCheckTest extends KualiTestBase {
    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
            .getLogger(SpringConfigurationConsistencyCheckTest.class);

    public void testAllLookupablesArePrototypes() throws Exception {
        List<String> failingBeans = new ArrayList<String>();

        Map<String, Lookupable> beans = SpringContext.getBeansOfType(Lookupable.class);
        Map<String, Lookupable> beans2 = SpringContext.getBeansOfType(Lookupable.class);

        for (String beanName : beans.keySet()) {
            BeanDefinition beanDef = SpringContext.applicationContext.getBeanFactory().getBeanDefinition(beanName);
            // skip entries in the rice import files or in testing files
            if (StringUtils.contains(beanDef.getResourceDescription(), "spring-kfs-imported-rice-beans.xml")
                    || StringUtils.contains(beanDef.getResourceDescription(), "-test.xml")) {
                continue;
            }
            if (ProxyUtils.getTargetIfProxied(beans.get(beanName))
                    .equals(ProxyUtils.getTargetIfProxied(beans2.get(beanName)))) {
                failingBeans.add("\n *** " + beanName + " is a singleton and should not be.");
            }
        }
        assertEquals("Beans Failing Non-Singleton check: " + failingBeans, 0, failingBeans.size());
    }

    public void testAllLookupableHelperServicesArePrototypes() throws Exception {
        List<String> failingBeans = new ArrayList<String>();

        Map<String, LookupableHelperService> beans = SpringContext.getBeansOfType(LookupableHelperService.class);
        Map<String, LookupableHelperService> beans2 = SpringContext.getBeansOfType(LookupableHelperService.class);

        for (String beanName : beans.keySet()) {
            BeanDefinition beanDef = SpringContext.applicationContext.getBeanFactory().getBeanDefinition(beanName);
            // skip entries in the rice import files or in testing files
            if (StringUtils.contains(beanDef.getResourceDescription(), "spring-kfs-imported-rice-beans.xml")
                    || StringUtils.contains(beanDef.getResourceDescription(), "-test.xml")) {
                continue;
            }
            if (ProxyUtils.getTargetIfProxied(beans.get(beanName))
                    .equals(ProxyUtils.getTargetIfProxied(beans2.get(beanName)))) {
                failingBeans.add("\n *** " + beanName + " is a singleton and should not be. ("
                        + beanDef.getResourceDescription() + ")");
            }
        }
        assertEquals("Beans Failing Non-Singleton check: " + failingBeans, 0, failingBeans.size());
    }

    public void testJobBeansReferencedInModuleDefinitions() throws Exception {
        // get all Job beans
        Map<String, JobDescriptor> jobs = SpringContext.getBeansOfType(JobDescriptor.class);
        Map<String, ModuleService> moduleServices = SpringContext.getBeansOfType(ModuleService.class);
        assertFalse("Jobs list must not be empty", jobs.isEmpty());
        assertFalse("Module list must not be empty", moduleServices.isEmpty());

        // build a list of all job names
        Set<String> jobNamesInBeans = jobs.keySet();
        Set<String> jobNamesInModules = new HashSet<String>();
        for (ModuleService m : moduleServices.values()) {
            jobNamesInModules.addAll(m.getModuleConfiguration().getJobNames());
        }

        Set<String> beansNotReferencedInModules = new HashSet<String>(jobNamesInBeans);
        beansNotReferencedInModules.removeAll(jobNamesInModules);
        Set<String> moduleJobsWithNoBeans = new HashSet<String>(jobNamesInModules);
        moduleJobsWithNoBeans.removeAll(jobNamesInBeans);

        assertEquals("All of the job definitions must be referenced in the module definitions.",
                Collections.emptySet(), beansNotReferencedInModules);
        assertEquals("All of the jobs in the module definitions must be defined in the Spring context.",
                Collections.emptySet(), moduleJobsWithNoBeans);
    }

    public void testTriggerBeansReferencedInModuleDefinitions() throws Exception {
        // get all Job beans
        Map<String, TriggerDescriptor> triggers = SpringContext.getBeansOfType(TriggerDescriptor.class);
        Map<String, ModuleService> moduleServices = SpringContext.getBeansOfType(ModuleService.class);
        assertFalse("Jobs list must not be empty", triggers.isEmpty());
        assertFalse("Module list must not be empty", moduleServices.isEmpty());

        // build a list of all job names
        Set<String> triggerNamesInBeans = triggers.keySet();
        Set<String> triggerNamesInModules = new HashSet<String>();
        for (ModuleService m : moduleServices.values()) {
            triggerNamesInModules.addAll(m.getModuleConfiguration().getTriggerNames());
        }
        Set<String> beansNotReferencedInModules = new HashSet<String>(triggerNamesInBeans);
        beansNotReferencedInModules.removeAll(triggerNamesInModules);
        Set<String> moduleTriggersWithNoBeans = new HashSet<String>(triggerNamesInModules);
        moduleTriggersWithNoBeans.removeAll(triggerNamesInBeans);

        assertEquals("All of the trigger definitions must be referenced in the module definitions.",
                Collections.emptySet(), beansNotReferencedInModules);
        assertEquals("All of the triggers in the module definitions must be defined in the Spring context.",
                Collections.emptySet(), moduleTriggersWithNoBeans);
    }

    // FY makers referenced in module definitions
    public void testFiscalYearMakerBeansReferencedInModuleDefinitions() throws Exception {
        // get all Job beans
        Map<String, FiscalYearMakerImpl> fiscalYearMakers = SpringContext.getBeansOfType(FiscalYearMakerImpl.class);
        Map<String, KfsModuleServiceImpl> moduleServices = SpringContext.getBeansOfType(KfsModuleServiceImpl.class);
        assertFalse("FiscalYearMaker list must not be empty", fiscalYearMakers.isEmpty());
        assertFalse("Module list must not be empty", moduleServices.isEmpty());

        // build a list of all job names
        Set<FiscalYearMakerImpl> fiscalYearMakerNamesInBeans = new HashSet<FiscalYearMakerImpl>();
        for (FiscalYearMakerImpl fym : fiscalYearMakers.values()) {
            fiscalYearMakerNamesInBeans.add((FiscalYearMakerImpl) ProxyUtils.getTargetIfProxied(fym));
        }
        Set<FiscalYearMakerImpl> fiscalYearMakerNamesInModules = new HashSet<FiscalYearMakerImpl>();
        for (KfsModuleServiceImpl m : moduleServices.values()) {
            if (m.getModuleConfiguration() instanceof FinancialSystemModuleConfiguration) {
                for (FiscalYearMaker fym : ((FinancialSystemModuleConfiguration) m.getModuleConfiguration())
                        .getFiscalYearMakers()) {
                    fiscalYearMakerNamesInModules.add((FiscalYearMakerImpl) ProxyUtils.getTargetIfProxied(fym));
                }
            } else {
                LOG.warn("Possible problem.  KFS Module service does not contain a KFS module configuration: " + m
                        + "\n Contains: " + m.getModuleConfiguration().getClass().getName());
            }
        }
        Set<FiscalYearMakerImpl> beansNotReferencedInModules = new HashSet<FiscalYearMakerImpl>(
                fiscalYearMakerNamesInBeans);
        beansNotReferencedInModules.removeAll(fiscalYearMakerNamesInModules);
        Set<FiscalYearMakerImpl> moduleFiscalYearMakersWithNoBeans = new HashSet<FiscalYearMakerImpl>(
                fiscalYearMakerNamesInModules);
        moduleFiscalYearMakersWithNoBeans.removeAll(fiscalYearMakerNamesInBeans);

        assertEquals("All of the FiscalYearMaker definitions must be referenced in the module definitions.",
                Collections.emptySet(), beansNotReferencedInModules);
        assertEquals("All of the FiscalYearMakers in the module definitions must be defined in the Spring context.",
                Collections.emptySet(), moduleFiscalYearMakersWithNoBeans);
    }

    public void testParentBeansShouldBeAbstract() {
        List<String> failingBeanNames = new ArrayList<String>();
        for (String beanName : SpringContext.applicationContext.getBeanDefinitionNames()) {
            BeanDefinition beanDef = SpringContext.applicationContext.getBeanFactory().getBeanDefinition(beanName);
            // skip entries in the rice import files or in testing files
            if (StringUtils.contains(beanDef.getResourceDescription(), "spring-kfs-imported-rice-beans.xml")
                    || StringUtils.contains(beanDef.getResourceDescription(), "-test.xml")) {
                continue;
            }
            if (beanName.endsWith("-parentBean") && !beanDef.isAbstract()) {
                failingBeanNames.add(beanName + " : " + beanDef.getResourceDescription() + "\n");
            }
        }
        assertEquals("The following parent beans are not defined as abstract:\n" + failingBeanNames, 0,
                failingBeanNames.size());
    }

    public void testServicesShouldHaveParentBeans() {
        List<String> failingBeanNames = new ArrayList<String>();
        for (String beanName : SpringContext.applicationContext.getBeanDefinitionNames()) {
            // skip testing mock beans
            if (StringUtils.containsIgnoreCase(beanName, "mock")) {
                continue;
            }
            BeanDefinition beanDef = SpringContext.applicationContext.getBeanFactory().getBeanDefinition(beanName);
            // skip entries in the rice import files or in testing files
            if (StringUtils.contains(beanDef.getResourceDescription(), "spring-kfs-imported-rice-beans.xml")
                    || StringUtils.contains(beanDef.getResourceDescription(), "-test.xml")) {
                continue;
            }
            String serviceClass = beanDef.getBeanClassName();
            if (StringUtils.contains(serviceClass, "service.impl") && //should be a service
                    !StringUtils.startsWith(serviceClass, "org.kuali.rice") && //let rice test their code
                    !beanDef.isAbstract()) { //abstract = parent

                try {
                    BeanDefinition parentBean = SpringContext.applicationContext.getBeanFactory()
                            .getBeanDefinition(beanName + "-parentBean");
                    String parentClass = parentBean.getBeanClassName();
                } catch (NoSuchBeanDefinitionException ex) {
                    failingBeanNames.add(beanName + " : " + beanDef.getResourceDescription() + "\n");
                }
            }
        }
        assertEquals("The following service beans do not have \"-parentBean\"s:\n" + failingBeanNames, 0,
                failingBeanNames.size());
    }

    // DAOs should extend from the xxxx class
    public void testDAOsShouldBeDAOs() throws Exception {
        List<String> failingBeanNames = new ArrayList<String>();
        for (String beanName : SpringContext.applicationContext.getBeanDefinitionNames()) {
            BeanDefinition beanDef = SpringContext.applicationContext.getBeanFactory().getBeanDefinition(beanName);
            // skip entries in the rice import files or in testing files
            if (StringUtils.contains(beanDef.getResourceDescription(), "spring-kfs-imported-rice-beans.xml")
                    || StringUtils.contains(beanDef.getResourceDescription(), "-test.xml")) {
                continue;
            }
            if (!beanDef.isAbstract()) {
                Object service = TestUtils.getUnproxiedService(beanName);
                if (beanName.endsWith("Dao") && !service.getClass().getName().endsWith("Proxy")
                        && !service.getClass().getName().startsWith("org.kuali.rice")) {
                    if (!(service instanceof PlatformAwareDao)) {
                        failingBeanNames.add(" *** FAIL: " + beanName + " does not implement PlatformAwareDao (is "
                                + service.getClass().getName() + ")\n" + " : " + beanDef.getResourceDescription()
                                + "\n");
                    }
                    if (!(service instanceof PlatformAwareDaoBaseOjb)
                            && !(service instanceof PlatformAwareDaoBaseJdbc)) {
                        failingBeanNames
                                .add(" *** FAIL: " + beanName + " does not extend PlatformAwareDaoBaseOjb/Jdbc (is "
                                        + service.getClass().getName() + ")\n" + " : "
                                        + beanDef.getResourceDescription() + "\n");
                    }
                }
            }
        }
        for (Map.Entry<String, PlatformAwareDao> dao : SpringContext.getBeansOfType(PlatformAwareDao.class)
                .entrySet()) {
            Object service = ProxyUtils.getTargetIfProxied(dao.getValue());
            if (!dao.getKey().endsWith("Dao") && !dao.getKey().endsWith("DaoBase")
                    && !service.getClass().getName().startsWith("org.kuali.rice")
                    && !FiscalYearMakerImpl.class.isAssignableFrom(service.getClass())) {
                failingBeanNames.add(" *** FAIL: Bean " + dao.getKey() + " implements PlatformAwareDao ("
                        + service.getClass().getName() + ") but its name does not end in 'Dao'\n");
            }
        }

        assertEquals("The following problems were detected in the DAO definitions:\n" + failingBeanNames, 0,
                failingBeanNames.size());
    }
}