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.util.HashMap; 020import java.util.LinkedHashMap; 021import java.util.List; 022import java.util.Map; 023import java.util.Map.Entry; 024 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.commons.lang.StringUtils; 028import org.apache.excalibur.source.Source; 029import org.apache.excalibur.source.SourceResolver; 030import org.apache.excalibur.source.impl.FileSource; 031import org.quartz.JobKey; 032import org.quartz.SchedulerException; 033 034import org.ametys.core.schedule.Runnable; 035import org.ametys.core.ui.Callable; 036import org.ametys.core.ui.StaticClientSideElement; 037import org.ametys.core.user.User; 038import org.ametys.core.user.UserIdentity; 039import org.ametys.core.user.UserManager; 040import org.ametys.core.util.JSONUtils; 041import org.ametys.plugins.core.schedule.Scheduler; 042import org.ametys.plugins.extraction.ExtractionConstants; 043import org.ametys.plugins.extraction.execution.pipeline.PipelineManager; 044import org.ametys.runtime.i18n.I18nizableText; 045 046/** 047 * This client site element creates a button to execute an extraction 048 */ 049public class ExecuteExtractionClientSideElement extends StaticClientSideElement 050{ 051 private UserManager _userManager; 052 private ExtractionDefinitionReader _reader; 053 private SourceResolver _sourceResolver; 054 private JSONUtils _jsonUtils; 055 private Scheduler _scheduler; 056 private PipelineManager _pipelineManager; 057 058 @Override 059 public void service(ServiceManager serviceManager) throws ServiceException 060 { 061 super.service(serviceManager); 062 _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE); 063 _reader = (ExtractionDefinitionReader) serviceManager.lookup(ExtractionDefinitionReader.ROLE); 064 _sourceResolver = (SourceResolver) serviceManager.lookup(SourceResolver.ROLE); 065 _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE); 066 _scheduler = (Scheduler) serviceManager.lookup(Scheduler.ROLE); 067 _pipelineManager = (PipelineManager) serviceManager.lookup(PipelineManager.ROLE); 068 } 069 070 /** 071 * Retrieve needed extraction parameters. 072 * @param definitionFile The extraction definition file path 073 * @return a <code>Map</code> containing parameters infos used to configure form to fill the parameters 074 * @throws Exception if an error occurs 075 */ 076 @Callable (right = ExtractionConstants.EXECUTE_EXTRACTION_RIGHT_ID) 077 public Map<String, Object> getExecutionParameters(String definitionFile) throws Exception 078 { 079 Map<String, Object> executionParameters = new LinkedHashMap<>(); 080 081 String definitionFilePath = ExtractionConstants.DEFINITIONS_DIR + definitionFile; 082 Source src = _sourceResolver.resolveURI(definitionFilePath); 083 File file = ((FileSource) src).getFile(); 084 085 if (!file.exists()) 086 { 087 throw new IllegalArgumentException("The file " + definitionFilePath + " does not exist."); 088 } 089 090 executionParameters.put("pipeline", _getPipelineInputConfig(definitionFile)); 091 092 Extraction extraction = _reader.readExtractionDefinitionFile(file); 093 094 Map<String, String> clasuesVariables = extraction.getQueryVariablesNamesAndContentTypes(); 095 List<String> optionalColumns = extraction.getDisplayOptionalColumnsNames(); 096 097 if (!clasuesVariables.isEmpty()) 098 { 099 Map<String, Object> clausesVariablesFieldSet = new HashMap<>(); 100 clausesVariablesFieldSet.put("role", "fieldset"); 101 clausesVariablesFieldSet.put("label", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_CLAUSES_VARIABLES_FIELDSET_LABEL")); 102 103 Map<String, Object> clausesVariablesFieldSetElements = new HashMap<>(); 104 for (Map.Entry<String, String> clausesVariable : clasuesVariables.entrySet()) 105 { 106 clausesVariablesFieldSetElements.put(clausesVariable.getKey(), _getClauseVariableInputConfig(clausesVariable)); 107 } 108 clausesVariablesFieldSet.put("elements", clausesVariablesFieldSetElements); 109 110 executionParameters.put("clausesVariables", clausesVariablesFieldSet); 111 } 112 113 if (!optionalColumns.isEmpty()) 114 { 115 Map<String, Object> optionalColumnsFieldSet = new HashMap<>(); 116 optionalColumnsFieldSet.put("role", "fieldset"); 117 optionalColumnsFieldSet.put("label", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_OPTIONAL_COLUMNS_FIELDSET_LABEL")); 118 119 Map<String, Object> optionalColumnsFieldSetElements = new HashMap<>(); 120 for (String optionalColumn : optionalColumns) 121 { 122 optionalColumnsFieldSetElements.put(optionalColumn, _getOptionalColumnsInputConfig(optionalColumn)); 123 } 124 optionalColumnsFieldSet.put("elements", optionalColumnsFieldSetElements); 125 126 executionParameters.put("optionalColumns", optionalColumnsFieldSet); 127 } 128 129 executionParameters.put("recipient", _getRecipientInputConfig()); 130 131 return executionParameters; 132 } 133 134 private Map<String, Object> _getPipelineInputConfig(String definitionFile) 135 { 136 Map<String, Object> inputConfig = new HashMap<>(); 137 138 inputConfig.put("label", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_PIPELINE_INPUT_LABEL")); 139 inputConfig.put("description", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_PIPELINE_INPUT_DESCRIPTION")); 140 inputConfig.put("type", "string"); 141 142 inputConfig.put("default-value", _pipelineManager.getDefaultPipeline()); 143 inputConfig.put("validation", _getMandatoryValidation()); 144 145 inputConfig.put("widget", "edition.select-pipeline"); 146 147 Map<String, Object> widgetParams = new HashMap<>(); 148 widgetParams.put("extraction", definitionFile); 149 inputConfig.put("widget-params", widgetParams); 150 151 return inputConfig; 152 } 153 154 private Map<String, Object> _getClauseVariableInputConfig(Entry<String, String> clausesVariable) 155 { 156 Map<String, Object> inputConfig = new HashMap<>(); 157 158 inputConfig.put("label", clausesVariable.getKey()); 159 inputConfig.put("description", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_CLAUSES_VARIABLE_INPUTS_DESCRIPTION")); 160 161 inputConfig.put("type", "content"); 162 inputConfig.put("widget", "edition.select-content"); 163 inputConfig.put("multiple", true); 164 165 Map<String, Object> widgetParams = new HashMap<>(); 166 widgetParams.put("contentType", clausesVariable.getValue()); 167 inputConfig.put("widget-params", widgetParams); 168 169 inputConfig.put("validation", _getMandatoryValidation()); 170 171 return inputConfig; 172 } 173 174 private Map<String, Object> _getOptionalColumnsInputConfig(String optionalColumn) 175 { 176 Map<String, Object> inputConfig = new HashMap<>(); 177 178 inputConfig.put("label", optionalColumn); 179 inputConfig.put("description", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_OPTIONAL_COLUMNS_INPUTS_DESCRIPTION")); 180 181 inputConfig.put("type", "boolean"); 182 inputConfig.put("widget", "edition.checkbox"); 183 184 inputConfig.put("validation", _getMandatoryValidation()); 185 186 return inputConfig; 187 } 188 189 private Map<String, Object> _getRecipientInputConfig() 190 { 191 Map<String, Object> inputConfig = new HashMap<>(); 192 193 // Get current user email 194 String currentUserEmail = null; 195 UserIdentity currentUser = _currentUserProvider.getUser(); 196 197 String login = currentUser.getLogin(); 198 if (StringUtils.isNotBlank(login)) 199 { 200 String userPopulationId = currentUser.getPopulationId(); 201 User user = _userManager.getUser(userPopulationId, login); 202 currentUserEmail = user.getEmail(); 203 } 204 205 inputConfig.put("label", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_RECIPIENT_INPUT_LABEL")); 206 inputConfig.put("description", new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_RECIPIENT_INPUT_DESCRIPTION")); 207 inputConfig.put("type", "string"); 208 inputConfig.put("default-value", currentUserEmail); 209 210 return inputConfig; 211 } 212 213 private Map<String, Object> _getMandatoryValidation() 214 { 215 Map<String, Object> mandatoryValidation = new HashMap<>(); 216 mandatoryValidation.put("mandatory", true); 217 return mandatoryValidation; 218 } 219 220 /** 221 * Execute the extraction 222 * @param definitionFilePath The extraction definition file path 223 * @param variables clauses variables and optional columns 224 * @param recipient An email will be sent at this address when the extraction is complete 225 * @param pipelineId The id of the extraction pipeline 226 * @return a Map with error if one occurs 227 * @throws Exception if an error occurs 228 */ 229 @Callable (right = ExtractionConstants.EXECUTE_EXTRACTION_RIGHT_ID) 230 public Map<String, Object> executeExtraction(String definitionFilePath, Map<String, Object> variables, String recipient, String pipelineId) throws Exception 231 { 232 Map<String, Object> result = new HashMap<>(); 233 234 try 235 { 236 String variablesAsString = _jsonUtils.convertObjectToJson(variables); 237 Runnable executeExtractionRunnable = new ExecuteExtractionRunnable(definitionFilePath, variablesAsString, recipient, pipelineId); 238 JobKey jobKey = new JobKey(executeExtractionRunnable.getId(), Scheduler.JOB_GROUP); 239 if (_scheduler.getScheduler().checkExists(jobKey)) 240 { 241 _scheduler.getScheduler().deleteJob(jobKey); 242 } 243 _scheduler.scheduleJob(executeExtractionRunnable); 244 getLogger().info("Scheduled extraction execution of " + definitionFilePath); 245 } 246 catch (SchedulerException e) 247 { 248 if (getLogger().isErrorEnabled()) 249 { 250 getLogger().error("An error occured when trying to schedule the extraction execution of " + definitionFilePath, e); 251 } 252 result.put("error", "scheduler-error"); 253 return result; 254 } 255 256 result.put("definitionFilePath", definitionFilePath); 257 return result; 258 } 259}