001/*
002 *  Copyright 2025 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.util.Collections;
019import java.util.HashMap;
020import java.util.Map;
021
022import org.apache.avalon.framework.component.Component;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.avalon.framework.service.Serviceable;
026import org.quartz.JobKey;
027import org.quartz.SchedulerException;
028
029import org.ametys.core.schedule.Runnable;
030import org.ametys.core.schedule.Runnable.FireProcess;
031import org.ametys.core.user.CurrentUserProvider;
032import org.ametys.core.util.JSONUtils;
033import org.ametys.plugins.core.impl.schedule.DefaultRunnable;
034import org.ametys.plugins.core.schedule.Scheduler;
035import org.ametys.plugins.extraction.ExtractionConstants;
036import org.ametys.runtime.i18n.I18nizableText;
037import org.ametys.runtime.plugin.component.AbstractLogEnabled;
038
039/**
040 * Helper for {@link Runnable} executing an extraction
041 */
042public class ExecuteExtractionRunnableHelper extends AbstractLogEnabled implements Component, Serviceable
043{
044    /** Avalon Role */
045    public static final String ROLE = ExecuteExtractionRunnableHelper.class.getName();
046    
047    private static final String __RUNNABLE_PREFIX = "org.ametys.plugins.extraction.execution.ExecuteExtractionRunnable$";
048    
049    private JSONUtils _jsonUtils;
050    private CurrentUserProvider _currentUserProvider;
051    private Scheduler _scheduler;
052    
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE);
056        _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
057        _scheduler = (Scheduler) manager.lookup(Scheduler.ROLE);
058    }
059   
060    /**
061     * Execute the extraction
062     * @param definitionFilePath The extraction definition file path
063     * @param variables clauses variables and optional columns
064     * @param recipient An email will be sent at this address when the extraction is complete
065     * @param pipelineId The id of the extraction pipeline
066     * @return a Map with error if one occurs
067     */
068    public Map<String, Object> executeExtraction(String definitionFilePath, Map<String, Object> variables, String recipient, String pipelineId)
069    {
070        try
071        {
072            Map<String, Object> jobParams = new HashMap<>();
073            jobParams.put(ExecuteExtractionSchedulable.DEFINITION_FILE_PATH_KEY, definitionFilePath);
074            jobParams.put(ExecuteExtractionSchedulable.VARIABLES_KEY, _jsonUtils.convertObjectToJson(variables));
075            jobParams.put(ExecuteExtractionSchedulable.RECIPIENT_KEY, recipient);
076            jobParams.put(ExecuteExtractionSchedulable.PIPELINE_KEY, pipelineId);
077            
078            Runnable executeExtractionRunnable = new DefaultRunnable(__RUNNABLE_PREFIX + definitionFilePath,
079                    new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_SCHEDULABLE_LABEL", Collections.singletonList(definitionFilePath)),
080                    new I18nizableText(ExtractionConstants.PLUGIN_NAME, "PLUGINS_EXTRACTION_EXECUTE_EXTRACTION_SCHEDULABLE_DESCRIPTION", Collections.singletonList(definitionFilePath)),
081                    FireProcess.NOW,
082                    null /* cron*/,
083                    "org.ametys.plugins.extraction.execution.ExecuteExtractionSchedulable",
084                    true /* removable */,
085                    true /* modifiable */,
086                    false /* deactivatable */,
087                    null /* misfire policy */,
088                    false /* isVolatile */,
089                    _currentUserProvider.getUser(),
090                    jobParams
091                );
092            
093            JobKey jobKey = new JobKey(executeExtractionRunnable.getId(), Scheduler.JOB_GROUP);
094            if (_scheduler.getScheduler().checkExists(jobKey))
095            {
096                _scheduler.getScheduler().deleteJob(jobKey);
097            }
098            _scheduler.scheduleJob(executeExtractionRunnable);
099            
100            getLogger().info("Scheduled extraction execution of " + definitionFilePath);
101            return Map.of("definitionFilePath", definitionFilePath);
102        }
103        catch (SchedulerException e)
104        {
105            getLogger().error("An error occured when trying to schedule the extraction execution of " + definitionFilePath, e);
106            return Map.of("error", "scheduler-error");
107        }
108    }
109    
110    /**
111     * Remove the scheduled task of extraction execution of the given file
112     * @param definitionFilePath The extraction definition file path
113     */
114    public void deleteRunnableJob(String definitionFilePath)
115    {
116        try
117        {
118            String runnableId = __RUNNABLE_PREFIX + definitionFilePath;
119            // Remove job corresponding to the runnable id (existing only if the extraction has been launched via the extraction execution tool) 
120            JobKey jobKey = new JobKey(runnableId, Scheduler.JOB_GROUP);
121            if (_scheduler.getScheduler().checkExists(jobKey))
122            {
123                _scheduler.getScheduler().deleteJob(jobKey);
124            }
125        }
126        catch (SchedulerException e)
127        {
128            getLogger().error("An error occured when trying to remove the scheduled task of extraction execution of " + definitionFilePath, e);
129        }
130    }
131}