Browse Source

eps statistics refactoring

Jason Rivard 7 years ago
parent
commit
05d55c70a0
23 changed files with 241 additions and 163 deletions
  1. 1 0
      server/src/main/java/password/pwm/AppProperty.java
  2. 6 0
      server/src/main/java/password/pwm/http/HttpEventManager.java
  3. 5 1
      server/src/main/java/password/pwm/http/PwmRequest.java
  4. 3 0
      server/src/main/java/password/pwm/http/filter/ObsoleteUrlFilter.java
  5. 7 0
      server/src/main/java/password/pwm/http/filter/RequestInitializationFilter.java
  6. 2 1
      server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java
  7. 24 0
      server/src/main/java/password/pwm/http/servlet/admin/AdminServlet.java
  8. 12 12
      server/src/main/java/password/pwm/http/servlet/resource/ResourceServletService.java
  9. 2 1
      server/src/main/java/password/pwm/ldap/auth/LDAPAuthenticationRequest.java
  10. 2 1
      server/src/main/java/password/pwm/svc/intruder/IntruderManager.java
  11. 34 0
      server/src/main/java/password/pwm/svc/stats/EpsStatistic.java
  12. 0 26
      server/src/main/java/password/pwm/svc/stats/Statistic.java
  13. 6 6
      server/src/main/java/password/pwm/svc/stats/StatisticsManager.java
  14. 3 3
      server/src/main/java/password/pwm/util/db/DatabaseService.java
  15. 8 0
      server/src/main/java/password/pwm/util/java/JavaHelper.java
  16. 12 0
      server/src/main/java/password/pwm/util/java/StringUtil.java
  17. 3 3
      server/src/main/java/password/pwm/util/localdb/LocalDBAdaptor.java
  18. 3 2
      server/src/main/java/password/pwm/util/operations/PasswordUtility.java
  19. 9 6
      server/src/main/java/password/pwm/ws/server/rest/RestStatisticsServer.java
  20. 1 0
      server/src/main/resources/password/pwm/AppProperty.properties
  21. 9 7
      server/src/main/resources/password/pwm/i18n/Admin.properties
  22. 3 2
      server/src/main/webapp/WEB-INF/jsp/admin-dashboard.jsp
  23. 86 92
      server/src/main/webapp/public/resources/js/admin.js

+ 1 - 0
server/src/main/java/password/pwm/AppProperty.java

@@ -88,6 +88,7 @@ public enum AppProperty {
     HTTP_RESOURCES_MAX_CACHE_BYTES                  ("http.resources.maxCacheBytes"),
     HTTP_RESOURCES_MAX_CACHE_BYTES                  ("http.resources.maxCacheBytes"),
     HTTP_RESOURCES_EXPIRATION_SECONDS               ("http.resources.expirationSeconds"),
     HTTP_RESOURCES_EXPIRATION_SECONDS               ("http.resources.expirationSeconds"),
     HTTP_RESOURCES_ENABLE_GZIP                      ("http.resources.gzip.enable"),
     HTTP_RESOURCES_ENABLE_GZIP                      ("http.resources.gzip.enable"),
+    HTTP_RESOURCES_PATH_NONCE_LENGTH                ("http.resources.pathNonce.length"),
     HTTP_RESOURCES_ENABLE_PATH_NONCE                ("http.resources.pathNonceEnable"),
     HTTP_RESOURCES_ENABLE_PATH_NONCE                ("http.resources.pathNonceEnable"),
     HTTP_RESOURCES_NONCE_PATH_PREFIX                ("http.resources.pathNoncePrefix"),
     HTTP_RESOURCES_NONCE_PATH_PREFIX                ("http.resources.pathNoncePrefix"),
     HTTP_RESOURCES_ZIP_FILES                        ("http.resources.zipFiles"),
     HTTP_RESOURCES_ZIP_FILES                        ("http.resources.zipFiles"),

+ 6 - 0
server/src/main/java/password/pwm/http/HttpEventManager.java

@@ -25,6 +25,7 @@ package password.pwm.http;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
 import password.pwm.PwmConstants;
 import password.pwm.PwmConstants;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextEvent;
@@ -59,6 +60,11 @@ public class HttpEventManager implements
             final ContextManager contextManager = ContextManager.getContextManager(httpSession);
             final ContextManager contextManager = ContextManager.getContextManager(httpSession);
             final PwmApplication pwmApplication = contextManager.getPwmApplication();
             final PwmApplication pwmApplication = contextManager.getPwmApplication();
             httpSession.setAttribute(PwmConstants.SESSION_ATTR_PWM_APP_NONCE, pwmApplication.getRuntimeNonce());
             httpSession.setAttribute(PwmConstants.SESSION_ATTR_PWM_APP_NONCE, pwmApplication.getRuntimeNonce());
+
+            if (pwmApplication != null && pwmApplication.getStatisticsManager() != null) {
+                pwmApplication.getStatisticsManager().updateEps(EpsStatistic.SESSIONS, 1);
+            }
+
             LOGGER.trace("new http session created");
             LOGGER.trace("new http session created");
         } catch (PwmUnrecoverableException e) {
         } catch (PwmUnrecoverableException e) {
             LOGGER.warn("error during sessionCreated event: " + e.getMessage());
             LOGGER.warn("error during sessionCreated event: " + e.getMessage());

+ 5 - 1
server/src/main/java/password/pwm/http/PwmRequest.java

@@ -87,6 +87,7 @@ public class PwmRequest extends PwmHttpRequestWrapper implements Serializable {
     private final PwmResponse pwmResponse;
     private final PwmResponse pwmResponse;
     private transient PwmApplication pwmApplication;
     private transient PwmApplication pwmApplication;
     private transient PwmSession pwmSession;
     private transient PwmSession pwmSession;
+    private PwmURL pwmURL;
 
 
     private final Set<PwmRequestFlag> flags = new HashSet<>();
     private final Set<PwmRequestFlag> flags = new HashSet<>();
 
 
@@ -372,7 +373,10 @@ public class PwmRequest extends PwmHttpRequestWrapper implements Serializable {
     }
     }
 
 
     public PwmURL getURL() {
     public PwmURL getURL() {
-        return new PwmURL(this.getHttpServletRequest());
+        if (pwmURL == null) {
+            pwmURL = new PwmURL(this.getHttpServletRequest());
+        }
+        return pwmURL;
     }
     }
 
 
     public void debugHttpRequestToLog()
     public void debugHttpRequestToLog()

+ 3 - 0
server/src/main/java/password/pwm/http/filter/ObsoleteUrlFilter.java

@@ -54,6 +54,9 @@ public class ObsoleteUrlFilter extends AbstractPwmFilter {
     private ProcessStatus redirectOldUrls(final PwmRequest pwmRequest)
     private ProcessStatus redirectOldUrls(final PwmRequest pwmRequest)
             throws PwmUnrecoverableException, IOException
             throws PwmUnrecoverableException, IOException
     {
     {
+        if (pwmRequest == null || pwmRequest.getURL() == null) {
+            return ProcessStatus.Continue;
+        }
         final PwmURL pwmURL = pwmRequest.getURL();
         final PwmURL pwmURL = pwmRequest.getURL();
         if (pwmURL.isResourceURL() || pwmURL.isCommandServletURL()) {
         if (pwmURL.isResourceURL() || pwmURL.isCommandServletURL()) {
             return ProcessStatus.Continue;
             return ProcessStatus.Continue;

+ 7 - 0
server/src/main/java/password/pwm/http/filter/RequestInitializationFilter.java

@@ -44,6 +44,7 @@ import password.pwm.http.PwmResponse;
 import password.pwm.http.PwmSession;
 import password.pwm.http.PwmSession;
 import password.pwm.http.PwmSessionWrapper;
 import password.pwm.http.PwmSessionWrapper;
 import password.pwm.http.PwmURL;
 import password.pwm.http.PwmURL;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.util.IPMatcher;
 import password.pwm.util.IPMatcher;
@@ -103,6 +104,12 @@ public class RequestInitializationFilter implements Filter {
         PwmApplication testPwmApplicationLoad = null;
         PwmApplication testPwmApplicationLoad = null;
         try { testPwmApplicationLoad = ContextManager.getPwmApplication(req); } catch (PwmException e) {}
         try { testPwmApplicationLoad = ContextManager.getPwmApplication(req); } catch (PwmException e) {}
 
 
+        if (testPwmApplicationLoad != null && mode == PwmApplicationMode.RUNNING) {
+            if (testPwmApplicationLoad.getStatisticsManager() != null) {
+                testPwmApplicationLoad.getStatisticsManager().updateEps(EpsStatistic.REQUESTS, 1);
+            }
+        }
+
         if (testPwmApplicationLoad == null && pwmURL.isResourceURL()) {
         if (testPwmApplicationLoad == null && pwmURL.isResourceURL()) {
             filterChain.doFilter(req, resp);
             filterChain.doFilter(req, resp);
         } else if (pwmURL.isStandaloneWebService() || pwmURL.isJerseyWebService()) {
         } else if (pwmURL.isStandaloneWebService() || pwmURL.isJerseyWebService()) {

+ 2 - 1
server/src/main/java/password/pwm/http/servlet/ClientApiServlet.java

@@ -25,6 +25,7 @@ import password.pwm.http.PwmRequest;
 import password.pwm.http.PwmSession;
 import password.pwm.http.PwmSession;
 import password.pwm.http.PwmURL;
 import password.pwm.http.PwmURL;
 import password.pwm.i18n.Display;
 import password.pwm.i18n.Display;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.util.LocaleHelper;
 import password.pwm.util.LocaleHelper;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.java.TimeDuration;
@@ -344,7 +345,7 @@ public class ClientApiServlet extends ControlledPwmServlet {
 
 
         {
         {
             final List<String> epsTypes = new ArrayList<>();
             final List<String> epsTypes = new ArrayList<>();
-            for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) {
+            for (final EpsStatistic loopEpsType : EpsStatistic.values()) {
                 epsTypes.add(loopEpsType.toString());
                 epsTypes.add(loopEpsType.toString());
             }
             }
             settingMap.put("epsTypes",epsTypes);
             settingMap.put("epsTypes",epsTypes);

+ 24 - 0
server/src/main/java/password/pwm/http/servlet/admin/AdminServlet.java

@@ -61,6 +61,7 @@ import password.pwm.util.localdb.LocalDBException;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.reports.ReportUtils;
 import password.pwm.util.reports.ReportUtils;
 import password.pwm.ws.server.RestResultBean;
 import password.pwm.ws.server.RestResultBean;
+import password.pwm.ws.server.rest.RestStatisticsServer;
 
 
 import javax.servlet.ServletException;
 import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.annotation.WebServlet;
@@ -105,6 +106,7 @@ public class AdminServlet extends ControlledPwmServlet {
         auditData(HttpMethod.GET),
         auditData(HttpMethod.GET),
         sessionData(HttpMethod.GET),
         sessionData(HttpMethod.GET),
         intruderData(HttpMethod.GET),
         intruderData(HttpMethod.GET),
+        statistics(HttpMethod.GET),
 
 
         ;
         ;
 
 
@@ -429,6 +431,28 @@ public class AdminServlet extends ControlledPwmServlet {
         return ProcessStatus.Halt;
         return ProcessStatus.Halt;
     }
     }
 
 
+    @ActionHandler(action = "statistics")
+    private ProcessStatus restStatisticsHandler(final PwmRequest pwmRequest)
+            throws ChaiUnavailableException, PwmUnrecoverableException, IOException
+    {
+        final String statKey = pwmRequest.readParameterAsString("statKey");
+        final String statName = pwmRequest.readParameterAsString("statName");
+        final String days = pwmRequest.readParameterAsString("days");
+
+        final StatisticsManager statisticsManager = pwmRequest.getPwmApplication().getStatisticsManager();
+        final RestStatisticsServer.JsonOutput jsonOutput = new RestStatisticsServer.JsonOutput();
+        jsonOutput.EPS = RestStatisticsServer.addEpsStats(statisticsManager);
+
+        if (statName != null && statName.length() > 0) {
+            jsonOutput.nameData = RestStatisticsServer.doNameStat(statisticsManager, statName, days);
+        } else {
+            jsonOutput.keyData = RestStatisticsServer.doKeyStat(statisticsManager, statKey);
+        }
+
+        final RestResultBean restResultBean = new RestResultBean(jsonOutput);
+        pwmRequest.outputJsonResult(restResultBean);
+        return ProcessStatus.Halt;
+    }
 
 
     private void processDebugUserSearch(final PwmRequest pwmRequest)
     private void processDebugUserSearch(final PwmRequest pwmRequest)
             throws PwmUnrecoverableException
             throws PwmUnrecoverableException

+ 12 - 12
server/src/main/java/password/pwm/http/servlet/resource/ResourceServletService.java

@@ -37,6 +37,7 @@ import password.pwm.svc.stats.EventRateMeter;
 import password.pwm.util.java.FileSystemUtility;
 import password.pwm.util.java.FileSystemUtility;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.Percent;
 import password.pwm.util.java.Percent;
+import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.secure.ChecksumOutputStream;
 import password.pwm.util.secure.ChecksumOutputStream;
@@ -47,7 +48,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.time.Instant;
 import java.time.Instant;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashMap;
@@ -157,13 +157,14 @@ public class ResourceServletService implements PwmService {
     private String makeResourcePathNonce()
     private String makeResourcePathNonce()
             throws PwmUnrecoverableException, IOException
             throws PwmUnrecoverableException, IOException
     {
     {
+        final int nonceLength = Integer.parseInt(pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_RESOURCES_PATH_NONCE_LENGTH));
         final boolean enablePathNonce = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_RESOURCES_ENABLE_PATH_NONCE));
         final boolean enablePathNonce = Boolean.parseBoolean(pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_RESOURCES_ENABLE_PATH_NONCE));
         if (!enablePathNonce) {
         if (!enablePathNonce) {
             return "";
             return "";
         }
         }
 
 
         final Instant startTime = Instant.now();
         final Instant startTime = Instant.now();
-        final ChecksumOutputStream checksumOs = new ChecksumOutputStream(PwmHashAlgorithm.MD5, new NullOutputStream());
+        final ChecksumOutputStream checksumStream = new ChecksumOutputStream(PwmHashAlgorithm.SHA512, new NullOutputStream());
 
 
         if (pwmApplication.getPwmEnvironment().getContextManager() != null) {
         if (pwmApplication.getPwmEnvironment().getContextManager() != null) {
             try {
             try {
@@ -173,10 +174,8 @@ public class ResourceServletService implements PwmService {
                     if (basePath != null && basePath.exists()) {
                     if (basePath != null && basePath.exists()) {
                         final File resourcePath = new File(basePath.getAbsolutePath() + File.separator + "public" + File.separator + "resources");
                         final File resourcePath = new File(basePath.getAbsolutePath() + File.separator + "public" + File.separator + "resources");
                         if (resourcePath.exists()) {
                         if (resourcePath.exists()) {
-                            final List<FileSystemUtility.FileSummaryInformation> fileSummaryInformations = new ArrayList<>();
-                            fileSummaryInformations.addAll(FileSystemUtility.readFileInformation(resourcePath));
-                            for (final FileSystemUtility.FileSummaryInformation fileSummaryInformation : fileSummaryInformations) {
-                                checksumOs.write((fileSummaryInformation.getSha1sum()).getBytes(PwmConstants.DEFAULT_CHARSET));
+                            for (final FileSystemUtility.FileSummaryInformation fileSummaryInformation : FileSystemUtility.readFileInformation(resourcePath)) {
+                                checksumStream.write((fileSummaryInformation.getSha1sum()).getBytes(PwmConstants.DEFAULT_CHARSET));
                             }
                             }
                         }
                         }
                     }
                     }
@@ -187,21 +186,22 @@ public class ResourceServletService implements PwmService {
         }
         }
 
 
         for (final FileResource fileResource : getResourceServletConfiguration().getCustomFileBundle().values()) {
         for (final FileResource fileResource : getResourceServletConfiguration().getCustomFileBundle().values()) {
-            JavaHelper.copyWhilePredicate(fileResource.getInputStream(), checksumOs, o -> true);
+            JavaHelper.copy(fileResource.getInputStream(), checksumStream);
         }
         }
 
 
         if (getResourceServletConfiguration().getZipResources() != null) {
         if (getResourceServletConfiguration().getZipResources() != null) {
             for (final String key : getResourceServletConfiguration().getZipResources().keySet()) {
             for (final String key : getResourceServletConfiguration().getZipResources().keySet()) {
-                final ZipFile value = getResourceServletConfiguration().getZipResources().get(key);
-                checksumOs.write(key.getBytes(PwmConstants.DEFAULT_CHARSET));
-                for (Enumeration<? extends ZipEntry> zipEnum = value.entries(); zipEnum.hasMoreElements(); ) {
+                final ZipFile zipFile = getResourceServletConfiguration().getZipResources().get(key);
+                checksumStream.write(key.getBytes(PwmConstants.DEFAULT_CHARSET));
+                for (Enumeration<? extends ZipEntry> zipEnum = zipFile.entries(); zipEnum.hasMoreElements(); ) {
                     final ZipEntry entry = zipEnum.nextElement();
                     final ZipEntry entry = zipEnum.nextElement();
-                    checksumOs.write(Long.toHexString(entry.getSize()).getBytes(PwmConstants.DEFAULT_CHARSET));
+                    JavaHelper.copy(zipFile.getInputStream(entry),checksumStream);
                 }
                 }
             }
             }
         }
         }
 
 
-        final String nonce = JavaHelper.byteArrayToHexString(checksumOs.getInProgressChecksum()).toLowerCase();
+        final byte[] checksumBytes = checksumStream.getInProgressChecksum();
+        final String nonce = StringUtil.truncate(JavaHelper.byteArrayToHexString(checksumBytes).toLowerCase(), nonceLength);
         LOGGER.debug("completed generation of nonce '" + nonce + "' in " + TimeDuration.fromCurrent(startTime).asCompactString());
         LOGGER.debug("completed generation of nonce '" + nonce + "' in " + TimeDuration.fromCurrent(startTime).asCompactString());
 
 
         final String noncePrefix = pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_RESOURCES_NONCE_PATH_PREFIX);
         final String noncePrefix = pwmApplication.getConfig().readAppProperty(AppProperty.HTTP_RESOURCES_NONCE_PATH_PREFIX);

+ 2 - 1
server/src/main/java/password/pwm/ldap/auth/LDAPAuthenticationRequest.java

@@ -51,6 +51,7 @@ import password.pwm.svc.event.AuditRecord;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.intruder.IntruderManager;
 import password.pwm.svc.intruder.IntruderManager;
 import password.pwm.svc.intruder.RecordType;
 import password.pwm.svc.intruder.RecordType;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.util.PasswordData;
 import password.pwm.util.PasswordData;
@@ -233,7 +234,7 @@ class LDAPAuthenticationRequest implements AuthenticationRequest {
         }
         }
 
 
         statisticsManager.incrementValue(Statistic.AUTHENTICATIONS);
         statisticsManager.incrementValue(Statistic.AUTHENTICATIONS);
-        statisticsManager.updateEps(Statistic.EpsType.AUTHENTICATION, 1);
+        statisticsManager.updateEps(EpsStatistic.AUTHENTICATION, 1);
         statisticsManager.updateAverageValue(Statistic.AVG_AUTHENTICATION_TIME,
         statisticsManager.updateAverageValue(Statistic.AVG_AUTHENTICATION_TIME,
                 TimeDuration.fromCurrent(startTime).getTotalMilliseconds());
                 TimeDuration.fromCurrent(startTime).getTotalMilliseconds());
 
 

+ 2 - 1
server/src/main/java/password/pwm/svc/intruder/IntruderManager.java

@@ -48,6 +48,7 @@ import password.pwm.svc.event.AuditEvent;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.SystemAuditRecord;
 import password.pwm.svc.event.SystemAuditRecord;
 import password.pwm.svc.event.UserAuditRecord;
 import password.pwm.svc.event.UserAuditRecord;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.util.DataStore;
 import password.pwm.util.DataStore;
@@ -374,7 +375,7 @@ public class IntruderManager implements Serializable, PwmService {
                 final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
                 final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
                 if (statisticsManager != null && statisticsManager.status() == STATUS.OPEN) {
                 if (statisticsManager != null && statisticsManager.status() == STATUS.OPEN) {
                     statisticsManager.incrementValue(Statistic.INTRUDER_ATTEMPTS);
                     statisticsManager.incrementValue(Statistic.INTRUDER_ATTEMPTS);
-                    statisticsManager.updateEps(Statistic.EpsType.INTRUDER_ATTEMPTS,1);
+                    statisticsManager.updateEps(EpsStatistic.INTRUDER_ATTEMPTS,1);
                     statisticsManager.incrementValue(recordType.getLockStatistic());
                     statisticsManager.incrementValue(recordType.getLockStatistic());
                 }
                 }
             }
             }

+ 34 - 0
server/src/main/java/password/pwm/svc/stats/EpsStatistic.java

@@ -0,0 +1,34 @@
+package password.pwm.svc.stats;
+
+import password.pwm.i18n.Admin;
+import password.pwm.util.LocaleHelper;
+
+import java.util.Locale;
+
+public enum EpsStatistic {
+    REQUESTS(null),
+    SESSIONS(null),
+    PASSWORD_CHANGES(Statistic.PASSWORD_CHANGES),
+    AUTHENTICATION(Statistic.AUTHENTICATIONS),
+    INTRUDER_ATTEMPTS(Statistic.INTRUDER_ATTEMPTS),
+    PWMDB_WRITES(null),
+    PWMDB_READS(null),
+    DB_WRITES(null),
+    DB_READS(null),
+    ;
+
+    private Statistic relatedStatistic;
+
+    EpsStatistic(final Statistic relatedStatistic) {
+        this.relatedStatistic = relatedStatistic;
+    }
+
+    public Statistic getRelatedStatistic() {
+        return relatedStatistic;
+    }
+
+    public String getLabel(final Locale locale) {
+        final String keyName = "Statistic_Label." + EpsStatistic.class.getSimpleName() + "_" + this.name();
+        return LocaleHelper.getLocalizedMessage(locale, keyName, null, Admin.class);
+    }
+}

+ 0 - 26
server/src/main/java/password/pwm/svc/stats/Statistic.java

@@ -179,32 +179,6 @@ public enum Statistic {
         }
         }
     }
     }
 
 
-    public enum EpsType {
-        PASSWORD_CHANGES(Statistic.PASSWORD_CHANGES),
-        AUTHENTICATION(Statistic.AUTHENTICATIONS),
-        INTRUDER_ATTEMPTS(Statistic.INTRUDER_ATTEMPTS),
-        PWMDB_WRITES(null),
-        PWMDB_READS(null),
-        DB_WRITES(null),
-        DB_READS(null),
-        ;
-
-        private Statistic relatedStatistic;
-
-        EpsType(final Statistic relatedStatistic) {
-            this.relatedStatistic = relatedStatistic;
-        }
-
-        public Statistic getRelatedStatistic() {
-            return relatedStatistic;
-        }
-
-        public String getLabel(final Locale locale) {
-            final String keyName = "Statistic_Label." + EpsType.class.getSimpleName() + "_" + this.name();
-            return LocaleHelper.getLocalizedMessage(locale, keyName, null, Admin.class);
-        }
-    }
-
     public enum EpsDuration {
     public enum EpsDuration {
         MINUTE(TimeDuration.MINUTE),
         MINUTE(TimeDuration.MINUTE),
         HOUR(TimeDuration.HOUR),
         HOUR(TimeDuration.HOUR),

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

@@ -212,7 +212,7 @@ public class StatisticsManager implements PwmService {
     }
     }
 
 
     public void init(final PwmApplication pwmApplication) throws PwmException {
     public void init(final PwmApplication pwmApplication) throws PwmException {
-        for (final Statistic.EpsType type : Statistic.EpsType.values()) {
+        for (final EpsStatistic type : EpsStatistic.values()) {
             for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) {
             for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) {
                 epsMeterMap.put(type.toString() + duration.toString(), new EventRateMeter(duration.getTimeDuration()));
                 epsMeterMap.put(type.toString() + duration.toString(), new EventRateMeter(duration.getTimeDuration()));
             }
             }
@@ -240,8 +240,8 @@ public class StatisticsManager implements PwmService {
         }
         }
 
 
         {
         {
-            for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) {
-                for (final Statistic.EpsType loopEpsDuration : Statistic.EpsType.values()) {
+            for (final EpsStatistic loopEpsType : EpsStatistic.values()) {
+                for (final EpsStatistic loopEpsDuration : EpsStatistic.values()) {
                     final String key = "EPS-" + loopEpsType.toString() + loopEpsDuration.toString();
                     final String key = "EPS-" + loopEpsType.toString() + loopEpsDuration.toString();
                     final String storedValue = localDB.get(LocalDB.DB.PWM_STATS,key);
                     final String storedValue = localDB.get(LocalDB.DB.PWM_STATS,key);
                     if (storedValue != null && storedValue.length() > 0) {
                     if (storedValue != null && storedValue.length() > 0) {
@@ -299,7 +299,7 @@ public class StatisticsManager implements PwmService {
                 localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE, statsCummulative.output());
                 localDB.put(LocalDB.DB.PWM_STATS, DB_KEY_CUMULATIVE, statsCummulative.output());
                 localDB.put(LocalDB.DB.PWM_STATS, currentDailyKey.toString(), statsDaily.output());
                 localDB.put(LocalDB.DB.PWM_STATS, currentDailyKey.toString(), statsDaily.output());
 
 
-                for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) {
+                for (final EpsStatistic loopEpsType : EpsStatistic.values()) {
                     for (final Statistic.EpsDuration loopEpsDuration : Statistic.EpsDuration.values()) {
                     for (final Statistic.EpsDuration loopEpsDuration : Statistic.EpsDuration.values()) {
                         final String key = "EPS-" + loopEpsType.toString();
                         final String key = "EPS-" + loopEpsType.toString();
                         final String mapKey = loopEpsType.toString() + loopEpsDuration.toString();
                         final String mapKey = loopEpsType.toString() + loopEpsDuration.toString();
@@ -441,13 +441,13 @@ public class StatisticsManager implements PwmService {
         }
         }
     }
     }
 
 
-    public void updateEps(final Statistic.EpsType type, final int itemCount) {
+    public void updateEps(final EpsStatistic type, final int itemCount) {
         for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) {
         for (final Statistic.EpsDuration duration : Statistic.EpsDuration.values()) {
             epsMeterMap.get(type.toString() + duration.toString()).markEvents(itemCount);
             epsMeterMap.get(type.toString() + duration.toString()).markEvents(itemCount);
         }
         }
     }
     }
 
 
-    public BigDecimal readEps(final Statistic.EpsType type, final Statistic.EpsDuration duration) {
+    public BigDecimal readEps(final EpsStatistic type, final Statistic.EpsDuration duration) {
         return epsMeterMap.get(type.toString() + duration.toString()).readEventRate();
         return epsMeterMap.get(type.toString() + duration.toString()).readEventRate();
     }
     }
 
 

+ 3 - 3
server/src/main/java/password/pwm/util/db/DatabaseService.java

@@ -38,7 +38,7 @@ import password.pwm.health.HealthRecord;
 import password.pwm.health.HealthStatus;
 import password.pwm.health.HealthStatus;
 import password.pwm.health.HealthTopic;
 import password.pwm.health.HealthTopic;
 import password.pwm.svc.PwmService;
 import password.pwm.svc.PwmService;
-import password.pwm.svc.stats.Statistic;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.util.java.AtomicLoopIntIncrementer;
 import password.pwm.util.java.AtomicLoopIntIncrementer;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.java.JavaHelper;
@@ -332,10 +332,10 @@ public class DatabaseService implements PwmService
             final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
             final StatisticsManager statisticsManager = pwmApplication.getStatisticsManager();
             if (statisticsManager != null && statisticsManager.status() == PwmService.STATUS.OPEN) {
             if (statisticsManager != null && statisticsManager.status() == PwmService.STATUS.OPEN) {
                 if (operationType == OperationType.READ) {
                 if (operationType == OperationType.READ) {
-                    statisticsManager.updateEps(Statistic.EpsType.DB_READS,1);
+                    statisticsManager.updateEps(EpsStatistic.DB_READS,1);
                 }
                 }
                 if (operationType == OperationType.WRITE) {
                 if (operationType == OperationType.WRITE) {
-                    statisticsManager.updateEps(Statistic.EpsType.DB_WRITES,1);
+                    statisticsManager.updateEps(EpsStatistic.DB_WRITES,1);
                 }
                 }
             }
             }
         }
         }

+ 8 - 0
server/src/main/java/password/pwm/util/java/JavaHelper.java

@@ -240,6 +240,14 @@ public class JavaHelper {
         throw exception;
         throw exception;
     }
     }
 
 
+    public static long copy(final InputStream input, final OutputStream output)
+            throws IOException
+    {
+        final int bufferSize = 4 * 1024;
+        final byte[] buffer = new byte[bufferSize];
+        return IOUtils.copyLarge(input, output, 0 , bufferSize, buffer);
+    }
+
     public static long copyWhilePredicate(final InputStream input, final OutputStream output, final Predicate predicate)
     public static long copyWhilePredicate(final InputStream input, final OutputStream output, final Predicate predicate)
             throws IOException
             throws IOException
     {
     {

+ 12 - 0
server/src/main/java/password/pwm/util/java/StringUtil.java

@@ -400,4 +400,16 @@ public abstract class StringUtil {
                 ? input.substring(0, length)
                 ? input.substring(0, length)
                 : input;
                 : input;
     }
     }
+
+    public static int convertStrToInt(final String string, final int defaultValue) {
+        if (string == null) {
+            return defaultValue;
+        }
+
+        try {
+            return Integer.parseInt(string);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
 }
 }

+ 3 - 3
server/src/main/java/password/pwm/util/localdb/LocalDBAdaptor.java

@@ -25,7 +25,7 @@ package password.pwm.util.localdb;
 import password.pwm.PwmApplication;
 import password.pwm.PwmApplication;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
-import password.pwm.svc.stats.Statistic;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.java.TimeDuration;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 
 
@@ -386,7 +386,7 @@ public class LocalDBAdaptor implements LocalDB {
     private void markRead(final int events) {
     private void markRead(final int events) {
         if (pwmApplication != null) {
         if (pwmApplication != null) {
             if (pwmApplication.getStatisticsManager() != null) {
             if (pwmApplication.getStatisticsManager() != null) {
-                pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PWMDB_READS,events);
+                pwmApplication.getStatisticsManager().updateEps(EpsStatistic.PWMDB_READS,events);
             }
             }
         }
         }
     }
     }
@@ -394,7 +394,7 @@ public class LocalDBAdaptor implements LocalDB {
     private void markWrite(final int events) {
     private void markWrite(final int events) {
         if (pwmApplication != null) {
         if (pwmApplication != null) {
             if (pwmApplication.getStatisticsManager() != null) {
             if (pwmApplication.getStatisticsManager() != null) {
-                pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PWMDB_WRITES,events);
+                pwmApplication.getStatisticsManager().updateEps(EpsStatistic.PWMDB_WRITES,events);
             }
             }
         }
         }
     }
     }

+ 3 - 2
server/src/main/java/password/pwm/util/operations/PasswordUtility.java

@@ -74,6 +74,7 @@ import password.pwm.svc.cache.CacheService;
 import password.pwm.svc.event.AuditEvent;
 import password.pwm.svc.event.AuditEvent;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.AuditRecordFactory;
 import password.pwm.svc.event.HelpdeskAuditRecord;
 import password.pwm.svc.event.HelpdeskAuditRecord;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.util.PasswordCharCounter;
 import password.pwm.util.PasswordCharCounter;
 import password.pwm.util.PasswordData;
 import password.pwm.util.PasswordData;
@@ -367,7 +368,7 @@ public class PasswordUtility {
         // update statistics
         // update statistics
         {
         {
             pwmApplication.getStatisticsManager().incrementValue(Statistic.PASSWORD_CHANGES);
             pwmApplication.getStatisticsManager().incrementValue(Statistic.PASSWORD_CHANGES);
-            pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES,1);
+            pwmApplication.getStatisticsManager().updateEps(EpsStatistic.PASSWORD_CHANGES,1);
             final int passwordStrength = PasswordUtility.judgePasswordStrength(newPassword.getStringValue());
             final int passwordStrength = PasswordUtility.judgePasswordStrength(newPassword.getStringValue());
             pwmApplication.getStatisticsManager().updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH,passwordStrength);
             pwmApplication.getStatisticsManager().updateAverageValue(Statistic.AVG_PASSWORD_STRENGTH,passwordStrength);
         }
         }
@@ -469,7 +470,7 @@ public class PasswordUtility {
         }
         }
 
 
         // update statistics
         // update statistics
-        pwmApplication.getStatisticsManager().updateEps(Statistic.EpsType.PASSWORD_CHANGES,1);
+        pwmApplication.getStatisticsManager().updateEps(EpsStatistic.PASSWORD_CHANGES,1);
         pwmApplication.getStatisticsManager().incrementValue(Statistic.HELPDESK_PASSWORD_SET);
         pwmApplication.getStatisticsManager().incrementValue(Statistic.HELPDESK_PASSWORD_SET);
 
 
         // create a uib for end user
         // create a uib for end user

+ 9 - 6
server/src/main/java/password/pwm/ws/server/rest/RestStatisticsServer.java

@@ -22,16 +22,18 @@
 
 
 package password.pwm.ws.server.rest;
 package password.pwm.ws.server.rest;
 
 
-import com.novell.ldapchai.util.StringHelper;
+import lombok.Data;
 import password.pwm.config.Configuration;
 import password.pwm.config.Configuration;
 import password.pwm.config.PwmSetting;
 import password.pwm.config.PwmSetting;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.ErrorInformation;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmError;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.http.ContextManager;
 import password.pwm.http.ContextManager;
+import password.pwm.svc.stats.EpsStatistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.Statistic;
 import password.pwm.svc.stats.StatisticsBundle;
 import password.pwm.svc.stats.StatisticsBundle;
 import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.stats.StatisticsManager;
+import password.pwm.util.java.StringUtil;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.ws.server.RestRequestBean;
 import password.pwm.ws.server.RestRequestBean;
 import password.pwm.ws.server.RestResultBean;
 import password.pwm.ws.server.RestResultBean;
@@ -69,6 +71,7 @@ public class RestStatisticsServer extends AbstractRestServer {
     @Context
     @Context
     ServletContext context;
     ServletContext context;
 
 
+    @Data
     public static class JsonOutput implements Serializable
     public static class JsonOutput implements Serializable
     {
     {
         public Map<String,String> EPS;
         public Map<String,String> EPS;
@@ -119,16 +122,16 @@ public class RestStatisticsServer extends AbstractRestServer {
         }
         }
     }
     }
 
 
-    private Map<String,Object> doNameStat(final StatisticsManager statisticsManager, final String statName, final String days) {
+    public static Map<String,Object> doNameStat(final StatisticsManager statisticsManager, final String statName, final String days) {
         final Statistic statistic = Statistic.valueOf(statName);
         final Statistic statistic = Statistic.valueOf(statName);
-        final int historyDays = StringHelper.convertStrToInt(days, 30);
+        final int historyDays = StringUtil.convertStrToInt(days, 30);
 
 
         final Map<String,Object> results = new HashMap<>();
         final Map<String,Object> results = new HashMap<>();
         results.putAll(statisticsManager.getStatHistory(statistic, historyDays));
         results.putAll(statisticsManager.getStatHistory(statistic, historyDays));
         return results;
         return results;
     }
     }
 
 
-    private Map<String,Object> doKeyStat(final StatisticsManager statisticsManager, final String statKey) {
+    public static Map<String,Object> doKeyStat(final StatisticsManager statisticsManager, final String statKey) {
         final String key = (statKey == null)
         final String key = (statKey == null)
                 ? StatisticsManager.KEY_CUMULATIVE
                 ? StatisticsManager.KEY_CUMULATIVE
                 : statKey;
                 : statKey;
@@ -142,9 +145,9 @@ public class RestStatisticsServer extends AbstractRestServer {
         return outputValueMap;
         return outputValueMap;
     }
     }
 
 
-    private Map<String,String> addEpsStats(final StatisticsManager statisticsManager){
+    public static Map<String,String> addEpsStats(final StatisticsManager statisticsManager){
         final Map<String,String> outputMap = new TreeMap<>();
         final Map<String,String> outputMap = new TreeMap<>();
-        for (final Statistic.EpsType loopEps : Statistic.EpsType.values()) {
+        for (final EpsStatistic loopEps : EpsStatistic.values()) {
             for (final Statistic.EpsDuration loopDuration : Statistic.EpsDuration.values()) {
             for (final Statistic.EpsDuration loopDuration : Statistic.EpsDuration.values()) {
                 final BigDecimal loopValue = statisticsManager.readEps(loopEps,loopDuration);
                 final BigDecimal loopValue = statisticsManager.readEps(loopEps,loopDuration);
                 final BigDecimal outputValue = loopValue.setScale(3, RoundingMode.UP);
                 final BigDecimal outputValue = loopValue.setScale(3, RoundingMode.UP);

+ 1 - 0
server/src/main/resources/password/pwm/AppProperty.properties

@@ -93,6 +93,7 @@ http.resources.maxCacheItems=500
 http.resources.maxCacheBytes=500000
 http.resources.maxCacheBytes=500000
 http.resources.expirationSeconds=86400
 http.resources.expirationSeconds=86400
 http.resources.gzip.enable=true
 http.resources.gzip.enable=true
+http.resources.pathNonce.length=32
 http.resources.pathNonceEnable=true
 http.resources.pathNonceEnable=true
 http.resources.pathNoncePrefix=nonce-
 http.resources.pathNoncePrefix=nonce-
 http.resources.zipFiles=[]
 http.resources.zipFiles=[]

+ 9 - 7
server/src/main/resources/password/pwm/i18n/Admin.properties

@@ -272,13 +272,15 @@ Statistic_Label.ForeignSessionsAccepted=Foreign Sessions Accepted
 Statistic_Description.ForeignSessionsAccepted=Number of sessions generated on a foreign or server or previous instance of this server and accepted as valid authentication.
 Statistic_Description.ForeignSessionsAccepted=Number of sessions generated on a foreign or server or previous instance of this server and accepted as valid authentication.
 Statistic_Label.ObsoleteUrlRequests=Obsolete URL Requests
 Statistic_Label.ObsoleteUrlRequests=Obsolete URL Requests
 Statistic_Description.ObsoleteUrlRequests=Number of web requests to obsolete URLs.
 Statistic_Description.ObsoleteUrlRequests=Number of web requests to obsolete URLs.
-Statistic_Label.EpsType_PASSWORD_CHANGES=Password Changes
-Statistic_Label.EpsType_AUTHENTICATION=Authentications
-Statistic_Label.EpsType_INTRUDER_ATTEMPTS=Intruder Attempts
-Statistic_Label.EpsType_PWMDB_READS=LocalDB Reads
-Statistic_Label.EpsType_PWMDB_WRITES=LocalDB Writes
-Statistic_Label.EpsType_DB_READS=Database Reads
-Statistic_Label.EpsType_DB_WRITES=Database Writes
+Statistic_Label.EpsStatistic_REQUESTS=Requests
+Statistic_Label.EpsStatistic_SESSIONS=Sessions
+Statistic_Label.EpsStatistic_PASSWORD_CHANGES=Password Changes
+Statistic_Label.EpsStatistic_AUTHENTICATION=Authentications
+Statistic_Label.EpsStatistic_INTRUDER_ATTEMPTS=Intruder Attempts
+Statistic_Label.EpsStatistic_PWMDB_READS=LocalDB Reads
+Statistic_Label.EpsStatistic_PWMDB_WRITES=LocalDB Writes
+Statistic_Label.EpsStatistic_DB_READS=Database Reads
+Statistic_Label.EpsStatistic_DB_WRITES=Database Writes
 Title_About=About
 Title_About=About
 Title_DirectoryReporting=Directory Reporting
 Title_DirectoryReporting=Directory Reporting
 Title_DataViewer=Data Viewer
 Title_DataViewer=Data Viewer

+ 3 - 2
server/src/main/webapp/WEB-INF/jsp/admin-dashboard.jsp

@@ -45,6 +45,7 @@
 <%@ page import="java.util.List" %>
 <%@ page import="java.util.List" %>
 <%@ page import="java.util.Locale" %>
 <%@ page import="java.util.Locale" %>
 <%@ page import="java.util.Map" %>
 <%@ page import="java.util.Map" %>
+<%@ page import="password.pwm.svc.stats.EpsStatistic" %>
 <!DOCTYPE html>
 <!DOCTYPE html>
 <%@ page language="java" session="true" isThreadSafe="true"
 <%@ page language="java" session="true" isThreadSafe="true"
          contentType="text/html" %>
          contentType="text/html" %>
@@ -111,8 +112,8 @@
                             <pwm:display key="Title_LastDay" bundle="Admin"/>
                             <pwm:display key="Title_LastDay" bundle="Admin"/>
                         </td>
                         </td>
                     </tr>
                     </tr>
-                    <% for (final Statistic.EpsType loopEpsType : Statistic.EpsType.values()) { %>
-                    <% if ((loopEpsType != Statistic.EpsType.DB_READS && loopEpsType != Statistic.EpsType.DB_WRITES) || dashboard_pwmApplication.getConfig().hasDbConfigured()) { %>
+                    <% for (final EpsStatistic loopEpsType : EpsStatistic.values()) { %>
+                    <% if ((loopEpsType != EpsStatistic.DB_READS && loopEpsType != EpsStatistic.DB_WRITES) || dashboard_pwmApplication.getConfig().hasDbConfigured()) { %>
                     <tr>
                     <tr>
                         <td class="key">
                         <td class="key">
                             <%= loopEpsType.getLabel(dashboard_pwmSession.getSessionStateBean().getLocale()) %> / Minute
                             <%= loopEpsType.getLabel(dashboard_pwmSession.getSessionStateBean().getLocale()) %> / Minute

+ 86 - 92
server/src/main/webapp/public/resources/js/admin.js

@@ -343,19 +343,17 @@ PWM_ADMIN.initActiveSessionGrid=function() {
 };
 };
 
 
 PWM_ADMIN.refreshActiveSessionGrid=function() {
 PWM_ADMIN.refreshActiveSessionGrid=function() {
-    require(["dojo"],function(dojo){
-        var grid = PWM_VAR['activeSessionsGrid'];
-        grid.refresh();
+    var grid = PWM_VAR['activeSessionsGrid'];
+    grid.refresh();
 
 
-        var maximum = PWM_MAIN.getObject('maxActiveSessionResults').value;
-        var url = PWM_MAIN.addParamToUrl(window.location.href,"processAction", "sessionData");
-        url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
-        var loadFunction = function(data) {
-            grid.renderArray(data['data']);
-            grid.set("sort", { attribute : 'createTime', ascending: false, descending: true });
-        };
-        PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
-    });
+    var maximum = PWM_MAIN.getObject('maxActiveSessionResults').value;
+    var url = PWM_MAIN.addParamToUrl(window.location.href,"processAction", "sessionData");
+    url = PWM_MAIN.addParamToUrl(url,'maximum',maximum);
+    var loadFunction = function(data) {
+        grid.renderArray(data['data']);
+        grid.set("sort", { attribute : 'createTime', ascending: false, descending: true });
+    };
+    PWM_MAIN.ajaxRequest(url,loadFunction,{method:'GET'});
 };
 };
 
 
 PWM_ADMIN.intruderHeaders = function(){
 PWM_ADMIN.intruderHeaders = function(){
@@ -550,99 +548,95 @@ PWM_ADMIN.showStatChart = function(statName,days,divName,options) {
             "dojox/gauges/GlossyCircularGauge",
             "dojox/gauges/GlossyCircularGauge",
             "dojo/domReady!"],
             "dojo/domReady!"],
         function(dojo,dijit,registry){
         function(dojo,dijit,registry){
-            var statsGetUrl = PWM_GLOBAL['url-restservice'] + "/statistics";
-            statsGetUrl += "?statName=" + statName;
-            statsGetUrl += "&days=" + days;
-
-            dojo.xhrGet({
-                url: statsGetUrl,
-                handleAs: "json",
-                headers: {"Accept":"application/json","X-RestClientKey":PWM_GLOBAL['restClientKey']},
-                timeout: 15 * 1000,
-                preventCache: true,
-                error: function(data) {
-                    for (var loopEpsTypeIndex = 0; loopEpsTypeIndex < epsTypes.length; loopEpsTypeIndex++) { // clear all the gauges
-                        var loopEpsName = epsTypes[loopEpsTypeIndex] + '';
+            var statsGetUrl = PWM_MAIN.addParamToUrl(window.location.href,"processAction","statistics");
+            statsGetUrl = PWM_MAIN.addParamToUrl(statsGetUrl, "statName", statName);
+            statsGetUrl = PWM_MAIN.addParamToUrl(statsGetUrl, "days", days);
+
+            var errorFunction = function() {
+                for (var loopEpsTypeIndex = 0; loopEpsTypeIndex < epsTypes.length; loopEpsTypeIndex++) { // clear all the gauges
+                    var loopEpsName = epsTypes[loopEpsTypeIndex] + '';
+                    for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
+                        var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
+                        var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
+                        if (PWM_MAIN.getObject(loopEpsID) !== null) {
+                            if (registry.byId(loopEpsID)) {
+                                registry.byId(loopEpsID).setAttribute('value','0');
+                            }
+                        }
+                    }
+                }
+                doRefresh();
+            };
+
+            var loadFunction = function(data) {
+                {// gauges
+                    console.log('Beginning stats update process...');
+                    data = data['data'];
+                    var activityCount = 0;
+                    for (var loopEpsIndex = 0; loopEpsIndex < epsTypes.length; loopEpsIndex++) {
+                        var loopEpsName = epsTypes[loopEpsIndex] + '';
                         for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
                         for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
                             var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
                             var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
                             var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
                             var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
+                            var loopFieldEpsID = "FIELD_" + loopEpsName + "_" + loopEpsDuration;
+                            var loopEpsValue = data['EPS'][loopEpsName + "_" + loopEpsDuration];
+                            var loopEpmValue = (loopEpsValue * 60).toFixed(3);
+                            var loopTop = PWM_GLOBAL['client.activityMaxEpsRate'];
+                            if (loopEpsDuration === "HOURLY") {
+                                activityCount += loopEpsValue;
+                            }
+                            if (PWM_MAIN.getObject(loopFieldEpsID) !== null) {
+                                PWM_MAIN.getObject(loopFieldEpsID).innerHTML = loopEpmValue;
+                            }
                             if (PWM_MAIN.getObject(loopEpsID) !== null) {
                             if (PWM_MAIN.getObject(loopEpsID) !== null) {
+                                console.log('EpsID=' + loopEpsID + ', ' + 'Eps=' + loopEpsValue + ', ' + 'Epm=' + loopEpmValue);
                                 if (registry.byId(loopEpsID)) {
                                 if (registry.byId(loopEpsID)) {
-                                    registry.byId(loopEpsID).setAttribute('value','0');
+                                    registry.byId(loopEpsID).setAttribute('value',loopEpmValue);
+                                    registry.byId(loopEpsID).setAttribute('max',loopTop);
+                                } else {
+                                    var glossyCircular = new dojox.gauges.GlossyCircularGauge({
+                                        background: [255, 255, 255, 0],
+                                        noChange: true,
+                                        value: loopEpmValue,
+                                        max: loopTop,
+                                        needleColor: '#FFDC8B',
+                                        majorTicksInterval: Math.abs(loopTop / 10),
+                                        minorTicksInterval: Math.abs(loopTop / 10),
+                                        id: loopEpsID,
+                                        width: 200,
+                                        height: 150
+                                    }, dojo.byId(loopEpsID));
+                                    glossyCircular.startup();
                                 }
                                 }
                             }
                             }
                         }
                         }
                     }
                     }
-                    doRefresh();
-                },
-                load: function(data) {
-                    {// gauges
-                        console.log('Beginning stats update process...');
-                        data = data['data'];
-                        var activityCount = 0;
-                        for (var loopEpsIndex = 0; loopEpsIndex < epsTypes.length; loopEpsIndex++) {
-                            var loopEpsName = epsTypes[loopEpsIndex] + '';
-                            for (var loopEpsDurationsIndex = 0; loopEpsDurationsIndex < epsDurations.length; loopEpsDurationsIndex++) { // clear all the gauges
-                                var loopEpsDuration = epsDurations[loopEpsDurationsIndex] + '';
-                                var loopEpsID = "EPS-GAUGE-" + loopEpsName + "_" + loopEpsDuration;
-                                var loopFieldEpsID = "FIELD_" + loopEpsName + "_" + loopEpsDuration;
-                                var loopEpsValue = data['EPS'][loopEpsName + "_" + loopEpsDuration];
-                                var loopEpmValue = (loopEpsValue * 60).toFixed(3);
-                                var loopTop = PWM_GLOBAL['client.activityMaxEpsRate'];
-                                if (loopEpsDuration === "HOURLY") {
-                                    activityCount += loopEpsValue;
-                                }
-                                if (PWM_MAIN.getObject(loopFieldEpsID) !== null) {
-                                    PWM_MAIN.getObject(loopFieldEpsID).innerHTML = loopEpmValue;
-                                }
-                                if (PWM_MAIN.getObject(loopEpsID) !== null) {
-                                    console.log('EpsID=' + loopEpsID + ', ' + 'Eps=' + loopEpsValue + ', ' + 'Epm=' + loopEpmValue);
-                                    if (registry.byId(loopEpsID)) {
-                                        registry.byId(loopEpsID).setAttribute('value',loopEpmValue);
-                                        registry.byId(loopEpsID).setAttribute('max',loopTop);
-                                    } else {
-                                        var glossyCircular = new dojox.gauges.GlossyCircularGauge({
-                                            background: [255, 255, 255, 0],
-                                            noChange: true,
-                                            value: loopEpmValue,
-                                            max: loopTop,
-                                            needleColor: '#FFDC8B',
-                                            majorTicksInterval: Math.abs(loopTop / 10),
-                                            minorTicksInterval: Math.abs(loopTop / 10),
-                                            id: loopEpsID,
-                                            width: 200,
-                                            height: 150
-                                        }, dojo.byId(loopEpsID));
-                                        glossyCircular.startup();
-                                    }
-                                }
-                            }
-                        }
-                        PWM_GLOBAL['epsActivityCount'] = activityCount;
+                    PWM_GLOBAL['epsActivityCount'] = activityCount;
+                }
+                if (divName !== null && PWM_MAIN.getObject(divName)) { // stats chart
+                    var values = [];
+                    for(var key in data['nameData']) {
+                        var value = data['nameData'][key];
+                        values.push(parseInt(value));
                     }
                     }
-                    if (divName !== null && PWM_MAIN.getObject(divName)) { // stats chart
-                        var values = [];
-                        for(var key in data['nameData']) {
-                            var value = data['nameData'][key];
-                            values.push(parseInt(value));
-                        }
 
 
-                        if (PWM_GLOBAL[divName + '-stored-reference']) {
-                            var existingChart = PWM_GLOBAL[divName + '-stored-reference'];
-                            existingChart.destroy();
-                        }
-                        var c = new dojox.charting.Chart2D(divName);
-                        PWM_GLOBAL[divName + '-stored-reference'] = c;
-                        c.addPlot("default", {type: "Columns", gap:'2'});
-                        c.addAxis("x", {});
-                        c.addAxis("y", {vertical: true});
-                        c.setTheme(dojox.charting.themes.Wetland);
-                        c.addSeries("Series 1", values);
-                        c.render();
+                    if (PWM_GLOBAL[divName + '-stored-reference']) {
+                        var existingChart = PWM_GLOBAL[divName + '-stored-reference'];
+                        existingChart.destroy();
                     }
                     }
-                    doRefresh();
+                    var c = new dojox.charting.Chart2D(divName);
+                    PWM_GLOBAL[divName + '-stored-reference'] = c;
+                    c.addPlot("default", {type: "Columns", gap:'2'});
+                    c.addAxis("x", {});
+                    c.addAxis("y", {vertical: true});
+                    c.setTheme(dojox.charting.themes.Wetland);
+                    c.addSeries("Series 1", values);
+                    c.render();
                 }
                 }
-            });
+                doRefresh();
+            };
+
+            PWM_MAIN.ajaxRequest(statsGetUrl, loadFunction, {errorFunction:errorFunction,method:'GET'});
         });
         });
 };
 };