001/* 002 * #%L 003 * Netarchivesuite - wayback 004 * %% 005 * Copyright (C) 2005 - 2018 The Royal Danish Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.wayback.indexer; 024 025import org.hibernate.Session; 026import org.hibernate.SessionFactory; 027import org.hibernate.cfg.AnnotationConfiguration; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031import dk.netarkivet.common.utils.Settings; 032import dk.netarkivet.wayback.WaybackSettings; 033 034/** 035 * This class contains a single static utility method which returns a Hibernate session: HibernateUtil.getSession(). 036 * <p> 037 * The configuration for the session is read from settings.xml in the elements nested under settings/wayback/hibernate. 038 */ 039public class HibernateUtil { 040 041 /** Logger for this class. */ 042 private static final Logger log = LoggerFactory.getLogger(HibernateUtil.class); 043 044 /** Key indicating the connection provider to be used by hibernate. */ 045 private static final String CONNECTION_PROVIDER_CLASS = "connection.provider_class"; 046 047 /** 048 * Value indicating use of the c3p0 as connection provider. This is hard coded and no other connection providers 049 * have been tested. 050 */ 051 private static final String ORG_HIBERNATE_CONNECTION_C3_P0_CONNECTION_PROVIDER = "org.hibernate.connection.C3P0ConnectionProvider"; 052 053 // For documentation of these values see the corresponding constants in 054 // the WaybackSettings class 055 private static final String C3P0_ACQUIRE_INCREMENT = "c3p0.acquire_increment"; 056 private static final String C3P0_IDLE_TEST_PERIOD = "c3p0.idle_test_period"; 057 private static final String C3P0_MAX_SIZE = "c3p0.max_size"; 058 private static final String C3P0_MAX_STATEMENTS = "c3p0.max_statements"; 059 private static final String C3P0_MIN_SIZE = "c3p0.min_size"; 060 private static final String C3P0_TIMEOUT = "c3p0.timeout"; 061 private static final String HIBERNATE_CONNECTION_DRIVER_CLASS = "hibernate.connection.driver_class"; 062 private static final String HIBERNATE_CONNECTION_URL = "hibernate.connection.url"; 063 private static final String HIBERNATE_DIALECT = "hibernate.dialect"; 064 private static final String HIBERNATE_FORMAT_SQL = "hibernate.format_sql"; 065 private static final String HIBERNATE_BYTECODE_USE_REFLECTION_OPTIMIZER = "hibernate.bytecode.use_reflection_optimizer"; 066 private static final String HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto"; 067 private static final String HIBERNATE_TRANSACTION_FACTORY_CLASS = "hibernate.transaction.factory_class"; 068 private static final String HIBERNATE_SHOW_SQL = "hibernate.show_sql"; 069 private static final String HIBERNATE_CONNECTION_USERNAME = "hibernate.connection.username"; 070 private static final String HIBERNATE_CONNECTION_PASSWORD = "hibernate.connection.password"; 071 072 /** 073 * Private constructor as this class is never instantiated. 074 */ 075 private HibernateUtil() { 076 } 077 078 /** 079 * The session factory from which sessions are obtained. There is no accessor supplied for this factory as a 080 * reference to it can be obtained if necessary (e.g. during a cleanup operation) from the Session itself. 081 */ 082 private static SessionFactory sessionFactory; 083 084 /** 085 * Properties of the hibernate session are loaded from settings.xml. There is therefore no need for a separate 086 * hibernate configuration file. 087 */ 088 private static void initialiseFactory() { 089 if (sessionFactory == null || sessionFactory.isClosed()) { 090 try { 091 log.info("Initialisefactory process initiated"); 092 AnnotationConfiguration config = new AnnotationConfiguration(); 093 config.setProperty(CONNECTION_PROVIDER_CLASS, ORG_HIBERNATE_CONNECTION_C3_P0_CONNECTION_PROVIDER); 094 config.setProperty(C3P0_ACQUIRE_INCREMENT, Settings.get(WaybackSettings.C3P0_ACQUIRE_INCREMENT)); 095 config.setProperty(C3P0_IDLE_TEST_PERIOD, Settings.get(WaybackSettings.C3P0_IDLE_PERIOD)); 096 config.setProperty(C3P0_MAX_SIZE, Settings.get(WaybackSettings.C3P0_MAX_SIZE)); 097 config.setProperty(C3P0_MAX_STATEMENTS, Settings.get(WaybackSettings.C3P0_MAX_STATEMENTS)); 098 config.setProperty(C3P0_MIN_SIZE, Settings.get(WaybackSettings.C3P0_MIN_SIZE)); 099 config.setProperty(C3P0_TIMEOUT, Settings.get(WaybackSettings.C3P0_TIMEOUT)); 100 config.setProperty(HIBERNATE_CONNECTION_DRIVER_CLASS, Settings.get(WaybackSettings.HIBERNATE_DB_DRIVER)); 101 config.setProperty(HIBERNATE_CONNECTION_URL, Settings.get(WaybackSettings.HIBERNATE_DB_URL)); 102 config.setProperty(HIBERNATE_DIALECT, Settings.get(WaybackSettings.HIBERNATE_DIALECT)); 103 config.setProperty(HIBERNATE_FORMAT_SQL, Settings.get(WaybackSettings.HIBERNATE_FORMAT_SQL)); 104 config.setProperty(HIBERNATE_BYTECODE_USE_REFLECTION_OPTIMIZER, 105 Settings.get(WaybackSettings.HIBERNATE_REFLECTION_OPTIMIZER)); 106 config.setProperty(HIBERNATE_HBM2DDL_AUTO, Settings.get(WaybackSettings.HIBERNATE_HBM2DDL_AUTO)); 107 config.setProperty(HIBERNATE_TRANSACTION_FACTORY_CLASS, 108 Settings.get(WaybackSettings.HIBERNATE_TRANSACTION_FACTORY)); 109 config.setProperty(HIBERNATE_SHOW_SQL, Settings.get(WaybackSettings.HIBERNATE_SHOW_SQL)); 110 log.info("Hibernate properties used: " + CONNECTION_PROVIDER_CLASS + " = " 111 + ORG_HIBERNATE_CONNECTION_C3_P0_CONNECTION_PROVIDER + ", " + C3P0_ACQUIRE_INCREMENT + " = " 112 + Settings.get(WaybackSettings.C3P0_ACQUIRE_INCREMENT) + ", " + C3P0_IDLE_TEST_PERIOD + " = " 113 + Settings.get(WaybackSettings.C3P0_IDLE_PERIOD) + ", " + C3P0_MAX_SIZE + " = " 114 + Settings.get(WaybackSettings.C3P0_MAX_SIZE) + ", " + C3P0_MAX_STATEMENTS + " = " 115 + Settings.get(WaybackSettings.C3P0_MAX_STATEMENTS) + ", " + C3P0_MIN_SIZE + " = " 116 + Settings.get(WaybackSettings.C3P0_MIN_SIZE) + ", " + C3P0_TIMEOUT + " = " 117 + Settings.get(WaybackSettings.C3P0_TIMEOUT) + ", " + HIBERNATE_CONNECTION_DRIVER_CLASS + " = " 118 + Settings.get(WaybackSettings.HIBERNATE_DB_DRIVER) + ", " + HIBERNATE_CONNECTION_URL + " = " 119 + Settings.get(WaybackSettings.HIBERNATE_DB_URL) + ", " + HIBERNATE_DIALECT + " = " 120 + Settings.get(WaybackSettings.HIBERNATE_DIALECT) + ", " + HIBERNATE_FORMAT_SQL + " = " 121 + Settings.get(WaybackSettings.HIBERNATE_FORMAT_SQL) + ", " 122 + HIBERNATE_BYTECODE_USE_REFLECTION_OPTIMIZER + " = " 123 + Settings.get(WaybackSettings.HIBERNATE_REFLECTION_OPTIMIZER) + ", " + HIBERNATE_HBM2DDL_AUTO 124 + " = " + Settings.get(WaybackSettings.HIBERNATE_HBM2DDL_AUTO) + ", " 125 + HIBERNATE_TRANSACTION_FACTORY_CLASS + " = " 126 + Settings.get(WaybackSettings.HIBERNATE_TRANSACTION_FACTORY) + ", " + HIBERNATE_SHOW_SQL 127 + " = " + Settings.get(WaybackSettings.HIBERNATE_SHOW_SQL)); 128 129 // Specifically allow unset username/password for the database 130 // so that we can use database without authentication, e.g. in 131 // testing. 132 if (!Settings.get(WaybackSettings.HIBERNATE_USERNAME).isEmpty()) { 133 config.setProperty(HIBERNATE_CONNECTION_USERNAME, Settings.get(WaybackSettings.HIBERNATE_USERNAME)); 134 } 135 if (!Settings.get(WaybackSettings.HIBERNATE_PASSWORD).isEmpty()) { 136 config.setProperty(HIBERNATE_CONNECTION_PASSWORD, Settings.get(WaybackSettings.HIBERNATE_PASSWORD)); 137 } 138 config.addAnnotatedClass(ArchiveFile.class); 139 sessionFactory = config.buildSessionFactory(); 140 } catch (Throwable ex) { 141 log.error("Could not connect to hibernate object store - exiting", ex); 142 throw new IllegalStateException("Could not connect to hibernate object store - exiting", ex); 143 } 144 } 145 } 146 147 /** 148 * Get a hibernate session for communicating with the object store for the wayback indexer. This method has the side 149 * effect of creating and initialising a SessionFactory object if there is no current open SessionFactory. 150 * 151 * @return the above mentioned hibernate session. 152 */ 153 public static Session getSession() { 154 initialiseFactory(); 155 return sessionFactory.openSession(); 156 } 157 158}