/*! * 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-2016 Pentaho Corporation.. All rights reserved. */ package org.pentaho.platform.scheduler2.ws.test; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.pentaho.platform.api.action.IAction; import org.pentaho.platform.api.engine.IPluginManager; import org.pentaho.platform.api.engine.IUserRoleListService; import org.pentaho.platform.api.engine.PluginBeanException; import org.pentaho.platform.api.scheduler2.ComplexJobTrigger; import org.pentaho.platform.api.scheduler2.IJobFilter; import org.pentaho.platform.api.scheduler2.IScheduler; import org.pentaho.platform.api.scheduler2.IScheduler.SchedulerStatus; import org.pentaho.platform.api.scheduler2.Job; import org.pentaho.platform.api.scheduler2.JobTrigger; import org.pentaho.platform.api.scheduler2.SchedulerException; import org.pentaho.platform.api.scheduler2.SimpleJobTrigger; import org.pentaho.platform.api.scheduler2.recur.ITimeRecurrence; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.core.system.boot.PlatformInitializationException; import org.pentaho.platform.engine.security.SecurityHelper; import org.pentaho.platform.scheduler2.quartz.QuartzScheduler; import org.pentaho.platform.scheduler2.quartz.test.StubUserDetailsService; import org.pentaho.platform.scheduler2.quartz.test.StubUserRoleListService; import org.pentaho.platform.scheduler2.recur.IncrementalRecurrence; import org.pentaho.platform.scheduler2.ws.ISchedulerService; import org.pentaho.platform.scheduler2.ws.ListParamValue; import org.pentaho.platform.scheduler2.ws.MapParamValue; import org.pentaho.platform.scheduler2.ws.ParamValue; import org.pentaho.platform.scheduler2.ws.StringParamValue; import org.pentaho.platform.scheduler2.ws.test.TestQuartzScheduler; import org.pentaho.test.platform.engine.core.MicroPlatform; import org.pentaho.test.platform.engine.core.PluginManagerAdapter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @SuppressWarnings( "nls" ) @RunWith( SpringJUnit4ClassRunner.class ) @ContextConfiguration public class JaxWsSchedulerServiceIT { @Autowired private ApplicationContext applicationContext; private ISchedulerService schedulerSvc; private Map<String, ParamValue> jobParams; private IScheduler scheduler; static final String TEST_USER = "TestUser"; private SimpleJobTrigger RUN_ONCE_IN_2_SECS; private SimpleJobTrigger RUN_ONCE_IN_3_SECS; @Before public void init() throws SchedulerException, PlatformInitializationException { schedulerSvc = (ISchedulerService) applicationContext.getBean( "schedulerFromWs" ); MicroPlatform mp = new MicroPlatform(); mp.define( IPluginManager.class, TstPluginManager.class ); mp.define( "IScheduler2", TestQuartzScheduler.class ); mp.define( IUserRoleListService.class, StubUserRoleListService.class ); mp.define( UserDetailsService.class, StubUserDetailsService.class ); mp.start(); scheduler = PentahoSystem.get( IScheduler.class, "IScheduler2", null ); scheduler.start(); MyAction.executed = false; MyAction.staticStringParam = null; jobParams = new HashMap<String, ParamValue>(); jobParams.put( "stringParam", new StringParamValue( "testStringValue" ) ); RUN_ONCE_IN_2_SECS = JobTrigger.ONCE_NOW; RUN_ONCE_IN_2_SECS.setStartTime( new Date( System.currentTimeMillis() + 2000L ) ); RUN_ONCE_IN_3_SECS = JobTrigger.ONCE_NOW; RUN_ONCE_IN_3_SECS.setStartTime( new Date( System.currentTimeMillis() + 2000L ) ); } @After public void after() throws SchedulerException { for ( Job job : scheduler.getJobs( null ) ) { scheduler.removeJob( job.getJobId() ); } } private static Map<String, ParamValue> generateFullJobParams() { HashMap<String, ParamValue> privateParams = new HashMap<String, ParamValue>(); ListParamValue listValue = new ListParamValue(); listValue.add( "testListVal0" ); listValue.add( "testListVal1" ); MapParamValue mapValue = new MapParamValue(); mapValue.put( "testMapKey0", "testMapVal0" ); mapValue.put( "testMapKey1", "testMapVal1" ); privateParams.put( "stringParam", new StringParamValue( "testStringValue" ) ); privateParams.put( "listParam", listValue ); privateParams.put( "mapParam", mapValue ); return privateParams; } @Test public void testCreateSimpleJob() throws SchedulerException { schedulerSvc.createSimpleJob( "test job", generateFullJobParams(), JobTrigger.ONCE_NOW ); int state = schedulerSvc.getSchedulerStatus(); Assert.assertEquals( SchedulerStatus.RUNNING.ordinal(), state ); int tries = 0; do { sleep( 1 ); } while ( !MyAction.executed && tries++ < 10 ); Assert.assertTrue( "the action was not executed in the expected window", MyAction.executed ); // // Along with this test, make sure all the different kinds of job parameters can be set // Assert.assertEquals( "job params not properly set", "testStringValue", MyAction.staticStringParam ); Assert.assertEquals( "job params not properly set", "testListVal0", MyAction.staticListParam.get( 0 ) ); Assert.assertEquals( "job params not properly set", "testListVal1", MyAction.staticListParam.get( 1 ) ); Assert.assertEquals( "job params not properly set", "testMapVal0", MyAction.staticMapParam.get( "testMapKey0" ) ); Assert.assertEquals( "job params not properly set", "testMapVal1", MyAction.staticMapParam.get( "testMapKey1" ) ); } @Test public void testCreateComplexJob() throws SchedulerException { int startingMinute = ( Calendar.getInstance().get( Calendar.MINUTE ) ) % 60; ComplexJobTrigger jobTrigger = new ComplexJobTrigger(); jobTrigger.setMinuteRecurrence( new IncrementalRecurrence( startingMinute, 1 ) ); jobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); System.out.println( jobTrigger.toString() ); schedulerSvc.createComplexJob( "test job", jobParams, jobTrigger ); int tries = 0; do { sleep( 10 ); } while ( !MyAction.executed && tries++ < 13 ); Assert.assertTrue( "the action was not executed in the expected window", MyAction.executed ); } @SuppressWarnings( "unchecked" ) @Test public void testGetJobs() throws SchedulerException { scheduler.pause(); schedulerSvc.createSimpleJob( "testGetJobsJob", generateFullJobParams(), JobTrigger.ONCE_NOW ); Job[] serviceJobs = schedulerSvc.getJobs(); // // First make sure the actual scheduler engine can find the newly created job // List<Job> engineJobs = scheduler.getJobs( new IJobFilter() { public boolean accept( Job job ) { return job.getJobName().contains( "testGetJobsJob" ); } } ); Assert.assertEquals( "The scheduler engine does not know about the job.", 1, engineJobs.size() ); Job engineJob = engineJobs.get( 0 ); // // Now make sure we have the same job available on the webservice client side // Assert.assertEquals( "The scheduler service does not know about the job.", 1, serviceJobs.length ); Job serviceJob = schedulerSvc.getJobs()[0]; Assert.assertEquals( "jobName is wrong", engineJob.getJobName(), serviceJob.getJobName() ); Map<String, Serializable> params = serviceJob.getJobParams(); Assert.assertTrue( "string job parameter is wrong", "testStringValue".equals( params.get( "stringParam" ) ) ); Assert.assertTrue( "list job parameter is missing", params.containsKey( "listParam" ) ); Assert.assertTrue( "map job parameter is missing", params.containsKey( "mapParam" ) ); Assert.assertTrue( "list job parameter is wrong type. Expected List but is " + params.get( "listParam" ).getClass().getName(), params.get( "listParam" ) instanceof List ); Assert.assertTrue( "map job parameter is wrong type. Expected Map but is " + params.get( "mapParam" ).getClass().getName(), params.get( "mapParam" ) instanceof Map ); List<String> listParam = (List<String>) params.get( "listParam" ); Assert.assertTrue( "list job parameter has wrong value", "testListVal0".equals( listParam.get( 0 ) ) ); Assert.assertTrue( "list job parameter has wrong value", "testListVal1".equals( listParam.get( 1 ) ) ); Map<String, String> mapParam = (Map<String, String>) params.get( "mapParam" ); Assert.assertTrue( "map job parameter has wrong value", "testMapVal0".equals( mapParam.get( "testMapKey0" ) ) ); Assert.assertTrue( "map job parameter has wrong value", "testMapVal1".equals( mapParam.get( "testMapKey1" ) ) ); } @Test public void testPause() throws SchedulerException { schedulerSvc.pause(); schedulerSvc.createSimpleJob( "test job", jobParams, JobTrigger.ONCE_NOW ); sleep( 5 ); Assert.assertFalse( "the action should not have been executed", MyAction.executed ); } @Test public void testResume() throws SchedulerException { schedulerSvc.pause(); schedulerSvc.createSimpleJob( "test job", jobParams, RUN_ONCE_IN_3_SECS ); schedulerSvc.start(); int tries = 0; do { sleep( 1 ); } while ( !MyAction.executed && tries++ < 10 ); Assert.assertTrue( "the action was not executed in the expected window", MyAction.executed ); } @Test public void testPauseJob() throws SchedulerException { String jobId = schedulerSvc.createSimpleJob( "test job", jobParams, RUN_ONCE_IN_2_SECS ); schedulerSvc.pauseJob( jobId ); sleep( 7 ); Assert.assertFalse( "the action should not have been executed", MyAction.executed ); } @Test public void testResumeJob() throws SchedulerException { String jobId = schedulerSvc.createSimpleJob( "test job", jobParams, RUN_ONCE_IN_3_SECS ); schedulerSvc.pauseJob( jobId ); schedulerSvc.resumeJob( jobId ); int tries = 0; do { sleep( 1 ); } while ( !MyAction.executed && tries++ < 10 ); Assert.assertTrue( "the action was not executed in the expected window", MyAction.executed ); } private void sleep( int seconds ) { try { Thread.sleep( seconds * 1000 ); } catch ( InterruptedException e ) { boolean ignored = true; } } public static class TstPluginManager extends PluginManagerAdapter { @Override public Class<?> loadClass( String beanId ) throws PluginBeanException { return MyAction.class; } } public static class MyAction implements IAction { public static boolean executed = false; public static String staticStringParam; public static List<String> staticListParam; public static Map<String, String> staticMapParam; public String stringParam; public List<String> listParam; public Map<String, String> mapParam; public void execute() throws Exception { System.out.println( "I RANNNNNN!! at " + new Date() ); executed = true; } // // Bean property getters/setters // public List<String> getListParam() { return listParam; } public void setListParam( List<String> listParam ) { this.listParam = listParam; staticListParam = listParam; } public Map<String, String> getMapParam() { return mapParam; } public void setMapParam( Map<String, String> mapParam ) { this.mapParam = mapParam; staticMapParam = mapParam; } public void setStringParam( String value ) { stringParam = value; staticStringParam = value; } public String getStringParam() { return stringParam; } } /* public static class TestQuartzScheduler extends QuartzScheduler { @Override protected String getCurrentUser() { SecurityHelper.getInstance().becomeUser( TEST_USER ); return super.getCurrentUser(); } } */ @Test( timeout = 1000 * 5 * 60 ) public void testUpdateComplexJob() throws SchedulerException { long start = System.currentTimeMillis() + 1000; long end = System.currentTimeMillis() + 1000 + 5 * 60 * 60 * 100; int startingMinute = ( Calendar.getInstance().get( Calendar.MINUTE ) + 10 ) % 60; ComplexJobTrigger jobTrigger = new ComplexJobTrigger(); jobTrigger.setStartTime( new Date( start ) ); jobTrigger.setEndTime( new Date( end ) ); jobTrigger.setMinuteRecurrence( new IncrementalRecurrence( startingMinute, 1 ) ); jobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); System.out.println( jobTrigger.toString() ); String jobId = schedulerSvc.createComplexJob( "test job", jobParams, jobTrigger ); Assert.assertEquals( 1, schedulerSvc.getJobs().length ); jobTrigger = new ComplexJobTrigger(); start = System.currentTimeMillis() + 2 * 1000; end = System.currentTimeMillis() + 1000 + 7 * 60 * 60 * 100; jobTrigger.setStartTime( new Date( start ) ); jobTrigger.setEndTime( new Date( end ) ); startingMinute = ( Calendar.getInstance().get( Calendar.MINUTE ) + 20 ) % 60; jobTrigger.setMinuteRecurrence( new IncrementalRecurrence( startingMinute, 5 ) ); jobTrigger.setHourlyRecurrence( (ITimeRecurrence) null ); System.out.println( jobTrigger.toString() ); HashMap<String, ParamValue> newJobParams = new HashMap<String, ParamValue>( jobParams ); newJobParams.put( "newKey", new StringParamValue( "" ) ); schedulerSvc.updateJobToUseComplexTrigger( jobId, newJobParams, jobTrigger ); Assert.assertEquals( 1, schedulerSvc.getJobs().length ); Job job = schedulerSvc.getJobs()[0]; jobTrigger = (ComplexJobTrigger) job.getJobTrigger(); Assert.assertEquals( (Integer) startingMinute, ( (IncrementalRecurrence) jobTrigger.getMinuteRecurrences().get( 0 ) ).getStartingValue() ); Assert.assertEquals( (Integer) 5, ( (IncrementalRecurrence) jobTrigger.getMinuteRecurrences().get( 0 ) ) .getIncrement() ); Assert.assertTrue( job.getJobParams().containsKey( "newKey" ) ); Assert.assertEquals( new Date( start ), jobTrigger.getStartTime() ); Assert.assertEquals( new Date( end ), jobTrigger.getEndTime() ); } @Test public void testUpdateSimpleJob() throws SchedulerException { long start = System.currentTimeMillis() + 1000; long end = System.currentTimeMillis() + 1000 + 5 * 60 * 60 * 100; SimpleJobTrigger jobTrigger = new SimpleJobTrigger(); jobTrigger.setStartTime( new Date( start ) ); jobTrigger.setEndTime( new Date( end ) ); jobTrigger.setRepeatInterval( 10 ); jobTrigger.setRepeatCount( 20 ); System.out.println( jobTrigger.toString() ); String jobId = schedulerSvc.createSimpleJob( "test job", jobParams, jobTrigger ); Assert.assertEquals( 1, schedulerSvc.getJobs().length ); jobTrigger = new SimpleJobTrigger(); start = System.currentTimeMillis() + 1000; end = System.currentTimeMillis() + 1000 + 5 * 60 * 60 * 100; jobTrigger.setStartTime( new Date( start ) ); jobTrigger.setEndTime( new Date( end ) ); jobTrigger.setRepeatInterval( 40 ); jobTrigger.setRepeatCount( 50 ); System.out.println( jobTrigger.toString() ); HashMap<String, ParamValue> newJobParams = new HashMap<String, ParamValue>( jobParams ); newJobParams.put( "newKey", new StringParamValue( "" ) ); schedulerSvc.updateJobToUseSimpleTrigger( jobId, newJobParams, jobTrigger ); Assert.assertEquals( 1, schedulerSvc.getJobs().length ); Job job = schedulerSvc.getJobs()[0]; jobTrigger = (SimpleJobTrigger) job.getJobTrigger(); Assert.assertEquals( 40, jobTrigger.getRepeatInterval() ); Assert.assertEquals( 50, jobTrigger.getRepeatCount() ); Assert.assertTrue( job.getJobParams().containsKey( "newKey" ) ); jobTrigger.getStartTime(); Assert.assertEquals( new Date( start ), jobTrigger.getStartTime() ); Assert.assertEquals( new Date( end ), jobTrigger.getEndTime() ); } }