001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.extraction.execution; 017 018import java.io.File; 019import java.time.ZonedDateTime; 020import java.time.format.DateTimeFormatter; 021import java.util.Collections; 022import java.util.Map; 023import java.util.regex.Pattern; 024 025import javax.mail.MessagingException; 026 027import org.apache.avalon.framework.activity.Initializable; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.commons.lang3.StringUtils; 031import org.apache.commons.lang3.exception.ExceptionUtils; 032import org.quartz.JobDataMap; 033import org.quartz.JobExecutionContext; 034 035import org.ametys.core.schedule.Schedulable; 036import org.ametys.core.util.I18nUtils; 037import org.ametys.core.util.JSONUtils; 038import org.ametys.core.util.mail.SendMailHelper; 039import org.ametys.plugins.core.impl.schedule.AbstractStaticSchedulable; 040import org.ametys.plugins.core.schedule.Scheduler; 041import org.ametys.plugins.extraction.ExtractionConstants; 042import org.ametys.plugins.extraction.execution.pipeline.PipelineDescriptor; 043import org.ametys.plugins.extraction.execution.pipeline.PipelineManager; 044import org.ametys.runtime.config.Config; 045import org.ametys.runtime.i18n.I18nizableText; 046 047/** 048 * A {@link Schedulable} job which execute an extraction 049 */ 050public class ExecuteExtractionSchedulable extends AbstractStaticSchedulable implements Initializable 051{ 052 /** The key for the extraction definition file */ 053 public static final String DEFINITION_FILE_PATH_KEY = "definitionFilePath"; 054 /** The key for the variables values */ 055 public static final String VARIABLES_KEY = "variables"; 056 /** The key for the recipient */ 057 public static final String RECIPIENT_KEY = "recipient"; 058 /** The key for the pipeline */ 059 public static final String PIPELINE_KEY = "pipeline"; 060 061 private static final String __JOBDATAMAP_DEFINITION_FILE_PATH_KEY = Scheduler.PARAM_VALUES_PREFIX + DEFINITION_FILE_PATH_KEY; 062 private static final String __JOBDATAMAP_VARIABLES_KEY = Scheduler.PARAM_VALUES_PREFIX + VARIABLES_KEY; 063 private static final String __JOBDATAMAP_RECIPIENT_KEY = Scheduler.PARAM_VALUES_PREFIX + RECIPIENT_KEY; 064 private static final String __JOBDATAMAP_PIPELINE_KEY = Scheduler.PARAM_VALUES_PREFIX + PIPELINE_KEY; 065 066 private static final DateTimeFormatter RESULT_FILE_NAME_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd'T'HH.mm.ss"); 067 068 private JSONUtils _jsonUtils; 069 private I18nUtils _i18nUtils; 070 private String _mailFrom; 071 private PipelineManager _pipelineManager; 072 private ExtractionExecutor _extractionExecutor; 073 074 @Override 075 public void service(ServiceManager manager) throws ServiceException 076 { 077 super.service(manager); 078 _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE); 079 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 080 _pipelineManager = (PipelineManager) manager.lookup(PipelineManager.ROLE); 081 _extractionExecutor = (ExtractionExecutor) manager.lookup(ExtractionExecutor.ROLE); 082 } 083 084 @Override 085 public void initialize() throws Exception 086 { 087 _mailFrom = Config.getInstance().getValue("smtp.mail.from"); 088 } 089 090 @Override 091 public void execute(JobExecutionContext context) throws Exception 092 { 093 JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); 094 String definitionFilePath = jobDataMap.getString(__JOBDATAMAP_DEFINITION_FILE_PATH_KEY); 095 096 // Get email address to send one when the extraction is complete (or if there is an error) 097 String recipient = jobDataMap.getString(__JOBDATAMAP_RECIPIENT_KEY); 098 099 String mailBody = null; 100 try 101 { 102 PipelineDescriptor pipeline = _pipelineManager.get(jobDataMap.getString(__JOBDATAMAP_PIPELINE_KEY)); 103 String defaultResultFileName = _getResultFileName(definitionFilePath, pipeline); 104 Map<String, Object> parameters = _getExtractionParameters(jobDataMap); 105 String lang = (String) parameters.get("lang"); 106 _extractionExecutor.execute(definitionFilePath, defaultResultFileName, lang, parameters, pipeline); 107 108 mailBody = _getSuccessMailBody(definitionFilePath); 109 } 110 catch (Exception e) 111 { 112 mailBody = _getFailureMailBody(definitionFilePath, e); 113 throw e; 114 } 115 finally 116 { 117 if (!StringUtils.isEmpty(recipient)) 118 { 119 _sendMail(recipient, mailBody); 120 } 121 } 122 } 123 124 private Map<String, Object> _getExtractionParameters(JobDataMap jobDataMap) 125 { 126 // variables parameters 127 String variablesAsString = jobDataMap.getString(__JOBDATAMAP_VARIABLES_KEY); 128 Map<String, Object> variablesAsMap = _jsonUtils.convertJsonToMap(variablesAsString); 129 return variablesAsMap; 130 } 131 132 private String _getResultFileName(String definitionFilePath, PipelineDescriptor pipeline) 133 { 134 String[] definitionFilePathSegments = definitionFilePath.split(Pattern.quote(File.separator)); 135 String definitionFileName = definitionFilePathSegments[definitionFilePathSegments.length - 1]; 136 137 int lastIndexOfDot = definitionFileName.lastIndexOf('.'); 138 if (-1 != lastIndexOfDot) 139 { 140 definitionFileName = definitionFileName.substring(0, lastIndexOfDot); 141 } 142 143 String extractionDate = ZonedDateTime.now().format(RESULT_FILE_NAME_DATE_TIME_FORMATTER); 144 145 StringBuilder resultFileName = new StringBuilder(); 146 resultFileName.append(definitionFileName).append("-").append(extractionDate); 147 resultFileName.append(".").append(pipeline.getDefaultExtension()); 148 return resultFileName.toString(); 149 } 150 151 private String _getSuccessMailBody(String definitionFileName) 152 { 153 I18nizableText bodyKey = new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_MAIL_SUCCESS_BODY", Collections.singletonList(definitionFileName)); 154 return _i18nUtils.translate(bodyKey, null); // FIXME Use user preference language 155 } 156 157 private String _getFailureMailBody (String definitionFileName, Throwable exception) 158 { 159 StringBuilder body = new StringBuilder(); 160 161 I18nizableText bodyKey = new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_MAIL_FAILURE_BODY", Collections.singletonList(definitionFileName)); 162 String intro = _i18nUtils.translate(bodyKey, null); // FIXME Use user preference language 163 164 body.append(intro).append("\n\n").append(ExceptionUtils.getStackTrace(exception)); 165 return body.toString(); 166 } 167 168 private void _sendMail(String recipient, String body) 169 { 170 String subject = _getMailSubject(); 171 try 172 { 173 SendMailHelper.sendMail(subject, null, body, recipient, _mailFrom); 174 } 175 catch (MessagingException e) 176 { 177 if (getLogger().isWarnEnabled()) 178 { 179 getLogger().warn("Fail to send email to " + recipient, e); 180 } 181 } 182 } 183 184 private String _getMailSubject () 185 { 186 I18nizableText subjectKey = new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_MAIL_SUBJECT"); 187 return _i18nUtils.translate(subjectKey, null); // FIXME Use user preference language 188 } 189}