/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.harvest.integration; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import java.util.UUID; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.FacetField; import org.emonocot.api.AnnotationService; import org.emonocot.api.CommentService; import org.emonocot.api.ResourceService; import org.emonocot.api.UserService; import org.emonocot.model.Annotation; import org.emonocot.model.Comment; import org.emonocot.model.auth.User; import org.emonocot.model.registry.Resource; import org.emonocot.pager.Page; import org.joda.time.DateTime; import org.joda.time.Period; import org.joda.time.format.PeriodFormat; import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.listener.JobExecutionListenerSupport; import org.springframework.batch.core.repository.JobRepository; import org.springframework.beans.factory.annotation.Autowired; public class NotifyingJobStatusListener extends JobExecutionListenerSupport { private static Logger logger = LoggerFactory.getLogger(NotifyingJobStatusListener.class); private static final String BUNDLE_NAME = "org.joda.time.format.messages"; private ResourceService resourceService; private AnnotationService annotationService; private UserService userService; private CommentService commentService; private String systemUser; private PeriodFormatter periodFormatter; private JobRepository jobRepository; @Autowired public void setResourceService(ResourceService resourceService) { this.resourceService = resourceService; } @Autowired public void setAnnotationService(AnnotationService annotationService) { this.annotationService = annotationService; } @Autowired public void setUserService(UserService userService) { this.userService = userService; } @Autowired public void setCommentService(CommentService commentService) { this.commentService = commentService; } @Autowired public void setJobRepository(JobRepository jobRepository) { this.jobRepository = jobRepository; } public void setSystemUser(String systemUser) { this.systemUser = systemUser; } public NotifyingJobStatusListener() { ResourceBundle b = ResourceBundle.getBundle(BUNDLE_NAME, Locale.ENGLISH); String[] variants = { b.getString("PeriodFormat.space"), b.getString("PeriodFormat.comma"), b.getString("PeriodFormat.commandand"), b.getString("PeriodFormat.commaspaceand")}; this.periodFormatter = new PeriodFormatterBuilder() .appendYears() .appendSuffix(b.getString("PeriodFormat.year"), b.getString("PeriodFormat.years")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendMonths() .appendSuffix(b.getString("PeriodFormat.month"), b.getString("PeriodFormat.months")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendWeeks() .appendSuffix(b.getString("PeriodFormat.week"), b.getString("PeriodFormat.weeks")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendDays() .appendSuffix(b.getString("PeriodFormat.day"), b.getString("PeriodFormat.days")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendHours() .appendSuffix(b.getString("PeriodFormat.hour"), b.getString("PeriodFormat.hours")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendMinutes() .appendSuffix(b.getString("PeriodFormat.minute"), b.getString("PeriodFormat.minutes")) .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants) .appendSeconds() .appendSuffix(b.getString("PeriodFormat.second"), b.getString("PeriodFormat.seconds")) .toFormatter(); } @Override public void afterJob(JobExecution jobExecution) { Period duration = new Period(jobExecution.getEndTime().getTime() - jobExecution.getStartTime().getTime()); StringBuffer exitDescription = new StringBuffer(); if (jobExecution.getJobInstance().getJobParameters().getString("resource.identifier") != null) { long info = 0; long warn = 0; long error = 0; Resource resource = resourceService.find(jobExecution .getJobInstance().getJobParameters() .getString("resource.identifier")); Map<String, String> selectedFacets = new HashMap<String, String>(); selectedFacets.put("base.class_s", "org.emonocot.model.Annotation"); selectedFacets.put("annotation.job_id_l", new Long(jobExecution.getId()).toString()); try { Page<Annotation> result = annotationService.search(null, null, 1, 0, new String[] { "annotation.type_s" }, null, selectedFacets, null, "annotated-obj"); FacetField annotationTypes = result.getFacetField("annotation.type_s"); for (FacetField.Count value : annotationTypes.getValues()) { if(value.getName() == null) { } else { switch (value.getName()) { case "Info": info = value.getCount(); break; case "Warn": warn = value.getCount(); break; case "Error": error = value.getCount(); break; default: break; } } } } catch (SolrServerException e) { // TODO Auto-generated catch block e.printStackTrace(); } exitDescription.append("Harvested " + resource.getTitle() + " " + jobExecution.getExitStatus().getExitCode()); exitDescription.append(". " + jobExecution.getStepExecutions().size() + " Steps Completed."); exitDescription.append(" Duration: " + periodFormatter.print(duration) + "."); exitDescription.append(" Issues - Info: " + info + ", warnings: " + warn + ", Errors: " + error); jobExecution.setExitStatus(jobExecution.getExitStatus().addExitDescription(exitDescription.toString())); jobRepository.update(jobExecution); logger.info(jobExecution.getExitStatus().getExitCode() + " " + jobExecution.getExitStatus().getExitDescription()); User user = userService.find(systemUser); // Create comment if a systemUser exists if(user != null) { Comment comment = new Comment(); comment.setIdentifier(UUID.randomUUID().toString()); comment.setComment(exitDescription.toString()); comment.setCreated(new DateTime()); comment.setStatus(Comment.Status.PENDING); comment.setUser(user); comment.setAboutData(resource); comment.setCommentPage(resource); commentService.save(comment); } } else { exitDescription.append(jobExecution.getJobInstance().getJobName() + " " + jobExecution.getExitStatus().getExitCode()); exitDescription.append(". " + jobExecution.getStepExecutions().size() + " Steps Completed."); exitDescription.append(" Duration: " + periodFormatter.print(duration) + "."); jobExecution.setExitStatus(new ExitStatus(jobExecution.getExitStatus().getExitCode(),exitDescription.toString())); jobRepository.update(jobExecution); logger.info(jobExecution.getExitStatus().getExitCode() + " " + jobExecution.getExitStatus().getExitDescription()); } } }