Forráskód Böngészése

fix startup issue with report service

Jason Rivard 8 éve
szülő
commit
f6e4a8b46b

+ 23 - 14
src/main/java/password/pwm/svc/report/ReportService.java

@@ -125,13 +125,6 @@ public class ReportService implements PwmService {
             return;
             return;
         }
         }
 
 
-        if (!pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.REPORTING_ENABLE)) {
-            LOGGER.debug(PwmConstants.REPORTING_SESSION_LABEL,"reporting module is not enabled, will remain closed");
-            status = STATUS.CLOSED;
-            executeCommand(ReportCommand.Clear);
-            return;
-        }
-
         try {
         try {
             userCacheService = new UserCacheService();
             userCacheService = new UserCacheService();
             userCacheService.init(pwmApplication);
             userCacheService.init(pwmApplication);
@@ -206,7 +199,8 @@ public class ReportService implements PwmService {
                         && reportStatus.getCurrentProcess() != ReportStatusInfo.ReportEngineProcess.SearchLDAP
                         && reportStatus.getCurrentProcess() != ReportStatusInfo.ReportEngineProcess.SearchLDAP
                         )
                         )
                 {
                 {
-                    executorService.submit(new ReadLDAPTask());
+                    executorService.execute(new ClearTask());
+                    executorService.execute(new ReadLDAPTask());
                     LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL,"submitted new ldap dredge task to executorService");
                     LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL,"submitted new ldap dredge task to executorService");
                 }
                 }
             }
             }
@@ -611,7 +605,7 @@ public class ReportService implements PwmService {
         }
         }
 
 
         private void updateRestingCacheData() {
         private void updateRestingCacheData() {
-            final long startTime = System.currentTimeMillis();
+            final Instant startTime = Instant.now();
             int examinedRecords = 0;
             int examinedRecords = 0;
 
 
             try (ClosableIterator<UserCacheRecord> iterator = iterator()) {
             try (ClosableIterator<UserCacheRecord> iterator = iterator()) {
@@ -630,18 +624,28 @@ public class ReportService implements PwmService {
 
 
                     if (TimeDuration.fromCurrent(lastLogOutputTime).isLongerThan(30, TimeUnit.SECONDS)) {
                     if (TimeDuration.fromCurrent(lastLogOutputTime).isLongerThan(30, TimeUnit.SECONDS)) {
                         final TimeDuration progressDuration = TimeDuration.fromCurrent(startTime);
                         final TimeDuration progressDuration = TimeDuration.fromCurrent(startTime);
-                        LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL,"cache review process in progress, examined " + examinedRecords
+                        LOGGER.trace(PwmConstants.REPORTING_SESSION_LABEL,
+                                "cache review process in progress, examined " + examinedRecords
                                 + " in " + progressDuration.asCompactString());
                                 + " in " + progressDuration.asCompactString());
                         lastLogOutputTime = Instant.now();
                         lastLogOutputTime = Instant.now();
                     }
                     }
                 }
                 }
                 final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
                 final TimeDuration totalTime = TimeDuration.fromCurrent(startTime);
                 LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL,
                 LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL,
-                        "completed cache review process of " + examinedRecords + " cached report records in " + totalTime.asCompactString());
+                        "completed cache review process of " + examinedRecords
+                                + " cached report records in " + totalTime.asCompactString());
             }
             }
         }
         }
     }
     }
 
 
+    private class DailyJobExecuteTask implements Runnable {
+        @Override
+        public void run() {
+            executorService.execute(new ClearTask());
+            executorService.execute(new ReadLDAPTask());
+        }
+    }
+
     private class InitializationTask implements Runnable {
     private class InitializationTask implements Runnable {
         @Override
         @Override
         public void run() {
         public void run() {
@@ -652,9 +656,14 @@ public class ReportService implements PwmService {
                 status = STATUS.CLOSED;
                 status = STATUS.CLOSED;
                 return;
                 return;
             }
             }
-            final long secondsUntilNextDredge = settings.getJobOffsetSeconds() + TimeDuration.fromCurrent(JavaHelper.nextZuluZeroTime()).getTotalSeconds();
-            executorService.scheduleAtFixedRate(new ReadLDAPTask(), secondsUntilNextDredge, TimeDuration.DAY.getTotalSeconds(), TimeUnit.SECONDS);
-            executorService.scheduleAtFixedRate(new RolloverTask(), secondsUntilNextDredge + 1, TimeDuration.DAY.getTotalSeconds(), TimeUnit.SECONDS);
+
+            final boolean reportingEnabled = pwmApplication.getConfig().readSettingAsBoolean(PwmSetting.REPORTING_ENABLE);
+            if (reportingEnabled) {
+                final Instant nextZuluZeroTime = JavaHelper.nextZuluZeroTime();
+                final long secondsUntilNextDredge = settings.getJobOffsetSeconds() + TimeDuration.fromCurrent(nextZuluZeroTime).getTotalSeconds();
+                executorService.scheduleAtFixedRate(new DailyJobExecuteTask(), secondsUntilNextDredge, TimeDuration.DAY.getTotalSeconds(), TimeUnit.SECONDS);
+                LOGGER.debug("scheduled daily execution, next task will be at " + nextZuluZeroTime.toString());
+            }
             executorService.submit(new RolloverTask());
             executorService.submit(new RolloverTask());
             executorService.submit(new ProcessWorkQueueTask());
             executorService.submit(new ProcessWorkQueueTask());
         }
         }

+ 6 - 5
src/main/java/password/pwm/svc/report/ReportSummaryData.java

@@ -43,6 +43,7 @@ import java.util.TreeMap;
 
 
 public class ReportSummaryData {
 public class ReportSummaryData {
     private static final long MS_DAY = TimeDuration.DAY.getTotalMilliseconds();
     private static final long MS_DAY = TimeDuration.DAY.getTotalMilliseconds();
+    private static BigInteger TWO = new BigInteger("2");
 
 
     private Instant meanCacheTime;
     private Instant meanCacheTime;
     private int totalUsers;
     private int totalUsers;
@@ -84,7 +85,7 @@ public class ReportSummaryData {
                 reportSummaryData.loginDays.put(day, 0);
                 reportSummaryData.loginDays.put(day, 0);
             }
             }
         }
         }
-        
+
         return reportSummaryData;
         return reportSummaryData;
     }
     }
 
 
@@ -266,7 +267,7 @@ public class ReportSummaryData {
         final BigInteger currentMillis = BigInteger.valueOf(meanCacheTime.toEpochMilli());
         final BigInteger currentMillis = BigInteger.valueOf(meanCacheTime.toEpochMilli());
         final BigInteger newMillis = BigInteger.valueOf(newTime.toEpochMilli());
         final BigInteger newMillis = BigInteger.valueOf(newTime.toEpochMilli());
         final BigInteger combinedMillis = currentMillis.add(newMillis);
         final BigInteger combinedMillis = currentMillis.add(newMillis);
-        final BigInteger halvedMillis = combinedMillis.divide(new BigInteger("2"));
+        final BigInteger halvedMillis = combinedMillis.divide(TWO);
         meanCacheTime = Instant.ofEpochMilli(halvedMillis.longValue());
         meanCacheTime = Instant.ofEpochMilli(halvedMillis.longValue());
     }
     }
 
 
@@ -274,17 +275,17 @@ public class ReportSummaryData {
         if (eventDate == null) {
         if (eventDate == null) {
             return 0;
             return 0;
         }
         }
-        
+
         final TimeDuration timeBoundary = new TimeDuration(0,timeWindow);
         final TimeDuration timeBoundary = new TimeDuration(0,timeWindow);
         final TimeDuration eventDifference = TimeDuration.fromCurrent(eventDate);
         final TimeDuration eventDifference = TimeDuration.fromCurrent(eventDate);
 
 
         if (timeWindow >= 0 && eventDate.isAfter(Instant.now()) && eventDifference.isShorterThan(timeBoundary)) {
         if (timeWindow >= 0 && eventDate.isAfter(Instant.now()) && eventDifference.isShorterThan(timeBoundary)) {
-                return adding ? 1 : -1;
+            return adding ? 1 : -1;
         }
         }
 
 
         if (timeWindow < 0 && eventDate.isBefore(Instant.now()) && eventDifference.isShorterThan(timeBoundary)) {
         if (timeWindow < 0 && eventDate.isBefore(Instant.now()) && eventDifference.isShorterThan(timeBoundary)) {
             return adding ? 1 : -1;
             return adding ? 1 : -1;
-        } 
+        }
 
 
         return 0;
         return 0;
     }
     }

+ 2 - 2
src/main/java/password/pwm/svc/stats/StatisticsManager.java

@@ -301,7 +301,7 @@ public class StatisticsManager implements PwmService {
             final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer";
             final String threadName = Helper.makeThreadName(pwmApplication, this.getClass()) + " timer";
             daemonTimer = new Timer(threadName, true);
             daemonTimer = new Timer(threadName, true);
             daemonTimer.schedule(new FlushTask(), 10 * 1000, DB_WRITE_FREQUENCY_MS);
             daemonTimer.schedule(new FlushTask(), 10 * 1000, DB_WRITE_FREQUENCY_MS);
-            daemonTimer.schedule(new NightlyTask(), JavaHelper.nextZuluZeroTime());
+            daemonTimer.schedule(new NightlyTask(), Date.from(JavaHelper.nextZuluZeroTime()));
         }
         }
 
 
         if (pwmApplication.getApplicationMode() == PwmApplicationMode.RUNNING) {
         if (pwmApplication.getApplicationMode() == PwmApplicationMode.RUNNING) {
@@ -391,7 +391,7 @@ public class StatisticsManager implements PwmService {
         public void run() {
         public void run() {
             writeDbValues();
             writeDbValues();
             resetDailyStats();
             resetDailyStats();
-            daemonTimer.schedule(new NightlyTask(), JavaHelper.nextZuluZeroTime());
+            daemonTimer.schedule(new NightlyTask(), Date.from(JavaHelper.nextZuluZeroTime()));
         }
         }
     }
     }
 
 

+ 2 - 2
src/main/resources/password/pwm/i18n/PwmSetting.properties

@@ -606,7 +606,7 @@ Setting_Description_recovery.response.writePreference=<p>Select the location whe
 Setting_Description_recovery.searchFilter=Add an LDAP search filter @PwmAppName@ uses to search for users during forgotten password recovery. The LDAP search filter must include each attribute in the <b>Forgotten Password User Search Form</b>.  @PwmAppName@ replaces tokens made of a form item name (such as <code>cn</code>) enclosed with a percent sign <code>%cn%</code> with values supplied by the user.<br><br>For example, if the <b>Activate User Form</b> included the attributes <code>cn</code> and <code>sn</code>, then this filter might be appropriate\:<br><br><code>(&amp;(objectClass\=person)(cn\=%cn%)(sn\=%sn%))</code><br><br>If this setting is left blank, @PwmAppName@ automatically generates a search filter based on the required items in the <b>Forgotten Password User Search Form</b>.
 Setting_Description_recovery.searchFilter=Add an LDAP search filter @PwmAppName@ uses to search for users during forgotten password recovery. The LDAP search filter must include each attribute in the <b>Forgotten Password User Search Form</b>.  @PwmAppName@ replaces tokens made of a form item name (such as <code>cn</code>) enclosed with a percent sign <code>%cn%</code> with values supplied by the user.<br><br>For example, if the <b>Activate User Form</b> included the attributes <code>cn</code> and <code>sn</code>, then this filter might be appropriate\:<br><br><code>(&amp;(objectClass\=person)(cn\=%cn%)(sn\=%sn%))</code><br><br>If this setting is left blank, @PwmAppName@ automatically generates a search filter based on the required items in the <b>Forgotten Password User Search Form</b>.
 Setting_Description_recovery.sendNewPassword.sendMethod=Select the method to send new password to users when the <b>Forgotten Password Success Action</b> is set to <b>Send new password</b>.
 Setting_Description_recovery.sendNewPassword.sendMethod=Select the method to send new password to users when the <b>Forgotten Password Success Action</b> is set to <b>Send new password</b>.
 Setting_Description_recovery.verificationMethods=Select the verification methods @PwmAppName@ uses during the forgotten password process.  The users must satisfy each option set to required.  The users can then select any of the remaining optional methods until they complete the minimum number of optional methods.<br/><br/>You can modify tthe names and a description shown to users for these methods by editing the display text keys for <code>Field_VerificationMethod[Method]</code> and <code>Description_VerificationMethod[Method]</code> where <code>[Method]</code> is the method type.
 Setting_Description_recovery.verificationMethods=Select the verification methods @PwmAppName@ uses during the forgotten password process.  The users must satisfy each option set to required.  The users can then select any of the remaining optional methods until they complete the minimum number of optional methods.<br/><br/>You can modify tthe names and a description shown to users for these methods by editing the display text keys for <code>Field_VerificationMethod[Method]</code> and <code>Description_VerificationMethod[Method]</code> where <code>[Method]</code> is the method type.
-Setting_Description_reporting.enable=Enable directory reporting.  When enabled, @PwmAppName@ maintains a local cache of user data and makes it available to the administrator.  Enabling this option requires additional disk space and possibly more Java heap memory, Test it on a test server before enabling this setting in a production environment.
+Setting_Description_reporting.enable=Enable daily reporting job.  When enabled, @PwmAppName@ will execute a daily report update job.  
 Setting_Description_reporting.job.intensity=Control the level of intensity of a reporting job execution.  Higher levels will complete the report job faster but cause more workload on @PwmAppName@ and the LDAP directory.
 Setting_Description_reporting.job.intensity=Control the level of intensity of a reporting job execution.  Higher levels will complete the report job faster but cause more workload on @PwmAppName@ and the LDAP directory.
 Setting_Description_reporting.job.timeOffset=Specify the number of seconds past midnight (GMT) when @PwmAppName@ processes the update job.  Setting this option to -1 disables the nightly job processor.
 Setting_Description_reporting.job.timeOffset=Specify the number of seconds past midnight (GMT) when @PwmAppName@ processes the update job.  Setting this option to -1 disables the nightly job processor.
 Setting_Description_reporting.ldap.maxQuerySize=Specify the maximum number of records read during a reporting query search.  Setting this value to a larger sizes requires more Java heap memory.
 Setting_Description_reporting.ldap.maxQuerySize=Specify the maximum number of records read during a reporting query search.  Setting this value to a larger sizes requires more Java heap memory.
@@ -1081,7 +1081,7 @@ Setting_Label_recovery.response.writePreference=Response Write Location
 Setting_Label_recovery.searchFilter=Forgotten Password User Search Filter
 Setting_Label_recovery.searchFilter=Forgotten Password User Search Filter
 Setting_Label_recovery.sendNewPassword.sendMethod=New Password Send Method
 Setting_Label_recovery.sendNewPassword.sendMethod=New Password Send Method
 Setting_Label_recovery.verificationMethods=Verification Methods
 Setting_Label_recovery.verificationMethods=Verification Methods
-Setting_Label_reporting.enable=Enable Directory Reporting
+Setting_Label_reporting.enable=Enable Daily Reporting Job
 Setting_Label_reporting.job.intensity=Reporting Job Intensity
 Setting_Label_reporting.job.intensity=Reporting Job Intensity
 Setting_Label_reporting.job.timeOffset=Reporting Job Time Offset
 Setting_Label_reporting.job.timeOffset=Reporting Job Time Offset
 Setting_Label_reporting.ldap.maxQuerySize=Maximum LDAP Query Size
 Setting_Label_reporting.ldap.maxQuerySize=Maximum LDAP Query Size

+ 6 - 9
src/main/webapp/WEB-INF/jsp/admin-analysis.jsp

@@ -64,7 +64,6 @@
         <%@ include file="fragment/admin-nav.jsp" %>
         <%@ include file="fragment/admin-nav.jsp" %>
         <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;"  data-dojo-props="doLayout: false, persist: true" id="analysis-topLevelTab">
         <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;"  data-dojo-props="doLayout: false, persist: true" id="analysis-topLevelTab">
             <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_DirectoryReporting" bundle="Admin"/>">
             <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_DirectoryReporting" bundle="Admin"/>">
-                <% if (analysis_pwmRequest.getConfig().readSettingAsBoolean(PwmSetting.REPORTING_ENABLE)) { %>
                 <div data-dojo-type="dijit.layout.ContentPane" title="<pwm:display key="Title_ReportEngineStatus" bundle="Admin"/>" class="tabContent">
                 <div data-dojo-type="dijit.layout.ContentPane" title="<pwm:display key="Title_ReportEngineStatus" bundle="Admin"/>" class="tabContent">
                     <table style="width:450px" id="statusTable">
                     <table style="width:450px" id="statusTable">
                         <tr><td><pwm:display key="Display_PleaseWait"/></td></tr>
                         <tr><td><pwm:display key="Display_PleaseWait"/></td></tr>
@@ -153,12 +152,6 @@
                         </script>
                         </script>
                     </pwm:script>
                     </pwm:script>
                 </div>
                 </div>
-                <% } else { %>
-                <div>
-                    <%= PwmError.ERROR_SERVICE_NOT_AVAILABLE.getLocalizedMessage(analysis_pwmRequest.getLocale(),
-                            analysis_pwmRequest.getConfig()) %>
-                </div>
-                <% } %>
             </div>
             </div>
             <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_EventStatistics" bundle="Admin"/>">
             <div data-dojo-type="dijit.layout.TabContainer" style="width: 100%; height: 100%;" data-dojo-props="doLayout: false, persist: true" title="<pwm:display key="Title_EventStatistics" bundle="Admin"/>">
                 <div data-dojo-type="dijit.layout.ContentPane" title="<pwm:display key="Title_RawStatistics" bundle="Admin"/>" class="tabContent">
                 <div data-dojo-type="dijit.layout.ContentPane" title="<pwm:display key="Title_RawStatistics" bundle="Admin"/>" class="tabContent">
@@ -255,11 +248,15 @@
                 dojoParser.parse('centerbody');
                 dojoParser.parse('centerbody');
                 ready(function(){
                 ready(function(){
                     registry.byId('statsChartSelect').set('value','<%=Statistic.PASSWORD_CHANGES%>');
                     registry.byId('statsChartSelect').set('value','<%=Statistic.PASSWORD_CHANGES%>');
+
                     setTimeout(function(){
                     setTimeout(function(){
                         refreshChart();
                         refreshChart();
                     },5*1000);
                     },5*1000);
-                    PWM_ADMIN.refreshReportDataSummary(5 * 1000);
-                    PWM_ADMIN.refreshReportDataStatus(5 * 1000);
+
+                    PWM_ADMIN.refreshReportDataSummary();
+                    PWM_ADMIN.refreshReportDataStatus();
+                    setInterval(function () { PWM_ADMIN.refreshReportDataSummary() }, 5 * 1000);
+                    setInterval(function () { PWM_ADMIN.refreshReportDataStatus() }, 5 * 1000);
                 });
                 });
 
 
                 <% for (final Statistic loopStat : Statistic.sortedValues(locale)) { %>
                 <% for (final Statistic loopStat : Statistic.sortedValues(locale)) { %>

+ 2 - 13
src/main/webapp/public/resources/js/admin.js

@@ -217,11 +217,7 @@ PWM_ADMIN.refreshReportDataGrid=function() {
 };
 };
 
 
 
 
-PWM_ADMIN.refreshReportDataStatus=function(refreshTime) {
-    var doRefresh = refreshTime
-        ? function(){setTimeout(function(){PWM_ADMIN.refreshReportDataStatus(refreshTime);},refreshTime);}
-        : function(){};
-
+PWM_ADMIN.refreshReportDataStatus=function() {
     var url = PWM_GLOBAL['url-context'] + "/private/admin";
     var url = PWM_GLOBAL['url-context'] + "/private/admin";
     url = PWM_MAIN.addParamToUrl(url, 'processAction','reportStatus');
     url = PWM_MAIN.addParamToUrl(url, 'processAction','reportStatus');
     var loadFunction = function(data) {
     var loadFunction = function(data) {
@@ -242,7 +238,6 @@ PWM_ADMIN.refreshReportDataStatus=function(refreshTime) {
         PWM_MAIN.getObject("reportStartButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Start');
         PWM_MAIN.getObject("reportStartButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Start');
         PWM_MAIN.getObject("reportStopButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Stop');
         PWM_MAIN.getObject("reportStopButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Stop');
         PWM_MAIN.getObject("reportClearButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Clear');
         PWM_MAIN.getObject("reportClearButton").disabled = !PWM_MAIN.JSLibrary.arrayContains(availableCommands,'Clear');
-        doRefresh();
     };
     };
     var errorFunction = function (error) {
     var errorFunction = function (error) {
         console.log('error during report status update: ' + error);
         console.log('error during report status update: ' + error);
@@ -250,12 +245,7 @@ PWM_ADMIN.refreshReportDataStatus=function(refreshTime) {
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET',errorFunction:errorFunction});
     PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET',errorFunction:errorFunction});
 };
 };
 
 
-PWM_ADMIN.refreshReportDataSummary=function(refreshTime) {
-    var doRefresh = refreshTime
-        ? function(){setTimeout(function(){PWM_ADMIN.refreshReportDataSummary(refreshTime);},refreshTime);}
-        : function(){};
-
-
+PWM_ADMIN.refreshReportDataSummary=function() {
     var url = PWM_GLOBAL['url-context'] + "/private/admin";
     var url = PWM_GLOBAL['url-context'] + "/private/admin";
     url = PWM_MAIN.addParamToUrl(url, 'processAction','reportSummary');
     url = PWM_MAIN.addParamToUrl(url, 'processAction','reportSummary');
 
 
@@ -268,7 +258,6 @@ PWM_ADMIN.refreshReportDataSummary=function(refreshTime) {
             }
             }
             PWM_MAIN.getObject('summaryTable').innerHTML = htmlTable;
             PWM_MAIN.getObject('summaryTable').innerHTML = htmlTable;
         }
         }
-        doRefresh();
     };
     };
     var errorFunction = function (error) {
     var errorFunction = function (error) {
         console.log('error during report status update: ' + error);
         console.log('error during report status update: ' + error);