cern.c2mon.server.history.dao.LoggerDAO.java Source code

Java tutorial

Introduction

Here is the source code for cern.c2mon.server.history.dao.LoggerDAO.java

Source

/******************************************************************************
 * Copyright (C) 2010-2016 CERN. All rights not expressly granted are reserved.
 *
 * This file is part of the CERN Control and Monitoring Platform 'C2MON'.
 * C2MON is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 3 of the license.
 *
 * C2MON 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 Lesser General Public License for
 * more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with C2MON. If not, see <http://www.gnu.org/licenses/>.
 *****************************************************************************/
package cern.c2mon.server.history.dao;

import java.util.List;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cern.c2mon.pmanager.IDBPersistenceHandler;
import cern.c2mon.pmanager.IFallback;
import cern.c2mon.pmanager.persistence.exception.IDBPersistenceException;
import cern.c2mon.server.history.mapper.LoggerMapper;

/**
 * Common DAO implementation for objects that need storing in a history table using
 * the fallback mechanism.
 *
 * @author Mark Brightwell
 *
 * @param <T>
 *          the object that is being logged in the history table
 */
public class LoggerDAO<T extends IFallback> implements IDBPersistenceHandler<T> {

    /**
     * Private class logger.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerDAO.class);

    /**
     * Maximum number of statements that will be executed in each SQL batch
     **/
    private static final int RECORDS_PER_BATCH = 500;

    /**
     * The iBatis factory used to acquire database sessions.
     */
    private SqlSessionFactory sqlSessionFactory;

    /**
     * Auto-commit mapper for single queries.
     */
    // private LoggerMapper<T> loggerMapper;

    /**
     * The mapper class name used for creating the batch logger mapper from the
     * session.
     */
    private Class<? extends LoggerMapper<T>> mapperInterface;

    /**
     * Information in order to identify the DB.
     */
    private String dbUrl;

    /**
     *
     * @param sqlSessionFactory
     * @param loggerMapper
     *          the auto-commit mapper for single queries/inserts
     * @param dbUrl
     *          only used for logging error messages
     * @throws ClassNotFoundException
     */
    public LoggerDAO(SqlSessionFactory sqlSessionFactory, String mapperInterface, String dbUrl)
            throws ClassNotFoundException {
        super();
        this.sqlSessionFactory = sqlSessionFactory;
        Class<?> tmpInterface = Class.forName(mapperInterface);
        if (LoggerMapper.class.isAssignableFrom(tmpInterface)) {
            this.mapperInterface = (Class<? extends LoggerMapper<T>>) tmpInterface;
        } else {
            throw new IllegalArgumentException(
                    "Unexpected class name passed to LoggerDAO constructor - unable to instantiate.");
        }
        this.dbUrl = dbUrl;
        // if (tmpInterface instanceof LoggerMapper) {
        // Class<? extends LoggerMapper> mappper = tmpInterface;
        // }
    }

    /**
     * Inserts into the database a set of rows containing the data coming in
     * several IFallback objects
     *
     * @param data
     *          List of IFallback object whose data has to be inserted in the DB
     * @throws IDBPersistenceException
     *           An exception is thrown in case an error occurs during the data
     *           insertion. The exception provides also the number of already
     *           committed objects
     */
    @SuppressWarnings("unchecked")
    // add generics to persistence manager
    public final void storeData(final List data) throws IDBPersistenceException {
        SqlSession session = null;
        int size = data.size();
        int commited = 0;
        T tag;

        try {
            // We use batch set of statements to improve performance
            session = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug("Obtained batch transacted SQL session (session: " + session.toString() + ")");
            }
            LoggerMapper<T> persistenceMapper = session.getMapper(mapperInterface);

            // Iterate through the list of DataTagCacheObjects to insert
            // them one by one
            for (int i = 0; i != size; i++) {
                if ((0 == i % RECORDS_PER_BATCH) && i > 0) {
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("storeData([Collection]) : Commiting rows for i=" + i);
                    }
                    session.commit();
                    commited = i;
                }

                if (data.get(i) != null) {
                    tag = (T) data.get(i);
                    if (LOGGER.isDebugEnabled()) {
                        LOGGER.debug("Logging object with ID: " + tag.getId());
                    }
                    persistenceMapper.insertLog(tag);
                }
            }
            // Commit the transaction
            session.commit();
            commited = size;
        } catch (PersistenceException e) {
            LOGGER.error("storeData([Collection]) : Error executing/closing prepared statement for " + data.size()
                    + " dataTags", e);
            try {
                if (session != null) {
                    session.rollback();
                }
            } catch (Exception sql) {
                LOGGER.error("storeData([Collection]) : Error rolling back transaction.", sql);
            }
            throw new IDBPersistenceException(e.getMessage(), commited);
        } finally {
            try {
                if (session != null) {
                    session.close();
                }
            } catch (Exception e) {
                LOGGER.error("storeData([Collection]) : Error closing session.", e);
            }
        }
    }

    @Override
    public String getDBInfo() {
        return "C2MON history account on DB with URL: " + dbUrl;
    }

    @Override
    public void storeData(IFallback object) throws IDBPersistenceException {
        SqlSession session = null;
        try {
            session = sqlSessionFactory.openSession();
            LoggerMapper<T> loggerMapper = session.getMapper(mapperInterface);
            loggerMapper.insertLog((T) object);
            session.commit();
        } catch (PersistenceException ex1) {
            String message = "Exception caught while persisting an object to the history";
            LOGGER.error(message, ex1);
            if (session != null)
                session.rollback();
            throw new IDBPersistenceException(message, ex1);
        } finally {
            if (session != null)
                session.close();
        }
    }

}