/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2017 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.web.http.api.resources; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.platform.api.repository2.unified.RepositoryFile; import org.pentaho.platform.api.repository2.unified.UnifiedRepositoryException; import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; import org.pentaho.platform.api.scheduler2.IJobTrigger; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; import org.pentaho.platform.plugin.services.exporter.ScheduleExportUtil; import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek; import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeek; import org.pentaho.platform.scheduler2.recur.QualifiedDayOfWeek.DayOfWeekQualifier; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.TimeZone; public class SchedulerResourceUtil { private static final Log logger = LogFactory.getLog( SchedulerResourceUtil.class ); public static final String RESERVEDMAPKEY_LINEAGE_ID = "lineage-id"; public static IJobTrigger convertScheduleRequestToJobTrigger( JobScheduleRequest scheduleRequest, IScheduler scheduler ) throws SchedulerException, UnifiedRepositoryException { // Used to determine if created by a RunInBackgroundCommand boolean runInBackground = scheduleRequest.getSimpleJobTrigger() == null && scheduleRequest.getComplexJobTrigger() == null && scheduleRequest.getCronJobTrigger() == null; // add 10 seconds to the RIB to ensure execution (see PPP-3264) IJobTrigger jobTrigger = runInBackground ? new SimpleJobTrigger( new Date( System.currentTimeMillis() + 10000 ), null, 0, 0 ) : scheduleRequest.getSimpleJobTrigger(); if ( scheduleRequest.getSimpleJobTrigger() != null ) { SimpleJobTrigger simpleJobTrigger = scheduleRequest.getSimpleJobTrigger(); if ( simpleJobTrigger.getStartTime() == null ) { simpleJobTrigger.setStartTime( new Date() ); } jobTrigger = simpleJobTrigger; } else if ( scheduleRequest.getComplexJobTrigger() != null ) { ComplexJobTriggerProxy proxyTrigger = scheduleRequest.getComplexJobTrigger(); ComplexJobTrigger complexJobTrigger = new ComplexJobTrigger(); complexJobTrigger.setStartTime( proxyTrigger.getStartTime() ); complexJobTrigger.setEndTime( proxyTrigger.getEndTime() ); complexJobTrigger.setDuration( scheduleRequest.getDuration() ); if ( proxyTrigger.getDaysOfWeek().length > 0 ) { if ( proxyTrigger.getWeeksOfMonth().length > 0 ) { for ( int dayOfWeek : proxyTrigger.getDaysOfWeek() ) { for ( int weekOfMonth : proxyTrigger.getWeeksOfMonth() ) { QualifiedDayOfWeek qualifiedDayOfWeek = new QualifiedDayOfWeek(); qualifiedDayOfWeek.setDayOfWeek( DayOfWeek.values()[ dayOfWeek ] ); if ( weekOfMonth == JobScheduleRequest.LAST_WEEK_OF_MONTH ) { qualifiedDayOfWeek.setQualifier( DayOfWeekQualifier.LAST ); } else { qualifiedDayOfWeek.setQualifier( DayOfWeekQualifier.values()[ weekOfMonth ] ); } complexJobTrigger.addDayOfWeekRecurrence( qualifiedDayOfWeek ); } } } else { for ( int dayOfWeek : proxyTrigger.getDaysOfWeek() ) { complexJobTrigger.addDayOfWeekRecurrence( dayOfWeek + 1 ); } } } else if ( proxyTrigger.getDaysOfMonth().length > 0 ) { for ( int dayOfMonth : proxyTrigger.getDaysOfMonth() ) { complexJobTrigger.addDayOfMonthRecurrence( dayOfMonth ); } } for ( int month : proxyTrigger.getMonthsOfYear() ) { complexJobTrigger.addMonthlyRecurrence( month + 1 ); } for ( int year : proxyTrigger.getYears() ) { complexJobTrigger.addYearlyRecurrence( year ); } Calendar calendar = Calendar.getInstance(); calendar.setTime( complexJobTrigger.getStartTime() ); complexJobTrigger.setHourlyRecurrence( calendar.get( Calendar.HOUR_OF_DAY ) ); complexJobTrigger.setMinuteRecurrence( calendar.get( Calendar.MINUTE ) ); complexJobTrigger.setUiPassParam( scheduleRequest.getComplexJobTrigger().getUiPassParam() ); jobTrigger = complexJobTrigger; } else if ( scheduleRequest.getCronJobTrigger() != null ) { if ( scheduler instanceof QuartzScheduler ) { String cronString = scheduleRequest.getCronJobTrigger().getCronString(); String delims = "[ ]+"; //$NON-NLS-1$ String[] tokens = cronString.split( delims ); if ( tokens.length < 7 ) { cronString += " *"; } ComplexJobTrigger complexJobTrigger = QuartzScheduler.createComplexTrigger( cronString ); complexJobTrigger.setStartTime( scheduleRequest.getCronJobTrigger().getStartTime() ); complexJobTrigger.setEndTime( scheduleRequest.getCronJobTrigger().getEndTime() ); complexJobTrigger.setDuration( scheduleRequest.getCronJobTrigger().getDuration() ); complexJobTrigger.setUiPassParam( scheduleRequest.getCronJobTrigger().getUiPassParam() ); jobTrigger = complexJobTrigger; } else { throw new IllegalArgumentException(); } } return jobTrigger; } public static void updateStartDateForTimeZone( JobScheduleRequest request ) { if ( request.getSimpleJobTrigger() != null ) { if ( request.getSimpleJobTrigger().getStartTime() != null ) { Date origStartDate = request.getSimpleJobTrigger().getStartTime(); Date serverTimeZoneStartDate = convertDateToServerTimeZone( origStartDate, request.getTimeZone() ); request.getSimpleJobTrigger().setStartTime( serverTimeZoneStartDate ); } } else if ( request.getComplexJobTrigger() != null ) { if ( request.getComplexJobTrigger().getStartTime() != null ) { Date origStartDate = request.getComplexJobTrigger().getStartTime(); Date serverTimeZoneStartDate = convertDateToServerTimeZone( origStartDate, request.getTimeZone() ); request.getComplexJobTrigger().setStartTime( serverTimeZoneStartDate ); } } else if ( request.getCronJobTrigger() != null ) { if ( request.getCronJobTrigger().getStartTime() != null ) { Date origStartDate = request.getCronJobTrigger().getStartTime(); Date serverTimeZoneStartDate = convertDateToServerTimeZone( origStartDate, request.getTimeZone() ); request.getCronJobTrigger().setStartTime( serverTimeZoneStartDate ); } } } public static Date convertDateToServerTimeZone( Date dateTime, String timeZone ) { Calendar userDefinedTime = Calendar.getInstance(); userDefinedTime.setTime( dateTime ); if ( !TimeZone.getDefault().getID().equalsIgnoreCase( timeZone ) ) { logger.warn( "original defined time: " + userDefinedTime.getTime().toString() + " on tz:" + timeZone ); Calendar quartzStartDate = new GregorianCalendar( TimeZone.getTimeZone( timeZone ) ); quartzStartDate.set( Calendar.YEAR, userDefinedTime.get( Calendar.YEAR ) ); quartzStartDate.set( Calendar.MONTH, userDefinedTime.get( Calendar.MONTH ) ); quartzStartDate.set( Calendar.DAY_OF_MONTH, userDefinedTime.get( Calendar.DAY_OF_MONTH ) ); quartzStartDate.set( Calendar.HOUR_OF_DAY, userDefinedTime.get( Calendar.HOUR_OF_DAY ) ); quartzStartDate.set( Calendar.MINUTE, userDefinedTime.get( Calendar.MINUTE ) ); quartzStartDate.set( Calendar.SECOND, userDefinedTime.get( Calendar.SECOND ) ); quartzStartDate.set( Calendar.MILLISECOND, userDefinedTime.get( Calendar.MILLISECOND ) ); logger.warn( "adapted time for " + TimeZone.getDefault().getID() + ": " + quartzStartDate.getTime().toString() ); return quartzStartDate.getTime(); } else { return dateTime; } } public static HashMap<String, Serializable> handlePDIScheduling( RepositoryFile file, HashMap<String, Serializable> parameterMap, Map<String, String> pdiParameters ) { HashMap<String, Serializable> convertedParameterMap = new HashMap<>(); boolean paramsAdded = false; if ( pdiParameters != null ) { convertedParameterMap.put( ScheduleExportUtil.RUN_PARAMETERS_KEY, (Serializable) pdiParameters ); paramsAdded = true; } else { pdiParameters = new HashMap<String, String>(); } if ( file != null && isPdiFile( file ) ) { Iterator<String> it = parameterMap.keySet().iterator(); while ( it.hasNext() ) { String param = (String) it.next(); if ( !StringUtils.isEmpty( param ) && parameterMap.containsKey( param ) ) { convertedParameterMap.put( param, parameterMap.get( param ).toString() ); if ( !paramsAdded ) { pdiParameters.put( param, parameterMap.get( param ).toString() ); } } } convertedParameterMap.put( "directory", FilenameUtils.getPathNoEndSeparator( file.getPath() ) ); String type = isTransformation( file ) ? "transformation" : "job"; convertedParameterMap.put( type, FilenameUtils.getBaseName( file.getPath() ) ); } else { convertedParameterMap.putAll( parameterMap ); } convertedParameterMap.putIfAbsent( ScheduleExportUtil.RUN_PARAMETERS_KEY, (Serializable) pdiParameters ); return convertedParameterMap; } public static boolean isPdiFile( RepositoryFile file ) { return isTransformation( file ) || isJob( file ); } public static boolean isTransformation( RepositoryFile file ) { return file != null && "ktr".equalsIgnoreCase( FilenameUtils.getExtension( file.getName() ) ); } public static boolean isJob( RepositoryFile file ) { return file != null && "kjb".equalsIgnoreCase( FilenameUtils.getExtension( file.getName() ) ); } }