Java tutorial
/*! * 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 Hitachi Vantara.. All rights reserved. */ package org.pentaho.reporting.platform.plugin.output; import junit.framework.Assert; import org.apache.commons.io.output.ByteArrayOutputStream; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.engine.core.system.PentahoSessionHolder; import org.pentaho.platform.engine.core.system.StandaloneSession; import org.pentaho.platform.engine.core.system.boot.PlatformInitializationException; import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.event.ReportProgressEvent; import org.pentaho.reporting.libraries.base.config.ModifiableConfiguration; import org.pentaho.reporting.libraries.resourceloader.ResourceManager; import org.pentaho.reporting.platform.plugin.MicroPlatformFactory; import org.pentaho.reporting.platform.plugin.SimpleReportingComponent; import org.pentaho.reporting.platform.plugin.async.AsyncExecutionStatus; import org.pentaho.reporting.platform.plugin.async.IAsyncReportListener; import org.pentaho.reporting.platform.plugin.async.ReportListenerThreadHolder; import org.pentaho.reporting.platform.plugin.async.TestListener; import org.pentaho.reporting.platform.plugin.cache.FileSystemCacheBackend; import org.pentaho.reporting.platform.plugin.cache.IPluginCacheManager; import org.pentaho.reporting.platform.plugin.cache.IReportContentCache; import org.pentaho.reporting.platform.plugin.cache.PluginCacheManagerImpl; import org.pentaho.reporting.platform.plugin.cache.PluginSessionCache; import org.pentaho.test.platform.engine.core.MicroPlatform; import java.io.File; import java.io.FileOutputStream; import java.io.Serializable; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class CachingPageableHTMLOutputIT { private IAsyncReportListener listener; SimpleReportingComponent rc; private static MicroPlatform microPlatform; private File tmp; private static FileSystemCacheBackend fileSystemCacheBackend; private static IPluginCacheManager iPluginCacheManager; @BeforeClass public static void setUpClass() throws PlatformInitializationException { fileSystemCacheBackend = new FileSystemCacheBackend(); fileSystemCacheBackend.setCachePath("/test-cache/"); microPlatform = MicroPlatformFactory.create(); microPlatform.define(ReportOutputHandlerFactory.class, FastExportReportOutputHandlerFactory.class); iPluginCacheManager = spy(new PluginCacheManagerImpl(new PluginSessionCache(fileSystemCacheBackend))); microPlatform.define("IPluginCacheManager", iPluginCacheManager); microPlatform.start(); } @AfterClass public static void tearDownClass() { Assert.assertTrue(fileSystemCacheBackend.purge(Collections.singletonList(""))); microPlatform.stop(); microPlatform = null; } @Before public void setUp() { ClassicEngineBoot.getInstance().start(); listener = mock(IAsyncReportListener.class); ReportListenerThreadHolder.setListener(listener); // create an instance of the component rc = new SimpleReportingComponent(); tmp = new File("target/test/resource/solution/system/tmp"); tmp.mkdirs(); final IPentahoSession session = new StandaloneSession(); PentahoSessionHolder.setSession(session); fileSystemCacheBackend.purge(Collections.singletonList("")); } @After public void tearDown() { ReportListenerThreadHolder.clear(); listener = null; } @Test public void testGenerate() throws Exception { ReportListenerThreadHolder.clear(); CachingPageableHTMLOutput cachingPageableHTMLOutput = new CachingPageableHTMLOutput(); cachingPageableHTMLOutput.generate(new MasterReport(), 1, new ByteArrayOutputStream(), 1); verify(listener, times(0)).reportProcessingStarted(any(ReportProgressEvent.class)); verify(listener, times(0)).reportProcessingFinished(any(ReportProgressEvent.class)); verify(listener, times(0)).reportProcessingUpdate(any(ReportProgressEvent.class)); } @Test public void testIsQueryLimitReachedFlagStoredInCacheMetadataTrue() throws Exception { ReportListenerThreadHolder.clear(); final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig(); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true"); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true"); try { final TestListener listener = new TestListener("1", UUID.randomUUID(), ""); ReportListenerThreadHolder.setListener(listener); final ResourceManager mgr = new ResourceManager(); final File src = new File("target/test/resource/solution/test/reporting/report.prpt"); final MasterReport report = (MasterReport) mgr.createDirectly(src, MasterReport.class).getResource(); report.setContentCacheKey("some_key"); // set row limit for report report.setQueryLimit(100); execute(report); assertTrue(listener.isQueryLimitReached()); final IReportContentCache cache = iPluginCacheManager.getCache(); Map<String, Serializable> metaData = cache.getMetaData(report.getContentCacheKey()); assertEquals(metaData.get("IsQueryLimitReached"), true); ReportListenerThreadHolder.clear(); assertNull(ReportListenerThreadHolder.getListener()); } finally { edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", null); } } @Test public void testIsQueryLimitReachedFlagStoredInCacheMetadataFalse() throws Exception { ReportListenerThreadHolder.clear(); fileSystemCacheBackend.purge(Collections.singletonList("")); final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig(); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true"); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true"); try { final TestListener listener = new TestListener("1", UUID.randomUUID(), ""); ReportListenerThreadHolder.setListener(listener); final ResourceManager mgr = new ResourceManager(); final File src = new File("target/test/resource/solution/test/reporting/report.prpt"); final MasterReport report = (MasterReport) mgr.createDirectly(src, MasterReport.class).getResource(); report.setContentCacheKey("somekey"); // set unlimited rows for report report.setQueryLimit(-1); execute(report); assertFalse(listener.isQueryLimitReached()); final IReportContentCache cache = iPluginCacheManager.getCache(); Map<String, Serializable> metaData = cache.getMetaData(report.getContentCacheKey()); assertNull(metaData.get("IsQueryLimitReached")); ReportListenerThreadHolder.clear(); assertNull(ReportListenerThreadHolder.getListener()); } finally { edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", null); } } @Test public void testIsQueryLimitReachedForFirstPageModeDisabled() throws Exception { ReportListenerThreadHolder.clear(); final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig(); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true"); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", "false"); try { final TestListener listener = new TestListener("1", UUID.randomUUID(), ""); ReportListenerThreadHolder.setListener(listener); final ResourceManager mgr = new ResourceManager(); final File src = new File("target/test/resource/solution/test/reporting/report.prpt"); final MasterReport report = (MasterReport) mgr.createDirectly(src, MasterReport.class).getResource(); report.setContentCacheKey("some_key"); // set row limit for report report.setQueryLimit(20); execute(report); assertTrue(listener.isQueryLimitReached()); final IReportContentCache cache = iPluginCacheManager.getCache(); Map<String, Serializable> metaData = cache.getMetaData(report.getContentCacheKey()); assertEquals(metaData.get("IsQueryLimitReached"), true); ReportListenerThreadHolder.clear(); assertNull(ReportListenerThreadHolder.getListener()); } finally { edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null); edConf.setConfigProperty("org.pentaho.reporting.platform.plugin.output.FirstPageMode", null); } } private void execute(final MasterReport r) throws Exception { // create an instance of the component final SimpleReportingComponent rc = new SimpleReportingComponent(); // create/set the InputStream rc.setReport(r); rc.setOutputType("text/html"); //$NON-NLS-1$ // turn on pagination, by way of input (typical mode for xaction) final HashMap<String, Object> inputs = new HashMap<String, Object>(); inputs.put("paginate", "true"); //$NON-NLS-1$ //$NON-NLS-2$ inputs.put("accepted-page", "0"); //$NON-NLS-1$ //$NON-NLS-2$ inputs.put("content-handler-pattern", "test"); rc.setInputs(inputs); final FileOutputStream outputStream = new FileOutputStream( new File(tmp, System.currentTimeMillis() + ".html")); //$NON-NLS-1$ //$NON-NLS-2$ rc.setOutputStream(outputStream); // execute the component assertTrue(rc.execute()); } @Test public void testScheduledReportContainsAllPages() throws Exception { ReportListenerThreadHolder.clear(); final CountDownLatch latch1 = new CountDownLatch(1); final CountDownLatch latch2 = new CountDownLatch(1); final ExecutorService executorService = Executors.newFixedThreadPool(2); final SimpleReportingComponent rc = new SimpleReportingComponent(); final ResourceManager mgr = new ResourceManager(); final File src = new File("target/test/resource/solution/test/reporting/BigReport.prpt"); final MasterReport masterReport = (MasterReport) mgr.createDirectly(src, MasterReport.class).getResource(); final String key = "test"; masterReport.setContentCacheKey(key); masterReport.setQueryLimit(500); rc.setReport(masterReport); rc.setOutputType("text/html"); //$NON-NLS-1$ // turn on pagination, by way of input (typical mode for xaction) final HashMap<String, Object> inputs = new HashMap<String, Object>(); inputs.put("paginate", "true"); //$NON-NLS-1$ //$NON-NLS-2$ inputs.put("accepted-page", "0"); //$NON-NLS-1$ //$NON-NLS-2$ rc.setInputs(inputs); final TestListener future1Listener = new TestListener("1", UUID.randomUUID(), ""); future1Listener.setStatus(AsyncExecutionStatus.SCHEDULED); final TestListener future2Listener = new TestListener("1", UUID.randomUUID(), ""); final Future<byte[]> future1 = executorService .submit(new CachingPageableHTMLOutputIT.TestTask(latch1, rc, future1Listener)); final Future<byte[]> future2 = executorService .submit(new CachingPageableHTMLOutputIT.TestTask(latch2, rc, future2Listener)); latch2.countDown(); while (!future2.isDone()) { if (future2Listener.isOnFirstPage()) { latch1.countDown(); break; } Thread.sleep(10); } final String content2 = new String(future2.get(), "UTF-8"); assertFalse(content2.contains("Scheduled paginated HTML report")); final String content1 = new String(future1.get(), "UTF-8"); assertTrue(content1.contains("Scheduled paginated HTML report")); assertEquals(future2Listener.getState().getPage(), future1Listener.getState().getTotalPages()); assertEquals(future1Listener.getState().getPage(), future1Listener.getState().getTotalPages()); } private class TestTask implements Callable<byte[]> { private final CountDownLatch latch; private final SimpleReportingComponent rc; private final TestListener listener; private TestTask(final CountDownLatch latch, final SimpleReportingComponent rc, final TestListener listener) { this.latch = latch; this.rc = rc; this.listener = listener; } @Override public byte[] call() throws Exception { latch.await(); try (final java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream()) { //$NON-NLS-1$ //$NON-NLS-2$ rc.setOutputStream(outputStream); ReportListenerThreadHolder.setListener(listener); rc.execute(); return outputStream.toByteArray(); } } } }