Skip to content

Commit

Permalink
#3268: Defer getting entries from the dictionary
Browse files Browse the repository at this point in the history
With the exception of the AccountDeactivationWorker schedule, changes in the dictionary are now properly reflected after a reload.
  • Loading branch information
gjvoosten committed Nov 4, 2020
1 parent 0d7b0fa commit dab10ec
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 134 deletions.
9 changes: 5 additions & 4 deletions src/main/java/mil/dds/anet/AnetApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,10 @@ public void run(AnetConfiguration configuration, Environment environment)
}

private void runAccountDeactivationWorker(final AnetConfiguration configuration,
final ScheduledExecutorService scheduler, final AnetObjectEngine engine)
throws IllegalArgumentException {
// Check whether the application is configured to auto-check for account deactivation
final ScheduledExecutorService scheduler, final AnetObjectEngine engine) {
// Check whether the application is configured to auto-check for account deactivation.
// NOTE: if you change this, reloading the dictionary from the admin interface is *not*
// sufficient, you will have to restart ANET for this change to be reflected
if (configuration.getDictionaryEntry("automaticallyInactivateUsers") != null) {
// Check for any accounts which are scheduled to be deactivated as they reach the end-of-tour
// date.
Expand All @@ -289,7 +290,7 @@ private void runAccountDeactivationWorker(final AnetConfiguration configuration,
final AccountDeactivationWorker deactivationWarningWorker = new AccountDeactivationWorker(
configuration, engine.getPersonDao(), accountDeactivationWarningInterval);

// Run the email deactivation worker at the set interval. In development run it every minute.
// Run the email deactivation worker at the set interval
scheduler.scheduleAtFixedRate(deactivationWarningWorker, accountDeactivationWarningInterval,
accountDeactivationWarningInterval, TimeUnit.SECONDS);

Expand Down
53 changes: 26 additions & 27 deletions src/main/java/mil/dds/anet/resources/ReportResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,28 +79,10 @@ public class ReportResource {
private final AnetObjectEngine engine;
private final AnetConfiguration config;

private final RollupGraphComparator rollupGraphComparator;
private final DateTimeFormatter dtf;
private final boolean engagementsIncludeTimeAndDuration;
private final DateTimeFormatter edtf;

public ReportResource(AnetObjectEngine engine, AnetConfiguration config) {
this.engine = engine;
this.dao = engine.getReportDao();
this.config = config;
this.dtf = DateTimeFormatter
.ofPattern((String) this.config.getDictionaryEntry("dateFormats.email.date"))
.withZone(DaoUtils.getDefaultZoneId());
engagementsIncludeTimeAndDuration = Boolean.TRUE
.equals((Boolean) this.config.getDictionaryEntry("engagementsIncludeTimeAndDuration"));
final String edtfPattern = (String) this.config
.getDictionaryEntry(engagementsIncludeTimeAndDuration ? "dateFormats.email.withTime"
: "dateFormats.email.date");
this.edtf = DateTimeFormatter.ofPattern(edtfPattern).withZone(DaoUtils.getDefaultZoneId());
@SuppressWarnings("unchecked")
List<String> pinnedOrgNames = (List<String>) this.config.getDictionaryEntry("pinned_ORGs");
this.rollupGraphComparator = new RollupGraphComparator(pinnedOrgNames);

}

@GraphQLQuery(name = "report")
Expand Down Expand Up @@ -736,7 +718,7 @@ public List<RollupGraph> getDailyRollupGraph(@GraphQLArgument(name = "startDate"
dailyRollupGraph = dao.getDailyRollupGraph(startDate, endDate, orgType, nonReportingOrgs);
}

Collections.sort(dailyRollupGraph, rollupGraphComparator);
Collections.sort(dailyRollupGraph, getRollupGraphComparator());

return dailyRollupGraph;
}
Expand Down Expand Up @@ -776,21 +758,15 @@ public String showRollupEmail(@GraphQLArgument(name = "startDate") Long start,
action.setAdvisorOrganizationUuid(advisorOrgUuid);
action.setPrincipalOrganizationUuid(principalOrgUuid);

@SuppressWarnings("unchecked")
final Map<String, Object> fields = (Map<String, Object>) config.getDictionaryEntry("fields");

Map<String, Object> context = new HashMap<String, Object>();
final Map<String, Object> context = new HashMap<String, Object>();
context.put("context", engine.getContext());
context.put("serverUrl", config.getServerUrl());
context.put(AdminSettingKeys.SECURITY_BANNER_TEXT.name(),
engine.getAdminSetting(AdminSettingKeys.SECURITY_BANNER_TEXT));
context.put(AdminSettingKeys.SECURITY_BANNER_COLOR.name(),
engine.getAdminSetting(AdminSettingKeys.SECURITY_BANNER_COLOR));
context.put(DailyRollupEmail.SHOW_REPORT_TEXT_FLAG, showReportText);
context.put("dateFormatter", dtf);
context.put("engagementsIncludeTimeAndDuration", engagementsIncludeTimeAndDuration);
context.put("engagementDateFormatter", edtf);
context.put("fields", fields);
addConfigToContext(context);

try {
Configuration freemarkerConfig = new Configuration(FREEMARKER_VERSION);
Expand Down Expand Up @@ -974,4 +950,27 @@ private void updateAssessment(Note newAssessment, Note oldAssessment) {
noteDao.update(newAssessment);
}
}

private void addConfigToContext(Map<String, Object> context) {
context.put("dateFormatter",
DateTimeFormatter.ofPattern((String) config.getDictionaryEntry("dateFormats.email.date"))
.withZone(DaoUtils.getDefaultZoneId()));
context.put("engagementsIncludeTimeAndDuration", Boolean.TRUE
.equals((Boolean) config.getDictionaryEntry("engagementsIncludeTimeAndDuration")));
final String edtfPattern = (String) config.getDictionaryEntry(Boolean.TRUE
.equals((Boolean) config.getDictionaryEntry("engagementsIncludeTimeAndDuration"))
? "dateFormats.email.withTime"
: "dateFormats.email.date");
context.put("engagementDateFormatter",
DateTimeFormatter.ofPattern(edtfPattern).withZone(DaoUtils.getDefaultZoneId()));
@SuppressWarnings("unchecked")
final Map<String, Object> fields = (Map<String, Object>) config.getDictionaryEntry("fields");
context.put("fields", fields);
}

private RollupGraphComparator getRollupGraphComparator() {
@SuppressWarnings("unchecked")
final List<String> pinnedOrgNames = (List<String>) config.getDictionaryEntry("pinned_ORGs");
return new RollupGraphComparator(pinnedOrgNames);
}
}
15 changes: 10 additions & 5 deletions src/main/java/mil/dds/anet/resources/TaskResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,12 @@ public class TaskResource {

private final AnetObjectEngine engine;
private final TaskDao dao;
private final String duplicateTaskShortName;
private final AnetConfiguration config;

public TaskResource(AnetObjectEngine engine, AnetConfiguration config) {
this.engine = engine;
this.dao = engine.getTaskDao();
final String taskShortLabel = (String) config.getDictionaryEntry("fields.task.shortLabel");
duplicateTaskShortName = String.format("Duplicate %s number", taskShortLabel);
this.config = config;
}

@GraphQLQuery(name = "task")
Expand All @@ -59,7 +58,7 @@ public Task createTask(@GraphQLRootContext Map<String, Object> context,
try {
created = dao.insert(t);
} catch (UnableToExecuteStatementException e) {
throw ResponseUtils.handleSqlException(e, duplicateTaskShortName);
throw createDuplicateException(e);
}
if (t.getPlanningApprovalSteps() != null) {
// Create the planning approval steps
Expand Down Expand Up @@ -156,7 +155,7 @@ public Integer updateTask(@GraphQLRootContext Map<String, Object> context,
// GraphQL mutations *have* to return something, so we return the number of updated rows
return numRows;
} catch (UnableToExecuteStatementException e) {
throw ResponseUtils.handleSqlException(e, duplicateTaskShortName);
throw createDuplicateException(e);
}
}

Expand All @@ -166,4 +165,10 @@ public AnetBeanList<Task> search(@GraphQLRootContext Map<String, Object> context
query.setUser(DaoUtils.getUserFromContext(context));
return dao.search(query);
}

private WebApplicationException createDuplicateException(UnableToExecuteStatementException e) {
final String taskShortLabel = (String) config.getDictionaryEntry("fields.task.shortLabel");
return ResponseUtils.handleSqlException(e,
String.format("Duplicate %s number", taskShortLabel));
}
}
44 changes: 23 additions & 21 deletions src/main/java/mil/dds/anet/threads/AccountDeactivationWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,21 @@
public class AccountDeactivationWorker extends AbstractWorker {

private final PersonDao dao;

private final List<Integer> daysTillEndOfTourWarnings;
private final List<String> ignoredDomainNames;

private final int warningIntervalInSecs;

public AccountDeactivationWorker(AnetConfiguration config, PersonDao dao,
int warningIntervalInSecs) {
super(config,
"Deactivation Warning Worker waking up to check for Future Account Deactivations");
this.dao = dao;

@SuppressWarnings("unchecked")
final List<Integer> daysTillWarning = (List<Integer>) config
.getDictionaryEntry("automaticallyInactivateUsers.emailRemindersDaysPrior");
this.daysTillEndOfTourWarnings =
daysTillWarning.stream().filter(i -> i > 0).collect(Collectors.toList());

@SuppressWarnings("unchecked")
List<String> domainNamesToIgnore =
(List<String>) config.getDictionaryEntry("automaticallyInactivateUsers.ignoredDomainNames");
this.ignoredDomainNames = domainNamesToIgnore == null ? domainNamesToIgnore
: domainNamesToIgnore.stream().map(x -> x.trim()).collect(Collectors.toList());

this.warningIntervalInSecs = warningIntervalInSecs;
}

@Override
protected void runInternal(Instant now, JobHistory jobHistory) {
// Make sure the mechanism will be triggered, so account deactivation checking can take place
final List<String> ignoredDomainNames = getDomainNamesToIgnore();
final List<Integer> daysTillEndOfTourWarnings = getDaysTillEndOfTourWarnings();
final List<Integer> warningDays =
(daysTillEndOfTourWarnings == null || daysTillEndOfTourWarnings.isEmpty())
? new ArrayList<>(0)
Expand Down Expand Up @@ -79,15 +64,32 @@ protected void runInternal(Instant now, JobHistory jobHistory) {
final Integer warning = warningDays.get(i);
final Integer nextWarning = i == warningDays.size() - 1 ? null : warningDays.get(i + 1);
checkDeactivationStatus(p, warning, nextWarning, now,
jobHistory == null ? null : jobHistory.getLastRun());
jobHistory == null ? null : jobHistory.getLastRun(), ignoredDomainNames,
warningIntervalInSecs);
}
});
}

private List<Integer> getDaysTillEndOfTourWarnings() {
@SuppressWarnings("unchecked")
final List<Integer> daysTillWarning = (List<Integer>) config
.getDictionaryEntry("automaticallyInactivateUsers.emailRemindersDaysPrior");
return daysTillWarning.stream().filter(i -> i > 0).collect(Collectors.toList());
}

private List<String> getDomainNamesToIgnore() {
@SuppressWarnings("unchecked")
final List<String> domainNamesToIgnore =
(List<String>) config.getDictionaryEntry("automaticallyInactivateUsers.ignoredDomainNames");
return domainNamesToIgnore == null ? null
: domainNamesToIgnore.stream().map(x -> x.trim()).collect(Collectors.toList());
}

private void checkDeactivationStatus(final Person person, final Integer daysBeforeWarning,
final Integer nextWarning, final Instant now, final Instant lastRun) {
final Integer nextWarning, final Instant now, final Instant lastRun,
final List<String> ignoredDomainNames, final Integer warningIntervalInSecs) {
if (person.getStatus() == Person.Status.INACTIVE
|| Utils.isDomainUserNameIgnored(person.getDomainUsername(), this.ignoredDomainNames)) {
|| Utils.isDomainUserNameIgnored(person.getDomainUsername(), ignoredDomainNames)) {
// Skip inactive ANET users or users from ignored domains
return;
}
Expand All @@ -100,7 +102,7 @@ private void checkDeactivationStatus(final Person person, final Integer daysBefo

final Instant warningDate = now.plus(daysBeforeWarning, ChronoUnit.DAYS);
final Instant prevWarningDate =
(lastRun == null) ? warningDate.minus(this.warningIntervalInSecs, ChronoUnit.SECONDS)
(lastRun == null) ? warningDate.minus(warningIntervalInSecs, ChronoUnit.SECONDS)
: lastRun.plus(daysBeforeWarning, ChronoUnit.DAYS);
if (person.getEndOfTourDate().isBefore(warningDate)
&& person.getEndOfTourDate().isAfter(prevWarningDate)) {
Expand Down
Loading

0 comments on commit dab10ec

Please sign in to comment.