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