/** * Copyright (C) 2015 Orange * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.francetelecom.clara.cloud.spring; import com.francetelecom.clara.cloud.commons.TechnicalException; import com.francetelecom.clara.cloud.model.DependantModelItem; import com.francetelecom.clara.cloud.model.TechnicalDeploymentTemplate; import com.francetelecom.clara.cloud.paas.activation.ActivationPlugin; import com.francetelecom.clara.cloud.paas.activation.ActivationStepEnum; import com.francetelecom.clara.cloud.paas.activation.v1.ActivationPluginStrategy; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.mock.jndi.SimpleNamingContextBuilder; import org.springframework.web.context.support.StandardServletEnvironment; import javax.naming.InitialContext; import javax.naming.NamingException; import java.io.IOException; import java.io.InputStream; import java.util.HashSet; import java.util.Properties; import java.util.Set; import static org.junit.Assert.*; public class PluginConfigurationIT { private static final Logger LOGGER = LoggerFactory.getLogger(PluginConfigurationIT.class); private static final Set<Class<?>> ignoredClasses = new HashSet<Class<?>>(); static { ignoredClasses.add(TechnicalDeploymentTemplate.class); //Deactivated subscriptions } /* * Initialize a JNDI repository with all props from propertiesFile */ private Properties initJndiValues(String propertiesFile) throws NamingException, IOException { InputStream propsStream = this.getClass().getClassLoader().getResourceAsStream(propertiesFile); assertNotNull("no property file found for " + propertiesFile, propsStream); Properties props = new Properties(); props.load(propsStream); SimpleNamingContextBuilder.emptyActivatedContextBuilder(); InitialContext initialContext = new InitialContext(); for (Object key : props.keySet()) { initialContext.bind((String) key, props.get(key)); } return props; } @Test public void should_not_found_any_dependant_model_item_without_active_plugin_in_production() throws Exception { String datacenter = System.getProperty("datacenter", "hudson"); initJndiValues("com/francetelecom/clara/cloud/commons/testconfigurations/credentials-" + datacenter + ".properties"); ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{ "classpath:/spring-config/application-context-plugins.xml", "classpath:/spring-config/datasources-hsqldb-context.xml", "classpath:/com/francetelecom/clara/cloud/commons/testconfigurations/mock-liquibase-context.xml", "classpath:/META-INF/spring/paas-activation-stubbed-context.xml", "classpath:/spring-config/mock-spring-authentication-manager-context.xml"}) { @Override protected ConfigurableEnvironment createEnvironment() { return new StandardServletEnvironment(); } }; ActivationPluginStrategy strategy = (ActivationPluginStrategy) context.getBean("pluginStrategy"); ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); provider.addIncludeFilter(new AssignableTypeFilter(DependantModelItem.class)); Set<BeanDefinition> findCandidateComponents = provider.findCandidateComponents("com/francetelecom/clara/cloud/model"); ActivationStepEnum[] steps = ActivationStepEnum.values(); Set<Class<?>> errorItems = new HashSet<Class<?>>(); for (BeanDefinition beanDefinition : findCandidateComponents) { ActivationPlugin foundPlugin = null; Class<?> testedClass = Class.forName(beanDefinition.getBeanClassName()); LOGGER.info("Lookin for a plugin handling {}", testedClass.getSimpleName()); for (ActivationStepEnum activationStepEnum : steps) { if (foundPlugin == null) { try { foundPlugin = strategy.getPlugin(testedClass, activationStepEnum); } catch (TechnicalException e) { //Ignore not found error } } } if (foundPlugin == null) { if (ignoredClasses.contains(testedClass)) { LOGGER.info("No plugin found for {} but ignored !", testedClass.getSimpleName()); } else { LOGGER.info("No plugin found for {}", testedClass.getSimpleName()); } errorItems.add(testedClass); } else { assertFalse(testedClass.getSimpleName() + " is ignored but a plugin has been found : " + foundPlugin.getClass().getSimpleName() + ".\nDid you activate new feature without refactoring this test specs ?", ignoredClasses.contains(testedClass)); LOGGER.info("Plugin found for {} : {}", testedClass.getSimpleName(), foundPlugin.getClass().getSimpleName()); } } errorItems.removeAll(ignoredClasses); assertTrue("No plugin found for some items " + errorItems.toString() + ".\nDid you miss some configuration in cloud-paas-webapp spring config?", errorItems.isEmpty()); } }