package gov.nysenate.openleg.service.process; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import gov.nysenate.openleg.config.Environment; import gov.nysenate.openleg.model.entity.SessionMember; import gov.nysenate.openleg.model.notification.Notification; import gov.nysenate.openleg.model.process.DataProcessErrorEvent; import gov.nysenate.openleg.model.process.DataProcessRun; import gov.nysenate.openleg.model.process.DataProcessUnit; import gov.nysenate.openleg.model.process.DataProcessWarnEvent; import gov.nysenate.openleg.processor.DataProcessor; import gov.nysenate.openleg.service.entity.member.event.UnverifiedMemberEvent; import org.apache.commons.lang3.exception.ExceptionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.time.LocalDateTime; import java.util.Optional; import static gov.nysenate.openleg.model.notification.NotificationType.*; @Service public class DataProcessNotificationService { @Autowired private EventBus eventBus; @Autowired Environment environment; @Autowired DataProcessor dataProcessor; private static final String dataProcessRunPath = "/api/3/admin/process/runs/id"; @PostConstruct public void init() { eventBus.register(this); } /** * Generates and dispatches a data process exception notification based on an exception * @param ex Throwable */ public void exceptionNotification(Throwable ex, int dataProcessId) { LocalDateTime occurred = LocalDateTime.now(); String summary = "Processing Exception at " + occurred + " - " + ExceptionUtils.getStackFrames(ex)[0]; String message = getDataProcessRunUrl(dataProcessId) + "\nThe following exception occurred while processing data at " + occurred + ":\n" + ExceptionUtils.getStackTrace(ex); Notification notification = new Notification(PROCESS_EXCEPTION, occurred, summary, message); eventBus.post(notification); } public void warningNotification(String warning, int dataProcessId, DataProcessUnit unit) { LocalDateTime occurred = unit.getEndDateTime(); String summary = "Non-fatal Processing exception at " + occurred; String message = getDataProcessRunUrl(dataProcessId) + "\n" + "action: " + unit.getAction() + " " + unit.getSourceType() + ": " + unit.getSourceId() + "\n" + "The following non-fatal exception occurred while processing data at " + occurred + ":\n" + warning; Notification notification = new Notification(PROCESS_WARNING, occurred, summary, message); eventBus.post(notification); } public void unverifiedMemberNotification(SessionMember member) { Optional<DataProcessRun> run = dataProcessor.getCurrentRun(); LocalDateTime occurred = LocalDateTime.now(); String summary = "New unverified session member: " + member.getLbdcShortName(); String message = "A new unverified session member has been created" + (run.isPresent() ? " during data processing" : "") + "\n" + (run.isPresent() ? getDataProcessRunUrl(run.get().getProcessId()) + "\n" : "") + "shortname: " + member.getLbdcShortName() + "\n" + "chamber: " + member.getChamber()+ "\n" + "session: " + member.getSessionYear(); Notification notification = new Notification(UNVERIFIED_MEMBER, occurred, summary, message); eventBus.post(notification); } @Subscribe public void handleDataProcessErrorEvent(DataProcessErrorEvent event) { exceptionNotification(event.getEx(), event.getProcessRunId()); } @Subscribe public void handleDataProcessWarnEvent(DataProcessWarnEvent event) { event.getUnit().getErrors() .forEach(warning -> warningNotification(warning, event.getDataProcessId(), event.getUnit())); } @Subscribe public void handleUnverifiedMemberEvent(UnverifiedMemberEvent event) { unverifiedMemberNotification(event.getMember()); } private String getDataProcessRunUrl(int dataProcessId) { return environment.getUrl() + dataProcessRunPath + "/" + dataProcessId; } }