View Javadoc
1   /*
2    * Copyright (c) 2002-2021, City of Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.plugins.importexport.service.export.daemon;
35  
36  import fr.paris.lutece.plugins.importexport.business.export.AutomaticExportConfig;
37  import fr.paris.lutece.plugins.importexport.business.export.IAutomaticExportConfigDAO;
38  import fr.paris.lutece.plugins.importexport.service.export.ExportManager;
39  import fr.paris.lutece.portal.service.daemon.Daemon;
40  import fr.paris.lutece.portal.service.datastore.DatastoreService;
41  import fr.paris.lutece.portal.service.spring.SpringContextService;
42  import fr.paris.lutece.portal.service.util.AppLogService;
43  import fr.paris.lutece.portal.service.util.AppPropertiesService;
44  
45  import java.util.Date;
46  import java.util.List;
47  
48  import org.apache.commons.lang3.StringUtils;
49  
50  /**
51   * Daemon to automatically export data from the database into files
52   */
53  public class ExportDaemon extends Daemon
54  {
55      private static final String PARAMETER_KEY_DAEMON_NEXT_SCHEDULE = "importexport.exportDaemon.daemonNextSchedule";
56      private static final String PARAMETER_KEY_DAEMON_INTERVAL = "importexport.exportDaemon.daemonInterval";
57  
58      private static final String PROPERTY_EXPORT_FOLDER = "importexport.exportDaemon.exportFolder";
59  
60      private static final String CONSTANT_DEFAULT_DAEMON_INTERVAL = "86400000";
61      private static final String CONSTANT_SLASH = "/";
62  
63      private IAutomaticExportConfigDAO _configDAO;
64  
65      /**
66       * {@inheritDoc}
67       */
68      @Override
69      public void run( )
70      {
71          String strNextSchedule = DatastoreService.getInstanceDataValue( PARAMETER_KEY_DAEMON_NEXT_SCHEDULE, StringUtils.EMPTY );
72          if ( StringUtils.isNotEmpty( strNextSchedule ) && StringUtils.isNumeric( strNextSchedule ) )
73          {
74              long lNextSchedule = Long.parseLong( strNextSchedule );
75              // If the time of the next schedule has passed, we run the exports
76              if ( lNextSchedule < new Date( ).getTime( ) )
77              {
78                  doExportData( );
79                  // We update the next schedule
80                  lNextSchedule = new Date( ).getTime( ) + Long.parseLong( getDaemonInterval( ) );
81                  DatastoreService.setInstanceDataValue( PARAMETER_KEY_DAEMON_NEXT_SCHEDULE, Long.toString( lNextSchedule ) );
82              }
83          }
84          else
85          {
86              String strDaemonInterval = getDaemonInterval( );
87              // We compute the next schedule from the current date plus the interval, and save it into the datastore
88              long lNextSchedule = new Date( ).getTime( ) + Long.parseLong( strDaemonInterval );
89              DatastoreService.setInstanceDataValue( PARAMETER_KEY_DAEMON_NEXT_SCHEDULE, Long.toString( lNextSchedule ) );
90          }
91      }
92  
93      /**
94       * Do export data from the database into files in the file system
95       */
96      private void doExportData( )
97      {
98          List<AutomaticExportConfig> listConfig = getAutomaticExportConfigDAO( ).findAll( true );
99          String strExportFolder = AppPropertiesService.getProperty( PROPERTY_EXPORT_FOLDER );
100         if ( strExportFolder != null && !strExportFolder.endsWith( CONSTANT_SLASH ) )
101         {
102             strExportFolder = strExportFolder + CONSTANT_SLASH;
103         }
104         int nExportSuccess = 0;
105         for ( AutomaticExportConfig config : listConfig )
106         {
107             try
108             {
109                 boolean bRes = ExportManager.doProcessExportIntoFile( strExportFolder + config.getOutputFileName( ), config.getTableName( ),
110                         config.getListColumns( ), config.getXslStylesheetId( ), config.getPlugin( ) );
111                 if ( bRes )
112                 {
113                     nExportSuccess++;
114                 }
115                 else
116                 {
117                     AppLogService
118                             .error( "The file '" + config.getOutputFileName( ) + "' was NOT filled with data of the table '" + config.getTableName( ) + "'" );
119                 }
120             }
121             catch( Exception e )
122             {
123                 AppLogService.error( e.getMessage( ), e );
124             }
125         }
126         setLastRunLogs( nExportSuccess + " out of " + listConfig.size( ) + " exports have been performed" );
127     }
128 
129     /**
130      * Get the IAutomaticExportConfigDAO
131      * 
132      * @return The IAutomaticExportConfigDAO
133      */
134     private IAutomaticExportConfigDAO getAutomaticExportConfigDAO( )
135     {
136         if ( _configDAO == null )
137         {
138             _configDAO = SpringContextService.getBean( ExportManager.BEAN_NAME_AUTOMATIC_EXPORT_CONFIG_DAO );
139         }
140         return _configDAO;
141     }
142 
143     /**
144      * Get the next scheduled export
145      * 
146      * @return A string describing the next scheduled export, in milliseconds format. The string may be null or empty if there is no next schedule
147      */
148     public static String getDaemonNextSchedule( )
149     {
150         return DatastoreService.getInstanceDataValue( PARAMETER_KEY_DAEMON_NEXT_SCHEDULE, StringUtils.EMPTY );
151     }
152 
153     /**
154      * Set the next schedule of the daemon
155      * 
156      * @param dateNextSchedule
157      *            The next schedule of the daemon
158      */
159     public static void setDaemonNextSchedule( Date dateNextSchedule )
160     {
161         if ( dateNextSchedule != null )
162         {
163             setDaemonNextSchedule( dateNextSchedule.getTime( ) );
164         }
165     }
166 
167     /**
168      * Set the next schedule of the daemon
169      * 
170      * @param lNextSchedule
171      *            The next schedule of the daemon in milliseconds
172      */
173     public static void setDaemonNextSchedule( long lNextSchedule )
174     {
175         DatastoreService.setInstanceDataValue( PARAMETER_KEY_DAEMON_NEXT_SCHEDULE, Long.toString( lNextSchedule ) );
176     }
177 
178     /**
179      * Get the interval of time between exports
180      * 
181      * @return The interval of time between exports. The returned value is assured o be a parsable long
182      */
183     public static String getDaemonInterval( )
184     {
185         String strDaemonInterval = DatastoreService.getInstanceDataValue( PARAMETER_KEY_DAEMON_INTERVAL, CONSTANT_DEFAULT_DAEMON_INTERVAL );
186         if ( strDaemonInterval == null || !StringUtils.isNumeric( strDaemonInterval ) )
187         {
188             // If the value retrieved is null or not numeric, we restore the default value
189             strDaemonInterval = CONSTANT_DEFAULT_DAEMON_INTERVAL;
190             DatastoreService.setInstanceDataValue( PARAMETER_KEY_DAEMON_INTERVAL, strDaemonInterval );
191         }
192         return strDaemonInterval;
193     }
194 
195     /**
196      * Set the interval of time between exports
197      * 
198      * @param lInterval
199      *            The interval of time between exports
200      */
201     public static void setDaemonInterval( long lInterval )
202     {
203         DatastoreService.setInstanceDataValue( PARAMETER_KEY_DAEMON_INTERVAL, Long.toString( lInterval ) );
204     }
205 }