AppInit.java
- /*
- * Copyright (c) 2002-2022, City of Paris
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice
- * and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice
- * and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * License 1.0
- */
- package fr.paris.lutece.portal.service.init;
- import java.io.FileInputStream;
- import java.io.FileWriter;
- import java.text.DateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Properties;
- import javax.servlet.ServletContext;
- import fr.paris.lutece.portal.service.admin.AdminAuthenticationService;
- import fr.paris.lutece.portal.service.admin.AdminUserService;
- import fr.paris.lutece.portal.service.content.ContentPostProcessorService;
- import fr.paris.lutece.portal.service.content.ContentService;
- import fr.paris.lutece.portal.service.daemon.AppDaemonService;
- import fr.paris.lutece.portal.service.database.AppConnectionService;
- import fr.paris.lutece.portal.service.datastore.CoreDataKeys;
- import fr.paris.lutece.portal.service.datastore.DatastoreService;
- import fr.paris.lutece.portal.service.fileimage.FileImageService;
- import fr.paris.lutece.portal.service.filter.FilterService;
- import fr.paris.lutece.portal.service.html.XmlTransformerCacheService;
- import fr.paris.lutece.portal.service.i18n.I18nService;
- import fr.paris.lutece.portal.service.mailinglist.AdminMailingListService;
- import fr.paris.lutece.portal.service.plugin.PluginService;
- import fr.paris.lutece.portal.service.portal.PortalService;
- import fr.paris.lutece.portal.service.search.IndexationService;
- import fr.paris.lutece.portal.service.security.SecurityService;
- import fr.paris.lutece.portal.service.servlet.ServletService;
- import fr.paris.lutece.portal.service.spring.SpringContextService;
- import fr.paris.lutece.portal.service.template.AppTemplateService;
- import fr.paris.lutece.portal.service.util.AppLogService;
- import fr.paris.lutece.portal.service.util.AppPathService;
- import fr.paris.lutece.portal.service.util.AppPropertiesService;
- import fr.paris.lutece.util.bean.BeanUtil;
- import fr.paris.lutece.util.html.HtmlTemplate;
- /**
- * This class initializes all the application services
- *
- * @since 1.1
- */
- public final class AppInit
- {
- private static final String PROPERTY_AUTOINIT = "autoInit";
- private static final String PROPERTY_INIT_WEBAPP_PROD_URL = "init.webapp.prod.url";
- private static final String PROPERTY_SENDMAIL_SUBJECT = "portal.system.log4j.sendmail.subject";
- private static final String PROPERTY_SITE_NAME = "lutece.name";
- private static final String MARK_WEBAPP_HOME = "webapp_home";
- private static final String MARK_PROD_URL = "lutece_prod_url";
- private static final String MARK_SENDMAIL_SUBJECT = "sendmail_subject";
- private static final String MARK_AUTOINIT = "autoinit";
- private static final String PATH_CONFIG = "/WEB-INF/conf/";
- private static final String FILE_PROPERTIES_CONFIG = "config.properties";
- private static final String FILE_PROPERTIES_DATABASE = "db.properties";
- private static final String PATH_TEMPLATES = "/WEB-INF/templates/";
- private static final String CONFIG_PROPERTIES_TEMPLATE = "admin/system/config_properties.html";
- private static boolean _bInitSuccessfull;
- private static String _strLoadingFailureCause;
- private static String _strLoadingFailureDetails;
- /**
- * Constructor
- */
- private AppInit( )
- {
- }
- /**
- * Initializes all the application services (used for junit tests)
- *
- * @param strConfPath
- * The relative path to the config files
- */
- public static void initServices( String strConfPath )
- {
- initServices( null, strConfPath, null );
- }
- /**
- * Initializes all the application services
- *
- * @param context
- * The servlet context
- * @param strConfPath
- * The relative path to the config files
- * @param strRealPath
- * The real path to the config files
- */
- public static void initServices( ServletContext context, String strConfPath, String strRealPath )
- {
- try
- {
- long lStart = System.currentTimeMillis( );
- Thread.currentThread( ).setName( "Lutece-MainThread" );
- // Initializes the properties download files containing the variables used by
- // the application
- AppPropertiesService.init( strConfPath );
- // Initializes the template services from the servlet context information
- AppTemplateService.init( PATH_TEMPLATES );
- // Initializes the Datastore Service
- DatastoreService.init( );
- if ( strRealPath != null )
- {
- // Initializes the properties download files containing the
- // variables used by the application
- initProperties( strRealPath );
- }
- AppLogService.info( " {} {} {} ...\n", AppInfo.LUTECE_BANNER_VERSION, "Starting version", AppInfo.getVersion( ) );
- // BeanUtil initialization, considering Lutèce availables locales and date
- // format properties
- BeanUtil.init( );
- // Initializes the connection pools
- AppConnectionService.init( strConfPath, FILE_PROPERTIES_DATABASE, "portal" );
- AppLogService.info( "Creating connexions pool 'portal'." );
-
- //Initializes early initialization services.
- StartUpServiceManager.initializeEarlyInitializationServices( );
- // Spring ApplicationContext initialization
- AppLogService.info( "Loading context files ..." );
- SpringContextService.init( context );
- // Initialize and run StartUp services
- AppLogService.info( "Running extra startup services ..." );
- StartUpServiceManager.init( );
- // XmlTransformer service cache manager
- XmlTransformerCacheService.init( );
- AdminMailingListService.init( );
- // Initializes Search Engine Indexation Service
- IndexationService.init( );
- // Initializes PluginService
- AppLogService.info( "Initializing plugins ..." );
- PluginService.init( );
- // Initializes FilterService and ServletService
- AppLogService.info( "Initializing plugins filters ..." );
- FilterService.init( context );
- AppLogService.info( "Initializing plugins servlets ..." );
- ServletService.init( context );
- // Trace Contents services loading
- traceContentServicesLoading( );
- // Initializes the SecurityService
- SecurityService.init( );
- // Initializes plugins autoincludes - needs to be launched before the daemons
- // (indexer could fail)
- AppTemplateService.initAutoIncludes( );
- // Initializes the daemons service
- AppDaemonService.init( );
- // Initializes the admin authentication module
- AdminAuthenticationService.init( );
- // Initialize FileImageService
- FileImageService.init( );
- // Initialize AdminUserService
- AdminUserService.init( );
- // Process post startup services
- AppLogService.info( "Running post startup services ..." );
- PostStartUpServiceManager.init( );
- // Initialize Content Post Processor Service
- ContentPostProcessorService.init( );
- _bInitSuccessfull = true;
- logStartupTime( );
- // Start datastore's cache after all processes that may use Datastore
- DatastoreService.startCache( );
- long lEnd = System.currentTimeMillis( );
- long lTime = 1 + ( lEnd - lStart ) / 1000;
- String strBaseUrl = getBaseUrl( context );
- StringBuilder sbBanner = new StringBuilder( );
- sbBanner.append( AppInfo.LUTECE_BANNER_SERVER ).append( " started successfully in " ).append( lTime ).append( "s !!!\n" )
- .append( "\n Front office " ).append( strBaseUrl ).append( AppPathService.getPortalUrl( ) ).append( "\n Back office " )
- .append( strBaseUrl ).append( AppPathService.getAdminMenuUrl( ) ).append( "\n" );
- AppLogService.info( sbBanner.toString( ) );
- }
- catch( LuteceInitException e )
- {
- _strLoadingFailureCause = e.getMessage( );
- Throwable cause = e.getCause( );
- while ( cause != null )
- {
- _strLoadingFailureDetails = cause.getMessage( );
- cause = cause.getCause( );
- }
- }
- }
- /**
- * Get a base url to display in start logs
- *
- * @param context
- * the servlet context
- * @return the base url
- */
- private static String getBaseUrl( ServletContext context )
- {
- StringBuilder sbBaseUrl = new StringBuilder( "http(s)://server:port" );
- if ( context != null )
- {
- sbBaseUrl.append( context.getContextPath( ) );
- }
- return sbBaseUrl.append( '/' ).toString( );
- }
- /**
- * Tells if Lutece Startup was successful
- *
- * @return True, if no error, otherwise false
- */
- public static boolean isWebappSuccessfullyLoaded( )
- {
- return _bInitSuccessfull;
- }
- /**
- * Returns the cause of the startup failure
- *
- * @return the cause of the startup failure
- */
- public static String getLoadingFailureCause( )
- {
- return _strLoadingFailureCause;
- }
- /**
- * Returns details of the startup failure
- *
- * @return details of the startup failure
- */
- public static String getLoadingFailureDetails( )
- {
- return _strLoadingFailureDetails;
- }
- /**
- * Traces Content Services loading
- */
- private static void traceContentServicesLoading( )
- {
- for ( ContentService cs : PortalService.getContentServicesList( ) )
- {
- AppLogService.info( "Content Service '{}' is loaded {} ", cs.getName( ), ( cs.isCacheEnable( ) ? " [ cache enable ] " : " [ cache disable ] " ) );
- }
- }
- /**
- * Initializes the config.properties file after first installation
- *
- * @param strRealPath
- * The real path to the configuration file
- */
- private static void initProperties( String strRealPath )
- {
- Map<String, Object> model = new HashMap<>( );
- Properties p = new Properties( );
- try ( FileInputStream fis = new FileInputStream( strRealPath + PATH_CONFIG + FILE_PROPERTIES_CONFIG ) )
- {
- p.load( fis );
- }
- catch( Exception e )
- {
- AppLogService.error( e.getMessage( ), e );
- }
- if ( Boolean.parseBoolean( p.getProperty( PROPERTY_AUTOINIT ) ) )
- {
- Object [ ] params = {
- AppPropertiesService.getProperty( PROPERTY_SITE_NAME )
- };
- String strSendMailSubject = I18nService.getLocalizedString( PROPERTY_SENDMAIL_SUBJECT, params, I18nService.getDefaultLocale( ) );
- model.put( MARK_SENDMAIL_SUBJECT, strSendMailSubject );
- model.put( MARK_WEBAPP_HOME, AppPathService.getWebAppPath( ) );
- model.put( MARK_PROD_URL, p.getProperty( PROPERTY_INIT_WEBAPP_PROD_URL ) );
- model.put( MARK_AUTOINIT, Boolean.FALSE.toString( ) );
- HtmlTemplate configTemplate = AppTemplateService.getTemplate( CONFIG_PROPERTIES_TEMPLATE, Locale.getDefault( ), model );
- // reset configuration cache to avoid configuration caching before macros are
- // set. See LUTECE-1460
- AppTemplateService.resetConfiguration( );
- try ( FileWriter fw = new FileWriter( strRealPath + PATH_CONFIG + FILE_PROPERTIES_CONFIG ) )
- {
- fw.write( configTemplate.getHtml( ) );
- }
- catch( Exception io )
- {
- AppLogService.error( "Error reading file", io );
- }
- }
- }
- /**
- * Log startup time.
- */
- private static void logStartupTime( )
- {
- String strStartupTime = DateFormat.getDateTimeInstance( ).format( new Date( ) );
- DatastoreService.setDataValue( CoreDataKeys.KEY_STARTUP_TIME, strStartupTime );
- }
- }