package gov.nysenate.openleg.service.spotcheck.base; import com.google.common.collect.*; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import gov.nysenate.openleg.config.Environment; import gov.nysenate.openleg.model.spotcheck.ReferenceDataNotFoundEx; import gov.nysenate.openleg.model.spotcheck.SpotCheckRefType; import gov.nysenate.openleg.model.spotcheck.SpotCheckReferenceEvent; import gov.nysenate.openleg.model.spotcheck.SpotCheckReport; import gov.nysenate.openleg.service.spotcheck.agenda.AgendaReportService; import gov.nysenate.openleg.service.spotcheck.billtext.BillTextReportService; import gov.nysenate.openleg.service.spotcheck.calendar.CalendarReportService; import gov.nysenate.openleg.service.spotcheck.daybreak.DaybreakReportService; import gov.nysenate.openleg.service.spotcheck.senatesite.agenda.AgendaReportServices; import gov.nysenate.openleg.service.spotcheck.senatesite.bill.BillReportService; import gov.nysenate.openleg.service.spotcheck.senatesite.calendar.CalendarReportServices; import gov.nysenate.openleg.util.DateUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.time.LocalDateTime; import static gov.nysenate.openleg.model.spotcheck.SpotCheckRefType.*; /** * Runs spotcheck reports based on scheduling and events */ @Service public class SpotcheckRunService { private static final Logger logger = LoggerFactory.getLogger(SpotcheckRunService.class); @Autowired private Environment env; @Autowired private EventBus eventBus; @Autowired private SpotCheckNotificationService spotCheckNotificationService; /** A multimap of reports that run whenever pertinent references are generated */ SetMultimap<SpotCheckRefType, SpotCheckReportService> eventTriggeredReports; /** --- Report Services --- */ /** Agenda Report Services */ @Autowired private AgendaReportService agendaReportService; /** Bill Report Services */ @Autowired private DaybreakReportService daybreakReportService; @Autowired private BillTextReportService billTextReportService; /** Calendar Report Services */ @Autowired private CalendarReportService calendarReportService; /** Nysenate.gov Report Services */ @Autowired private BillReportService senSiteBillReportService; @Autowired private CalendarReportServices senSiteCalReportService; @Autowired private AgendaReportServices senSiteAgendaReportService; @PostConstruct public void init() { eventBus.register(this); eventTriggeredReports = ImmutableSetMultimap.<SpotCheckRefType, SpotCheckReportService>builder() .put(LBDC_AGENDA_ALERT, agendaReportService) .put(LBDC_DAYBREAK, daybreakReportService) .put(LBDC_SCRAPED_BILL, billTextReportService) .put(LBDC_CALENDAR_ALERT, calendarReportService) .put(SENATE_SITE_BILLS, senSiteBillReportService) .put(SENATE_SITE_CALENDAR, senSiteCalReportService) .put(SENATE_SITE_AGENDA,senSiteAgendaReportService) .build(); } /** * Given a spotcheck reference event, runs all reports that use the event's spotcheck reference type * @param referenceEvent SpotCheckReferenceEvent */ @Subscribe public synchronized void handleSpotcheckReferenceEvent(SpotCheckReferenceEvent referenceEvent) { runReports(referenceEvent.getRefType()); } /** * Run all reports that use the give reference type for the given date time range * * @param refType SpotCheckRefType * @param reportRange Range<LocalDateTime> */ public synchronized void runReports(SpotCheckRefType refType, Range<LocalDateTime> reportRange) { eventTriggeredReports.get(refType) .forEach(reportService -> runReport(reportService, reportRange)); } /** * Run all reports that use the given reference type * * @param refType SpotCheckRefType */ public synchronized void runReports(SpotCheckRefType refType) { runReports(refType, DateUtils.ALL_DATE_TIMES); } /** --- Internal Methods --- */ private <T> void runReport(SpotCheckReportService<T> reportService, Range<LocalDateTime> reportRange) { logger.info("Attempting to run a {} report..", reportService.getSpotcheckRefType()); try { SpotCheckReport<T> report = reportService.generateReport( DateUtils.startOfDateTimeRange(reportRange), DateUtils.endOfDateTimeRange(reportRange)); int notesCutoff = 140; // Cut off the notes in the display after this many characters logger.info("Saving report: {} {} {}", report.getReportDateTime(), report.getReferenceType(), report.getNotes() != null ? StringUtils.substring(report.getNotes(), 0, notesCutoff) + (report.getNotes().length() > notesCutoff ? "..." : "") : ""); reportService.saveReport(report); spotCheckNotificationService.spotcheckCompleteNotification(report); } catch (ReferenceDataNotFoundEx ex) { logger.info("No report generated: no {} references could be found. Message: " + ex.getMessage(), reportService.getSpotcheckRefType()); } catch (Exception ex) { spotCheckNotificationService.handleSpotcheckException(ex, true); } } }