1   // 
2   //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
3   //All rights reserved. 
4   //   
5   //Redistribution and use in source and binary forms, with or without modification,  
6   //are permitted provided that the following conditions are met: 
7   //   
8   //* Redistributions of source code must retain the above copyright notice,  
9   //this list of conditions and the following disclaimer. 
10  //* Redistributions in binary form must reproduce the above copyright notice,  
11  //this list of conditions and the following disclaimer in the documentation  
12  //and/or other materials provided with the distribution. 
13  //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.  
14  //nor the names of its contributors may be used to endorse or promote products  
15  //derived from this software without specific prior written permission. 
16  // 
17  //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"  
18  //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  
19  //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
20  //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,  
21  //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  
22  //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
23  //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
24  //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  
25  //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  
26  //POSSIBILITY OF SUCH DAMAGE. 
27  //
28  
29  package org.objectledge.scheduler.db;
30  
31  import java.text.SimpleDateFormat;
32  import java.util.Date;
33  
34  import javax.sql.DataSource;
35  import javax.xml.parsers.DocumentBuilder;
36  import javax.xml.parsers.DocumentBuilderFactory;
37  
38  import org.apache.log4j.LogManager;
39  import org.jcontainer.dna.Configuration;
40  import org.jcontainer.dna.Logger;
41  import org.jcontainer.dna.impl.DefaultConfiguration;
42  import org.jcontainer.dna.impl.Log4JLogger;
43  import org.objectledge.context.Context;
44  import org.objectledge.database.Database;
45  import org.objectledge.database.DatabaseUtils;
46  import org.objectledge.database.DefaultDatabase;
47  import org.objectledge.database.HsqldbDataSource;
48  import org.objectledge.database.IdGenerator;
49  import org.objectledge.database.JotmTransaction;
50  import org.objectledge.database.persistence.DefaultPersistence;
51  import org.objectledge.database.persistence.Persistence;
52  import org.objectledge.filesystem.FileSystem;
53  import org.objectledge.logging.LedgeDOMConfigurator;
54  import org.objectledge.mail.MailSystem;
55  import org.objectledge.scheduler.AbstractJobDescriptor;
56  import org.objectledge.scheduler.AbstractScheduler;
57  import org.objectledge.scheduler.AtScheduleFactory;
58  import org.objectledge.scheduler.InvalidScheduleException;
59  import org.objectledge.scheduler.JobModificationException;
60  import org.objectledge.scheduler.JobNotFoundException;
61  import org.objectledge.scheduler.Schedule;
62  import org.objectledge.scheduler.ScheduleFactory;
63  import org.objectledge.threads.ThreadPool;
64  import org.objectledge.utils.LedgeTestCase;
65  import org.picocontainer.MutablePicoContainer;
66  import org.picocontainer.defaults.DefaultPicoContainer;
67  import org.w3c.dom.Document;
68  import org.xml.sax.InputSource;
69  
70  /**
71   * @author <a href="mailto:pablo@caltha.pl">Pawel Potempski</a>
72   *
73   */
74  public class DBSchedulerTest extends LedgeTestCase
75  {
76      private FileSystem fs = null;
77  
78      private DBScheduler scheduler;
79  
80      /*
81       * @see TestCase#setUp()
82       */
83      protected void setUp() throws Exception
84      {
85          super.setUp();
86          fs = FileSystem.getStandardFileSystem("src/test/resources");
87          InputSource source = new InputSource(fs.getInputStream(
88              "config/org.objectledge.logging.LoggingConfigurator.xml"));
89          DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
90          Document logConfig = builder.parse(source);
91          LedgeDOMConfigurator configurator = new LedgeDOMConfigurator(fs);
92          configurator.doConfigure(logConfig.getDocumentElement(), LogManager.getLoggerRepository());
93          Logger logger = new Log4JLogger(org.apache.log4j.Logger.getLogger(DBScheduler.class));
94          Configuration config = getConfig("config/org.objectledge.threads.ThreadPool.xml");
95          Context context = new Context();
96          ThreadPool threadPool = new ThreadPool(null, context,config, logger);
97          config = getConfig("config/org.objectledge.scheduler.TransientScheduler.xml");
98          ScheduleFactory[] scheduleFactories = new ScheduleFactory[1];
99          scheduleFactories[0] = new AtScheduleFactory();
100         DataSource dataSource = getDataSource();
101         IdGenerator idGenerator = new IdGenerator(dataSource);
102         JotmTransaction transaction = new JotmTransaction(0, 120, new Context(), logger, null);
103         Database database = new DefaultDatabase(dataSource, idGenerator, transaction);        
104         
105         Persistence persistence = new DefaultPersistence(database, logger);
106         MutablePicoContainer container = new DefaultPicoContainer();
107         scheduler = new DBScheduler(container, config, 
108             logger, threadPool, scheduleFactories, persistence);
109         scheduler.start();
110     }
111 
112     public void testCreateJobDescriptor()
113         throws Exception
114     {
115         assertNotNull(scheduler);
116         Schedule schedule = scheduler.createSchedule("at","");
117         scheduler.createJobDescriptor("bar",schedule,"org.objectledge.scheduler.FooJob");
118         try
119         {
120             scheduler.createJobDescriptor("bar",schedule,"org.objectledge.scheduler.FooJob");
121             fail("should throw the exception");
122         }
123         catch(IllegalArgumentException e)
124         {
125             //ok!
126         }
127     }
128     
129 
130     public void testDeleteJobDescriptor()
131         throws Exception
132     {
133         AbstractJobDescriptor job = scheduler.getJobDescriptor("foo");
134         assertNotNull(job);
135         scheduler.deleteJobDescriptor(job);
136     }
137 
138     public void testAllowsModifications()
139     {
140         assertEquals(true,scheduler.allowsModifications());
141     }
142 
143     public void testEnable()
144         throws Exception
145     {
146         Schedule schedule = scheduler.createSchedule("at","");
147         scheduler.createJobDescriptor("bar2",schedule,"org.objectledge.scheduler.FooJob");        
148         AbstractJobDescriptor job = scheduler.getJobDescriptor("bar2");
149         assertNotNull(job);
150         assertEquals(false, job.isEnabled());
151         scheduler.enable(job);
152         assertEquals(true, job.isEnabled());
153     }
154 
155     public void testGetJobDescriptors()
156     {
157         AbstractJobDescriptor[] jobs = scheduler.getJobDescriptors();
158         assertEquals(2, jobs.length);
159     }
160 
161     public void testGetScheduleTypes()
162     {
163         String[] types = scheduler.getScheduleTypes();
164         assertEquals(1, types.length);
165         assertEquals("at", types[0]);
166     }
167 
168     public void testCreateSchedule()
169         throws Exception
170     {
171         Schedule schedule = scheduler.createSchedule("at","");
172         assertNotNull(schedule);
173         assertEquals("",schedule.getConfig());
174         assertEquals("at",schedule.getType());
175         assertNull(null,schedule.getNextRunTime(new Date(), new Date()));
176         try
177         {
178             scheduler.createSchedule("foo","");
179             fail("should throw the exception");
180         }
181         catch(InvalidScheduleException e)
182         {
183             //ok!
184         }
185     }
186 
187     public void testGetDateFormat()
188     {
189         assertEquals(new SimpleDateFormat(AbstractScheduler.DATE_FORMAT_DEFAULT),
190                        scheduler.getDateFormat());
191     }
192 
193     public void testDBJobDescriptor()
194         throws Exception
195     {
196         Schedule schedule = scheduler.createSchedule("at","");
197         scheduler.createJobDescriptor("foo.bar",schedule,"org.objectledge.scheduler.FooJob");
198         DBJobDescriptor job = (DBJobDescriptor)scheduler.getJobDescriptor("foo.bar");
199         assertEquals(false, job.isRunning());
200         job.setSchedule(schedule);
201         job.setJobClassName("foo.bar");
202         job.setAutoClean(false);
203         assertEquals("foo.bar", job.getJobClassName());
204         assertEquals(false, job.getAutoClean());
205     }
206 
207     public void testAdditional()
208     {
209         JobNotFoundException e = new JobNotFoundException("foo");
210         assertEquals("foo", e.getMessage());
211         JobNotFoundException ee = new JobNotFoundException("bar", e);
212         assertEquals("bar", ee.getMessage());
213         Exception eee = new JobModificationException("bar", e);
214         assertEquals("bar", eee.getMessage());
215     }
216 
217 
218     //////////////////////////////
219 
220     private Configuration getConfig(String name)
221         throws Exception
222     {
223         return getConfig(fs, name);
224     }
225 
226     private DataSource getDataSource() throws Exception
227     {
228         DefaultConfiguration conf = new DefaultConfiguration("config", "", "/");
229         DefaultConfiguration url = new DefaultConfiguration("url", "", "/config");
230         url.setValue("jdbc:hsqldb:.");
231         conf.addChild(url);
232         DefaultConfiguration user = new DefaultConfiguration("user", "", "/config");
233         user.setValue("sa");
234         conf.addChild(user);
235         DataSource ds = new HsqldbDataSource(conf);
236         if(!DatabaseUtils.hasTable(ds, "ledge_id_table"))
237         {
238             DatabaseUtils.runScript(ds, fs.getReader("sql/database/IdGeneratorTables.sql", "UTF-8"));
239         }
240         if(!DatabaseUtils.hasTable(ds, "ledge_scheduler"))
241         {        
242             DatabaseUtils.runScript(ds, 
243                 fs.getReader("sql/scheduler/db/DBSchedulerTables.sql", "UTF-8"));
244             DatabaseUtils.runScript(ds, 
245                 fs.getReader("sql/scheduler/db/DBSchedulerTest.sql", "UTF-8"));
246         }
247         return ds;
248     }
249     
250 }