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