private void updateCacheFromLdap() throws ChaiUnavailableException, ChaiOperationException, PwmOperationalException, PwmUnrecoverableException { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "beginning process to updating user cache records from ldap"); if (status != STATUS.OPEN) { return; } cancelFlag = false; reportStatus = new ReportStatusInfo(settings.getSettingsHash()); reportStatus.setInProgress(true); reportStatus.setStartDate(new Date()); try { final Queue<UserIdentity> allUsers = new LinkedList<>(getListOfUsers()); reportStatus.setTotal(allUsers.size()); while (status == STATUS.OPEN && !allUsers.isEmpty() && !cancelFlag) { final Date startUpdateTime = new Date(); final UserIdentity userIdentity = allUsers.poll(); try { if (updateCachedRecordFromLdap(userIdentity)) { reportStatus.setUpdated(reportStatus.getUpdated() + 1); } } catch (Exception e) { String errorMsg = "error while updating report cache for " + userIdentity.toString() + ", cause: "; errorMsg += e instanceof PwmException ? ((PwmException) e).getErrorInformation().toDebugStr() : e.getMessage(); final ErrorInformation errorInformation; errorInformation = new ErrorInformation(PwmError.ERROR_REPORTING_ERROR, errorMsg); LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, errorInformation.toDebugStr()); reportStatus.setLastError(errorInformation); reportStatus.setErrors(reportStatus.getErrors() + 1); } reportStatus.setCount(reportStatus.getCount() + 1); reportStatus.getEventRateMeter().markEvents(1); final TimeDuration totalUpdateTime = TimeDuration.fromCurrent(startUpdateTime); if (settings.isAutoCalcRest()) { avgTracker.addSample(totalUpdateTime.getTotalMilliseconds()); Helper.pause(avgTracker.avgAsLong()); } else { Helper.pause(settings.getRestTime().getTotalMilliseconds()); } } if (cancelFlag) { reportStatus.setLastError( new ErrorInformation( PwmError.ERROR_SERVICE_NOT_AVAILABLE, "report cancelled by operator")); } } finally { reportStatus.setFinishDate(new Date()); reportStatus.setInProgress(false); } LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "update user cache process completed: " + JsonUtil.serialize(reportStatus)); }
@Override public void init(PwmApplication pwmApplication) throws PwmException { status = STATUS.OPENING; this.pwmApplication = pwmApplication; if (pwmApplication.getApplicationMode() == PwmApplication.MODE.READ_ONLY) { LOGGER.debug( PwmConstants.REPORTING_SESSION_LABEL, "application mode is read-only, will remain closed"); status = STATUS.CLOSED; return; } if (pwmApplication.getLocalDB() == null || LocalDB.Status.OPEN != pwmApplication.getLocalDB().status()) { LOGGER.debug(PwmConstants.REPORTING_SESSION_LABEL, "LocalDB is not open, will remain closed"); status = STATUS.CLOSED; 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; clear(); return; } try { userCacheService = new UserCacheService(); userCacheService.init(pwmApplication); } catch (Exception e) { LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, "unable to init cache service"); status = STATUS.CLOSED; return; } settings = ReportSettings.readSettingsFromConfig(pwmApplication.getConfig()); summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays()); executorService = Executors.newSingleThreadScheduledExecutor( Helper.makePwmThreadFactory( Helper.makeThreadName(pwmApplication, this.getClass()) + "-", true)); String startupMsg = "report service started"; LOGGER.debug(startupMsg); executorService.submit(new InitializationTask()); status = STATUS.OPEN; }
public void clear() throws LocalDBException, PwmUnrecoverableException { final Date startTime = new Date(); LOGGER.info(PwmConstants.REPORTING_SESSION_LABEL, "clearing cached report data"); if (userCacheService != null) { userCacheService.clear(); } summaryData = ReportSummaryData.newSummaryData(settings.getTrackDays()); reportStatus = new ReportStatusInfo(settings.getSettingsHash()); saveTempData(); LOGGER.info( PwmConstants.REPORTING_SESSION_LABEL, "finished clearing report " + TimeDuration.fromCurrent(startTime).asCompactString()); }
private void initTempData() throws LocalDBException, PwmUnrecoverableException { final String cleanFlag = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG); if (!"true".equals(cleanFlag)) { LOGGER.error(PwmConstants.REPORTING_SESSION_LABEL, "did not shut down cleanly"); reportStatus = new ReportStatusInfo(settings.getSettingsHash()); reportStatus.setTotal(userCacheService.size()); } else { try { final String jsonInfo = pwmApplication.readAppAttribute(PwmApplication.AppAttribute.REPORT_STATUS); if (jsonInfo != null && !jsonInfo.isEmpty()) { reportStatus = JsonUtil.deserialize(jsonInfo, ReportStatusInfo.class); } } catch (Exception e) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "error loading cached report status info into memory: " + e.getMessage()); } } reportStatus = reportStatus == null ? new ReportStatusInfo(settings.getSettingsHash()) : reportStatus; // safety final String currentSettingCache = settings.getSettingsHash(); if (reportStatus.getSettingsHash() != null && !reportStatus.getSettingsHash().equals(currentSettingCache)) { LOGGER.error( PwmConstants.REPORTING_SESSION_LABEL, "configuration has changed, will clear cached report data"); clear(); } reportStatus.setInProgress(false); pwmApplication.writeAppAttribute(PwmApplication.AppAttribute.REPORT_CLEAN_FLAG, "false"); }
private List<UserIdentity> getListOfUsers() throws ChaiUnavailableException, ChaiOperationException, PwmUnrecoverableException, PwmOperationalException { return readAllUsersFromLdap( pwmApplication, settings.getSearchFilter(), settings.getMaxSearchSize()); }
private boolean updateCachedRecordFromLdap( final UserIdentity userIdentity, final UserInfoBean userInfoBean, final UserCacheService.StorageKey storageKey) throws ChaiUnavailableException, PwmUnrecoverableException, LocalDBException { final UserCacheRecord userCacheRecord = userCacheService.readStorageKey(storageKey); TimeDuration cacheAge = null; if (userCacheRecord != null && userCacheRecord.getCacheTimestamp() != null) { cacheAge = TimeDuration.fromCurrent(userCacheRecord.getCacheTimestamp()); } boolean updateCache = false; if (userInfoBean != null) { updateCache = true; } else { if (cacheAge == null) { LOGGER.trace( PwmConstants.REPORTING_SESSION_LABEL, "stored cache for " + userIdentity + " is missing cache storage timestamp, will update"); updateCache = true; } else if (cacheAge.isLongerThan(settings.getMinCacheAge())) { LOGGER.trace( PwmConstants.REPORTING_SESSION_LABEL, "stored cache for " + userIdentity + " is " + cacheAge.asCompactString() + " old, will update"); updateCache = true; } } if (updateCache) { if (userCacheRecord != null) { if (summaryData != null && summaryData.getEpoch() != null && summaryData.getEpoch().equals(userCacheRecord.getSummaryEpoch())) { summaryData.remove(userCacheRecord); } } final UserInfoBean newUserBean; if (userInfoBean != null) { newUserBean = userInfoBean; } else { newUserBean = new UserInfoBean(); final UserStatusReader.Settings readerSettings = new UserStatusReader.Settings(); readerSettings.setSkipReportUpdate(true); final ChaiProvider chaiProvider = pwmApplication.getProxyChaiProvider(userIdentity.getLdapProfileID()); final UserStatusReader userStatusReader = new UserStatusReader( pwmApplication, PwmConstants.REPORTING_SESSION_LABEL, readerSettings); userStatusReader.populateUserInfoBean( newUserBean, PwmConstants.DEFAULT_LOCALE, userIdentity, chaiProvider); } final UserCacheRecord newUserCacheRecord = userCacheService.updateUserCache(newUserBean); if (summaryData != null && summaryData.getEpoch() != null && newUserCacheRecord != null) { if (!summaryData.getEpoch().equals(newUserCacheRecord.getSummaryEpoch())) { newUserCacheRecord.setSummaryEpoch(summaryData.getEpoch()); userCacheService.store(newUserCacheRecord); } summaryData.update(newUserCacheRecord); } } return updateCache; }