/* * Copyright (c) 2010-2013 Evolveum * * 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.evolveum.midpoint.repo.sql.testing; import com.evolveum.midpoint.repo.sql.SqlRepositoryConfiguration; import com.evolveum.midpoint.repo.sql.SqlRepositoryFactory; import com.evolveum.midpoint.repo.sql.SqlRepositoryServiceImpl; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import org.apache.commons.lang.StringUtils; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * @author lazyman */ public class TestSqlRepositoryBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware { private static final Trace LOGGER = TraceManager.getTrace(TestSqlRepositoryBeanPostProcessor.class); private static final String TRUNCATE_FUNCTION = "cleanupTestDatabase"; private static final String TRUNCATE_PROCEDURE = "cleanupTestDatabaseProc"; private ApplicationContext context; @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ((bean instanceof SqlRepositoryFactory) || (bean instanceof SessionFactory) || (bean instanceof SqlRepositoryServiceImpl)) { LOGGER.info("Post process: " + bean.getClass().getName()); } if (!(bean instanceof SessionFactory)) { return bean; } LOGGER.info("Postprocessing session factory - removing everything from database if necessary."); TestSqlRepositoryFactory factory = context.getBean(TestSqlRepositoryFactory.class); //we'll attempt to drop database objects if configuration contains dropIfExists=true and embedded=false SqlRepositoryConfiguration config = factory.getSqlConfiguration(); if (!config.isDropIfExists() || config.isEmbedded()) { LOGGER.info("We're not deleting objects from DB, drop if exists=false or embedded=true."); return bean; } LOGGER.info("Deleting objects from database."); SessionFactory sessionFactory = (SessionFactory) bean; Session session = sessionFactory.openSession(); try { session.beginTransaction(); Query query; if (useProcedure(factory.getSqlConfiguration())) { LOGGER.info("Using truncate procedure."); query = session.createSQLQuery("{ call " + TRUNCATE_PROCEDURE + "() }"); query.executeUpdate(); } else { LOGGER.info("Using truncate function."); query = session.createSQLQuery("select " + TRUNCATE_FUNCTION + "();"); query.uniqueResult(); } session.getTransaction().commit(); } catch (Exception ex) { LOGGER.error("Couldn't cleanup database, reason: " + ex.getMessage(), ex); if (session != null && session.isOpen()) { Transaction transaction = session.getTransaction(); if (transaction != null && transaction.isActive()) { transaction.rollback(); } } throw new BeanInitializationException("Couldn't cleanup database, reason: " + ex.getMessage(), ex); } finally { if (session != null && session.isOpen()) { session.close(); } } return bean; } /** * This method decides whether function or procedure (oracle, ms sql server) * will be used to cleanup testing database. * * @param config * @return */ private boolean useProcedure(SqlRepositoryConfiguration config) { return StringUtils.containsIgnoreCase(config.getHibernateDialect(), "oracle") || StringUtils.containsIgnoreCase(config.getHibernateDialect(), "SQLServer"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; } }