PaymentCycleScheduler.java
package uk.gov.dhsc.htbhf.claimant.scheduler;
import lombok.extern.slf4j.Slf4j;
import net.javacrumbs.shedlock.core.SchedulerLock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import uk.gov.dhsc.htbhf.claimant.repository.ClosingPaymentCycle;
import uk.gov.dhsc.htbhf.claimant.repository.PaymentCycleRepository;
import uk.gov.dhsc.htbhf.requestcontext.aop.NewRequestContextWithSessionId;
import java.time.LocalDate;
import java.util.List;
import static uk.gov.dhsc.htbhf.logging.ExceptionDetailGenerator.constructExceptionDetail;
/**
* Responsible for creating new {@link uk.gov.dhsc.htbhf.claimant.entity.PaymentCycle} objects
* for active claims whose current PaymentCycle is due to come to an end
* (ending on or before [today + end-date-offset-days]).
* This scheduler simply invokes the CreateNewPaymentCycleJob for each such claim.
*/
@Slf4j
@Component
public class PaymentCycleScheduler {
private final PaymentCycleRepository paymentCycleRepository;
private final CreateNewPaymentCycleJob job;
private final int endDateOffsetDays;
public PaymentCycleScheduler(
PaymentCycleRepository paymentCycleRepository,
CreateNewPaymentCycleJob job,
@Value("${payment-cycle.schedule.end-date-offset-days}") int endDateOffsetDays) {
this.paymentCycleRepository = paymentCycleRepository;
this.job = job;
this.endDateOffsetDays = endDateOffsetDays;
}
@Scheduled(cron = "${payment-cycle.schedule.cron-schedule}")
@SchedulerLock(
name = "Create new payment cycles",
lockAtLeastForString = "${payment-cycle.schedule.minimum-lock-time}",
lockAtMostForString = "${payment-cycle.schedule.maximum-lock-time}")
@NewRequestContextWithSessionId(sessionId = "PaymentCycleScheduler")
public void createNewPaymentCycles() {
LocalDate cycleEndDate = LocalDate.now().plusDays(endDateOffsetDays);
log.trace("Querying for active claims with cycles ending on {}", cycleEndDate);
List<ClosingPaymentCycle> cycles = paymentCycleRepository.findActiveClaimsWithCycleEndingOnOrBefore(cycleEndDate);
if (CollectionUtils.isEmpty(cycles)) {
log.trace("No new PaymentCycles to create");
} else {
log.info("Creating new PaymentCycles for {} claims", cycles.size());
cycles.forEach(this::createNewPaymentCycle);
log.debug("Finished creating new PaymentCycles for {} claims", cycles.size());
}
}
private void createNewPaymentCycle(ClosingPaymentCycle cycle) {
try {
job.createNewPaymentCycle(cycle.getClaimId(), cycle.getCycleId(), cycle.getCycleEndDate().plusDays(1));
} catch (RuntimeException e) {
log.error("Unable to create new payment cycle for claim {}: {}", cycle.getClaimId(), constructExceptionDetail(e), e);
}
}
}