use of gov.cms.ab2d.coverage.model.CoveragePeriod in project ab2d by CMSgov.
the class CoverageServiceImpl method failSearch.
@Override
public CoverageSearchEvent failSearch(int periodId, String description) {
CoveragePeriod period = findCoveragePeriod(periodId);
CoverageJobStatus coverageJobStatus = period.getStatus();
if (coverageJobStatus != CoverageJobStatus.IN_PROGRESS) {
throw new InvalidJobStateTransition("cannot change from " + coverageJobStatus + " to " + CoverageJobStatus.FAILED);
}
try {
// Delete all results from current search that is failing
coverageServiceRepo.deleteCurrentSearch(period);
} catch (Exception exception) {
String issue = String.format(COVERAGE_DELETE_FAILED + " Failed to delete coverage for a failed search for %s-%d-%d. " + "There could be duplicate enrollment data in the db", period.getContractNumber(), period.getYear(), period.getMonth());
eventLogger.alert(issue, PUBLIC_LIST);
throw exception;
}
// Before finishing up alert AB2D team that there could be a problem with enrollment
String issue = String.format(COVERAGE_UPDATE_FAILED + " Failed to update coverage for %s-%d-%d." + " There could be out of date enrollment data in the db", period.getContractNumber(), period.getYear(), period.getMonth());
eventLogger.alert(issue, PUBLIC_LIST);
return updateStatus(period, description, CoverageJobStatus.FAILED);
}
use of gov.cms.ab2d.coverage.model.CoveragePeriod in project ab2d by CMSgov.
the class CoverageDriverImpl method isCoverageAvailable.
/**
* Determine whether database contains all necessary enrollment for a contract and that no updates to that
* enrollment are currently occurring.
*
* Steps
* - Lock coverage so no other workers can modify coverage while this check is occurring
* - Create any {@link CoveragePeriod}s that are currently missing
* - Check the following to determine whether a job can run (return false if any are not met)
* - Look for whether months have failed to update during earlier attempts
* - Look for coverage periods that have never been successfully searched and queue them
* - Look for coverage periods currently being updated
*
* @param job job to check for coverage
* @throws CoverageDriverException if enrollment state violates assumed preconditions or database lock cannot be retrieved
* @throws InterruptedException if trying to lock the table is interrupted
*/
@Trace(metricName = "EnrollmentIsAvailable", dispatcher = true)
@Override
public boolean isCoverageAvailable(Job job, ContractDTO contract) throws InterruptedException {
String contractNumber = job.getContractNumber();
assert contractNumber.equals(contract.getContractNumber());
Lock coverageLock = coverageLockWrapper.getCoverageLock();
// Track whether locked or not to prevent an illegal monitor exception
boolean locked = false;
try {
locked = coverageLock.tryLock(MINUTE, TimeUnit.MINUTES);
if (!locked) {
log.warn("Could not retrieve lock after timeout of {} minute(s)." + " Cannot confirm coverage metadata is available", MINUTE);
return false;
}
// Check whether a coverage period is missing for this contract.
// If so then create those coverage periods.
discoverCoveragePeriods(mapping.map(contract));
log.info("queueing never searched coverage metadata periods for {}", contractNumber);
/*
* If any relevant coverage period has never been pulled from BFD successfully then automatically fail the
* search
*/
List<CoveragePeriod> neverSearched = coverageService.coveragePeriodNeverSearchedSuccessfully().stream().filter(period -> Objects.equals(contract.getContractNumber(), period.getContractNumber())).toList();
if (!neverSearched.isEmpty()) {
// Check that we've not submitted and failed these jobs
neverSearched.forEach(period -> checkCoveragePeriodValidity(job, period));
// Add all never searched coverage periods to the queue for processing
neverSearched.forEach(period -> coverageProcessor.queueCoveragePeriod(period, false));
return false;
}
log.info("checking whether any coverage metadata is currently being updated for {}", contractNumber);
/*
* If coverage periods are submitted, in progress or null then ignore for the moment.
*
* There will always be at least one coverage period returned.
*/
List<CoveragePeriod> periods = coverageService.findAssociatedCoveragePeriods(contract.getContractNumber());
if (periods.isEmpty()) {
log.error("There are no existing coverage periods for this job so no metadata exists");
throw new CoverageDriverException("There are no existing coverage periods for this job so no ");
}
return periods.stream().map(CoveragePeriod::getStatus).noneMatch(status -> status == null || status == CoverageJobStatus.IN_PROGRESS || status == CoverageJobStatus.SUBMITTED);
} catch (InterruptedException interruptedException) {
log.error("Interrupted attempting to retrieve lock. Cannot confirm coverage metadata is available");
throw interruptedException;
} finally {
if (locked) {
coverageLock.unlock();
}
}
}
use of gov.cms.ab2d.coverage.model.CoveragePeriod in project ab2d by CMSgov.
the class CoverageDriverImpl method findAndCancelStuckCoverageJobs.
private Set<CoveragePeriod> findAndCancelStuckCoverageJobs() {
log.info("attempting to find all stuck coverage searches and then cancel those stuck coverage searches");
CoverageUpdateConfig config = retrieveConfig();
Set<CoveragePeriod> stuckJobs = new LinkedHashSet<>(coverageService.coveragePeriodStuckJobs(OffsetDateTime.now(ZoneOffset.UTC).minusHours(config.getStuckHours())));
for (CoveragePeriod period : stuckJobs) {
coverageService.failSearch(period.getId(), "coverage period current job has been stuck for at least " + config.getStuckHours() + " hours and is now considered failed.");
}
return stuckJobs;
}
use of gov.cms.ab2d.coverage.model.CoveragePeriod in project ab2d by CMSgov.
the class CoverageDriverImpl method numberOfBeneficiariesToProcess.
/**
* Determine number of beneficiaries enrolled in the contract which should be pulled from the database
* and queried from BFD.
*
* Get all coverage periods associated with a contract and then find all unique beneficiaries between
* those coverage periods.
*
* @throws CoverageDriverException job has no contract which should not be possible
*/
@Trace(metricName = "EnrollmentCount", dispatcher = true)
@Override
public int numberOfBeneficiariesToProcess(Job job, ContractDTO contract) {
ZonedDateTime now = getEndDateTime();
if (contract == null) {
throw new CoverageDriverException("cannot retrieve metadata for job missing contract");
}
ZonedDateTime startDateTime = getStartDateTime(contract);
List<CoveragePeriod> periodsToReport = new ArrayList<>();
while (startDateTime.isBefore(now)) {
CoveragePeriod periodToReport = coverageService.getCoveragePeriod(mapping.map(contract), startDateTime.getMonthValue(), startDateTime.getYear());
periodsToReport.add(periodToReport);
startDateTime = startDateTime.plusMonths(1);
}
log.info("counting number of beneficiaries for {} coverage periods for job {}", periodsToReport.size(), job.getJobUuid());
return coverageService.countBeneficiariesByCoveragePeriod(periodsToReport);
}
use of gov.cms.ab2d.coverage.model.CoveragePeriod in project ab2d by CMSgov.
the class CoverageDriverImpl method queueStaleCoveragePeriods.
/**
* Find all work that needs to be done including new coverage periods, jobs that have been running too long,
* and coverage information that is too old.
*
* @throws InterruptedException if is interrupted by a shutdown
* @throws CoverageDriverException on failure to acquire lock programmatically
*/
@Override
public void queueStaleCoveragePeriods() throws InterruptedException {
Lock lock = coverageLockWrapper.getCoverageLock();
boolean locked = false;
try {
Set<CoveragePeriod> outOfDateInfo = getCoveragePeriods();
log.info("queueing all stale coverage periods");
/*
* Guarantee that no other worker node is also trying to start or update queued searches
*/
locked = lock.tryLock(TEN_MINUTES, TimeUnit.MINUTES);
if (locked) {
for (CoveragePeriod period : outOfDateInfo) {
log.info("Attempting to add {}-{}-{} to queue", period.getContractNumber(), period.getYear(), period.getMonth());
}
for (CoveragePeriod period : outOfDateInfo) {
coverageProcessor.queueCoveragePeriod(period, false);
}
log.info("queued all stale coverage periods");
} else {
throw new CoverageDriverException("could not retrieve lock to update stale coverage periods");
}
} catch (InterruptedException interruptedException) {
log.error("locking interrupted so stale coverage periods could not be updated");
throw interruptedException;
} finally {
if (locked) {
lock.unlock();
}
}
}
Aggregations