/* * JAME 6.2.1 * http://jame.sourceforge.net * * Copyright 2001, 2016 Andrea Medeghini * * This file is part of JAME. * * JAME is an application for creating fractals and other graphics artifacts. * * JAME is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * JAME 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with JAME. If not, see <http://www.gnu.org/licenses/>. * */ package net.sf.jame.test; import java.io.File; import java.io.OutputStream; import java.util.HashMap; import java.util.logging.Logger; import net.sf.jame.core.util.ConnectionFactory; import net.sf.jame.core.util.DefaultThreadFactory; import net.sf.jame.core.util.ProgressListener; import net.sf.jame.core.util.Surface; import net.sf.jame.core.util.Worker; import net.sf.jame.core.xml.XML; import net.sf.jame.core.xml.XMLNodeBuilder; import net.sf.jame.queue.DefaultConnectionFactory; import net.sf.jame.queue.LibraryService; import net.sf.jame.queue.LibraryServiceListener; import net.sf.jame.queue.Session; import net.sf.jame.queue.clip.RenderClip; import net.sf.jame.queue.clip.RenderClipDataRow; import net.sf.jame.queue.extensions.encoder.JPEGEncoderConfig; import net.sf.jame.queue.extensions.encoder.JPEGEncoderRuntime; import net.sf.jame.queue.job.RenderJobDataRow; import net.sf.jame.queue.jxta.JXTADiscoveryService; import net.sf.jame.queue.jxta.JXTANetworkService; import net.sf.jame.queue.jxta.JXTASpoolJobService; import net.sf.jame.queue.network.spool.DistributedServiceProcessor; import net.sf.jame.queue.network.spool.LocalServiceProcessor; import net.sf.jame.queue.profile.RenderProfile; import net.sf.jame.queue.profile.RenderProfileDataRow; import net.sf.jame.queue.spool.DefaultDistributedJobService; import net.sf.jame.queue.spool.DefaultJobService; import net.sf.jame.queue.spool.JobData; import net.sf.jame.queue.spool.JobListener; import net.sf.jame.queue.spool.job.DistributedJob; import net.sf.jame.queue.spool.job.DistributedJobFactory; import net.sf.jame.queue.spool.job.DistributedSpoolJobFactory; import net.sf.jame.queue.spool.job.LocalSpoolJob; import net.sf.jame.queue.spool.job.LocalSpoolJobFactory; import net.sf.jame.twister.TwisterClip; import net.sf.jame.twister.TwisterClipXMLExporter; import net.sf.jame.twister.TwisterConfig; import net.sf.jame.twister.TwisterConfigBuilder; import net.sf.jame.twister.TwisterSequence; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * @author Andrea Medeghini */ public class SpoolJobServiceTest { private static final Logger logger = Logger.getLogger(SpoolJobServiceTest.class.getName()); private void deleteFiles(final File path) { final File[] files = path.listFiles(); for (final File file : files) { if (file.isDirectory()) { deleteFiles(file); } file.delete(); } } @Test public void testSpool() throws Exception { @SuppressWarnings("unused") final Surface surface = new Surface(200, 200); final File workDir = new File("workdir"); final File tmpDir = new File(workDir, "tmp"); tmpDir.mkdirs(); deleteFiles(tmpDir); final ConnectionFactory factory = new DefaultConnectionFactory(workDir); final Session session = new Session(factory); final LibraryService service = new LibraryService(session, workDir); final RenderClipDataRow clipDataRow = new RenderClipDataRow(new RenderClip()); clipDataRow.setClipName("test clip"); service.createClip(clipDataRow, null); final RenderProfileDataRow renderProfile = new RenderProfileDataRow(new RenderProfile()); renderProfile.setProfileName("test profile"); renderProfile.setClipName(clipDataRow.getClipName()); renderProfile.setClipId(clipDataRow.getClipId()); renderProfile.setImageWidth(640); renderProfile.setImageHeight(480); renderProfile.setOffsetX(0); renderProfile.setOffsetY(0); renderProfile.setStartTime(0); renderProfile.setStopTime(0); service.createProfile(renderProfile); final TwisterClip clip = new TwisterClip(); final TwisterSequence sequence = new TwisterSequence(); clip.addSequence(sequence); final TwisterConfigBuilder configBuilder = new TwisterConfigBuilder(); final TwisterConfig config = configBuilder.createDefaultConfig(); sequence.setFinalConfig(config); final TwisterClipXMLExporter exporter = new TwisterClipXMLExporter(); final Document doc = XML.createDocument(); final XMLNodeBuilder builder = XML.createDefaultXMLNodeBuilder(doc); final Element element = exporter.exportToElement(clip, builder); doc.appendChild(element); final OutputStream os = service.getClipOutputStream(clipDataRow.getClipId()); XML.saveDocument(os, "twister-clip.xml", doc); os.close(); Worker worker = new Worker(new DefaultThreadFactory("TestSpool Worker", true, Thread.MIN_PRIORITY)); final DistributedServiceProcessor processor1 = new DistributedServiceProcessor(new DefaultDistributedJobService<DistributedJob>(0, "DistributedProcessor", new DistributedJobFactory(tmpDir, worker), worker), 10); final LocalServiceProcessor processor2 = new LocalServiceProcessor(new DefaultJobService<LocalSpoolJob>(0, "LocalProcessor", new LocalSpoolJobFactory(service, worker), worker), 10); final JXTASpoolJobService jobService = new JXTASpoolJobService(0, new JXTADiscoveryService(new JXTANetworkService(tmpDir, "http://jame.sf.net", "JXTASpool", "Andrea Medeghini", "1.0", processor1), processor2), new DistributedSpoolJobFactory(service, worker), worker); processor1.start(); processor2.start(); jobService.start(); worker.start(); final HashMap<Integer, String> jobs = new HashMap<Integer, String>(); service.addServiceListener(new LibraryServiceListener() { public void clipCreated(final RenderClipDataRow clip) { } public void clipDeleted(final RenderClipDataRow clip) { } public void clipUpdated(final RenderClipDataRow clip) { } public void clipLoaded(final RenderClipDataRow clip) { } public void jobCreated(final RenderJobDataRow job) { final String jobId = jobService.createJob(new TestListener()); jobService.setJobData(jobId, job, job.getFrameNumber()); jobs.put(job.getJobId(), jobId); logger.info("Job " + jobId + " created"); } public void jobDeleted(final RenderJobDataRow job) { final String jobId = jobs.get(job.getJobId()); jobService.deleteJob(jobId); logger.info("Job " + jobId + " deleted"); } public void jobStarted(final RenderJobDataRow job) { final String jobId = jobs.get(job.getJobId()); jobService.runJob(jobId); logger.info("Job " + jobId + " started"); } public void jobStopped(final RenderJobDataRow job) { final String jobId = jobs.get(job.getJobId()); jobService.stopJob(jobId); logger.info("Job " + jobId + " stopped"); } public void jobAborted(final RenderJobDataRow job) { } public void jobUpdated(final RenderJobDataRow job) { } public void jobResumed(final RenderJobDataRow job) { } public void profileCreated(final RenderProfileDataRow profile) { } public void profileDeleted(final RenderProfileDataRow profile) { } public void profileUpdated(final RenderProfileDataRow profile) { } public void profileLoaded(final RenderProfileDataRow profile) { } }); ProgressListener listener = new ProgressListener() { public void done() { } public void failed(final Throwable e) { } public void stateChanged(final String message, final int percentage) { } public void stateChanged(final String message) { } }; service.createJobs(renderProfile.getProfileId(), listener, "Creating jobs", 100f); service.startJobs(renderProfile.getProfileId(), listener, "Creating jobs", 100f); Thread.sleep(5000); try { while (true) { // boolean terminated = true; // for (final DistributedSpoolJob job : jobs.values()) { // if (!job.isTerminated()) { // terminated = false; // } // } // if (terminated) { // break; // } Thread.sleep(60000); } } catch (final InterruptedException e) { } service.stopJobs(renderProfile.getProfileId(), listener, "Creating jobs", 100f); // for (final DistributedSpoolJob job : jobs.values()) { // service.jobCompleted(job.getJobDataRow()); // } final JPEGEncoderRuntime encoder = new JPEGEncoderRuntime(); encoder.setConfig(new JPEGEncoderConfig()); service.exportProfile(renderProfile, encoder, listener, new File("test.jpeg")); worker.stop(); jobService.stop(); processor1.stop(); processor2.stop(); session.close(); } private static class TestListener implements JobListener { /** * @see net.sf.jame.queue.spool.JobListener#updated(String, JobData) */ public void updated(final String jobId, final JobData job) { logger.info("Job state changed " + job); } /** * @see net.sf.jame.queue.spool.JobListener#started(String, JobData) */ public void started(final String jobId, final JobData job) { logger.info("Job started " + job); } /** * @see net.sf.jame.queue.spool.JobListener#stopped(String, JobData) */ public void stopped(final String jobId, final JobData job) { logger.info("Job stopped " + job); } /** * @see net.sf.jame.queue.spool.JobListener#terminated(String, JobData) */ public void terminated(final String jobId, final JobData job) { logger.info("Job terminated " + job); } /** * @see net.sf.jame.queue.spool.JobListener#disposed(String, JobData) */ public void disposed(final String jobId, final JobData job) { logger.info("Job disposed " + job); } } }