Search in sources :

Example 26 with CoveragePeriod

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);
}
Also used : CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod) CoverageJobStatus(gov.cms.ab2d.coverage.model.CoverageJobStatus) EntityNotFoundException(javax.persistence.EntityNotFoundException)

Example 27 with CoveragePeriod

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();
        }
    }
}
Also used : Trace(com.newrelic.api.agent.Trace) ContractForCoverageDTO(gov.cms.ab2d.coverage.model.ContractForCoverageDTO) ZonedDateTime(java.time.ZonedDateTime) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) Constants(gov.cms.ab2d.common.util.Constants) Scheduled(org.springframework.scheduling.annotation.Scheduled) CoverageUtils.getEndDateTime(gov.cms.ab2d.worker.processor.coverage.CoverageUtils.getEndDateTime) CoverageJobStatus(gov.cms.ab2d.coverage.model.CoverageJobStatus) ArrayList(java.util.ArrayList) CoveragePagingRequest(gov.cms.ab2d.coverage.model.CoveragePagingRequest) CoveragePresentCheck(gov.cms.ab2d.worker.processor.coverage.check.CoveragePresentCheck) CoverageCount(gov.cms.ab2d.coverage.model.CoverageCount) CoverageNoDuplicatesCheck(gov.cms.ab2d.worker.processor.coverage.check.CoverageNoDuplicatesCheck) Service(org.springframework.stereotype.Service) AB2D_ZONE(gov.cms.ab2d.common.util.DateUtil.AB2D_ZONE) Map(java.util.Map) CoverageStableCheck(gov.cms.ab2d.worker.processor.coverage.check.CoverageStableCheck) ContractToContractCoverageMapping(gov.cms.ab2d.worker.config.ContractToContractCoverageMapping) ZoneOffset(java.time.ZoneOffset) ContractDTO(gov.cms.ab2d.common.dto.ContractDTO) LinkedHashSet(java.util.LinkedHashSet) DateUtil(gov.cms.ab2d.common.util.DateUtil) Contract(gov.cms.ab2d.common.model.Contract) Job(gov.cms.ab2d.common.model.Job) CoverageSearchRepository(gov.cms.ab2d.coverage.repository.CoverageSearchRepository) CoveragePagingResult(gov.cms.ab2d.coverage.model.CoveragePagingResult) CoverageUpToDateCheck(gov.cms.ab2d.worker.processor.coverage.check.CoverageUpToDateCheck) Set(java.util.Set) CoverageUtils.getAttestationTime(gov.cms.ab2d.worker.processor.coverage.CoverageUtils.getAttestationTime) CoverageService(gov.cms.ab2d.coverage.service.CoverageService) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AB2D_EPOCH(gov.cms.ab2d.common.util.DateUtil.AB2D_EPOCH) List(java.util.List) Lock(java.util.concurrent.locks.Lock) Slf4j(lombok.extern.slf4j.Slf4j) OffsetDateTime(java.time.OffsetDateTime) ChronoUnit(java.time.temporal.ChronoUnit) DayOfWeek(java.time.DayOfWeek) PropertiesService(gov.cms.ab2d.common.service.PropertiesService) CoveragePeriodsPresentCheck(gov.cms.ab2d.worker.processor.coverage.check.CoveragePeriodsPresentCheck) PdpClientService(gov.cms.ab2d.common.service.PdpClientService) CoverageMapping(gov.cms.ab2d.coverage.model.CoverageMapping) CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod) TemporalAdjusters(java.time.temporal.TemporalAdjusters) Optional(java.util.Optional) CoverageSearch(gov.cms.ab2d.coverage.model.CoverageSearch) CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod) Lock(java.util.concurrent.locks.Lock) Trace(com.newrelic.api.agent.Trace)

Example 28 with CoveragePeriod

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;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod)

Example 29 with CoveragePeriod

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);
}
Also used : ZonedDateTime(java.time.ZonedDateTime) CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod) ArrayList(java.util.ArrayList) Trace(com.newrelic.api.agent.Trace)

Example 30 with CoveragePeriod

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();
        }
    }
}
Also used : CoveragePeriod(gov.cms.ab2d.coverage.model.CoveragePeriod) Lock(java.util.concurrent.locks.Lock)

Aggregations

CoveragePeriod (gov.cms.ab2d.coverage.model.CoveragePeriod)62 Test (org.junit.jupiter.api.Test)40 DisplayName (org.junit.jupiter.api.DisplayName)38 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)25 CoverageSearchEvent (gov.cms.ab2d.coverage.model.CoverageSearchEvent)22 ContractDTO (gov.cms.ab2d.common.dto.ContractDTO)20 CoverageSearch (gov.cms.ab2d.coverage.model.CoverageSearch)19 OffsetDateTime (java.time.OffsetDateTime)18 CoverageJobStatus (gov.cms.ab2d.coverage.model.CoverageJobStatus)15 CoverageMapping (gov.cms.ab2d.coverage.model.CoverageMapping)15 ContractToContractCoverageMapping (gov.cms.ab2d.worker.config.ContractToContractCoverageMapping)14 ContractForCoverageDTO (gov.cms.ab2d.coverage.model.ContractForCoverageDTO)12 Identifiers (gov.cms.ab2d.coverage.model.Identifiers)11 ZonedDateTime (java.time.ZonedDateTime)11 ArrayList (java.util.ArrayList)11 LinkedHashSet (java.util.LinkedHashSet)11 Job (gov.cms.ab2d.common.model.Job)10 AB2D_EPOCH (gov.cms.ab2d.common.util.DateUtil.AB2D_EPOCH)9 CoveragePagingRequest (gov.cms.ab2d.coverage.model.CoveragePagingRequest)9 CoveragePagingResult (gov.cms.ab2d.coverage.model.CoveragePagingResult)9